===== PART 6/12 ===== 'campaign_id' => $campaign->id, 'created >=' => $today_start_utc, 'created <=' => $today_end_utc, ]) ->count(); if ($today_count >= $campaign->daily_limit) { $is_valid = false; $reject_reason = "Daily limit exceeded (count: {$today_count}, limit: {$campaign->daily_limit})"; } } // Check ip_limit (only for traffic campaigns - count from start of today) if ($is_valid && $ad_type == 4 && !empty($campaign->ip_limit) && $campaign->ip_limit > 0) { $Statistics = TableRegistry::getTableLocator()->get('Statistics'); // Count from start of today (same logic as daily_limit) $today_start_local = Time::now($time_zone)->startOfDay(); $today_start_utc = $today_start_local->timezone('UTC')->format('Y-m-d H:i:s'); $ip_count = $Statistics->find() ->where([ 'campaign_id' => $campaign->id, 'ip' => $current_ip, 'created >=' => $today_start_utc, ]) ->count(); if ($ip_count >= $campaign->ip_limit) { $is_valid = false; $reject_reason = "IP limit exceeded (count: {$ip_count}, limit: {$campaign->ip_limit})"; } } // Log result if ($is_valid) { file_put_contents($debug_log, "[" . date('Y-m-d H:i:s') . "] [FILTER] Campaign #{$campaign->id} ({$campaign->name}) - ACCEPTED\n", FILE_APPEND); $valid_campaign_items[] = $item; } else { file_put_contents($debug_log, "[" . date('Y-m-d H:i:s') . "] [FILTER] Campaign #{$campaign->id} ({$campaign->name}) - REJECTED: {$reject_reason}\n", FILE_APPEND); } } file_put_contents($debug_log, "[" . date('Y-m-d H:i:s') . "] [FILTER] Filter complete - Valid campaigns: " . count($valid_campaign_items) . "\n", FILE_APPEND); // If no valid campaigns found, return to default campaigns if (count($valid_campaign_items) == 0) { // Try to get default campaigns as fallback $campaign_items = $CampaignItems->find() ->contain(['Campaigns']) ->where([ 'Campaigns.default_campaign' => 1, 'Campaigns.ad_type' => $ad_type, 'Campaigns.status' => 1, "Campaigns.traffic_source IN (1, :traffic_source)", 'CampaignItems.weight <=' => 100, 'CampaignItems.views < (CampaignItems.purchase * 1000)', "CampaignItems.country IN ( 'all', :country)", ]) ->order(['CampaignItems.weight' => 'ASC']) ->bind(':traffic_source', $traffic_source, 'integer') ->bind(':country', $country, 'string') ->toArray(); file_put_contents($debug_log, "[" . date('Y-m-d H:i:s') . "] [QUERY] Query 3 (default campaigns) - Found: " . count($campaign_items) . " campaigns\n", FILE_APPEND); $valid_campaign_items = $campaign_items; } // If still no valid campaigns found (all exceeded limits), return empty if (count($valid_campaign_items) == 0) { file_put_contents($debug_log, "[" . date('Y-m-d H:i:s') . "] [RESULT] No valid campaigns available\n", FILE_APPEND); // Return empty paidAds to indicate no campaign available $paidAds->mode = 'simple'; $paidAds->advertiser_price = 0; $paidAds->publisher_price = 0; $paidAds->ci = 0; $paidAds->cui = 0; $paidAds->cii = 0; $paidAds->website_url = ''; $paidAds->banner_size = ''; $paidAds->banner_code = ''; $paidAds->content = ''; return $paidAds; } shuffle($valid_campaign_items); $campaign_item = array_values($valid_campaign_items)[0]; // Save campaign to session if ($alias) { $_SESSION[$session_key] = $campaign_item->id; } $paidAds->mode = 'campaign'; $paidAds->advertiser_price = $campaign_item->advertiser_price; $paidAds->publisher_price = $campaign_item->publisher_price; $paidAds->ci = $campaign_item->campaign_id; $paidAds->cui = $campaign_item->campaign->user_id; $paidAds->cii = $campaign_item->id; $paidAds->website_url = $campaign_item->campaign->website_url; $paidAds->banner_size = $campaign_item->campaign->banner_size; $paidAds->banner_code = $campaign_item->campaign->banner_code; $paidAds->content = $campaign_item->campaign->content ?? ''; return $paidAds; } /** * @param array|object $data * @param \App\Model\Entity\Link $link * @param int $ad_type * @return array */ protected function calcEarnings($data, $link, $ad_type) { /** * Views reasons * 1- Earn * 2- Disabled cookie * 3- Anonymous user * 4- Adblock * 5- Proxy * 6- IP changed * 7- Not unique * 8- Full weight * 9- Default campaign * 10- Direct * 11- Invalid Country * 12- Earnings disabled * 13- User disabled earnings * 14- Blocked referer * 15- Hourly limit reached * 16- Daily limit reached * 17- Monthly limit reached * 18- Campaign daily limit reached (race condition check) * 19- Campaign IP limit reached (race condition check)