===== PART 8/12 ===== , 'url' => $link->url, ]; return $content; } /** * RE-CHECK daily_limit and ip_limit for traffic campaigns (ad_type = 4) * This prevents race conditions where multiple users check limits simultaneously */ if ($ad_type == 4) { $campaign = $campaign_item->campaign; $current_ip = get_ip(); $time_zone = get_option('timezone', 'UTC'); $now = Time::now($time_zone); // Re-check daily_limit if (!empty($campaign->daily_limit) && $campaign->daily_limit > 0) { $Statistics = TableRegistry::getTableLocator()->get('Statistics'); $today_start_local = Time::now($time_zone)->startOfDay(); $today_end_local = Time::now($time_zone)->endOfDay(); $today_start_utc = $today_start_local->timezone('UTC')->format('Y-m-d H:i:s'); $today_end_utc = $today_end_local->timezone('UTC')->format('Y-m-d H:i:s'); $today_count = $Statistics->find() ->where([ 'campaign_id' => $campaign->id, 'created >=' => $today_start_utc, 'created <=' => $today_end_utc, ]) ->count(); if ($today_count >= $campaign->daily_limit) { // Daily limit reached, reject this view $this->updateLinkHits($link); $this->addNormalStatisticEntry($link, $ad_type, $data, $cookie['ip'], 18); $content = [ 'status' => 'success', 'message' => '', 'url' => $link->url, ]; return $content; } } // Re-check ip_limit if (!empty($campaign->ip_limit) && $campaign->ip_limit > 0) { $Statistics = TableRegistry::getTableLocator()->get('Statistics'); $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) { // IP limit reached, reject this view $this->updateLinkHits($link); $this->addNormalStatisticEntry($link, $ad_type, $data, $cookie['ip'], 19); $content = [ 'status' => 'success', 'message' => '', 'url' => $link->url, ]; return $content; } } } } /** * Check if proxy */ if ($this->isProxy()) { // Update link hits $this->updateLinkHits($link); $this->addNormalStatisticEntry($link, $ad_type, $data, get_ip(), 5); $content = [ 'status' => 'success', //'message' => 'Go without Earn because proxy', 'message' => '', 'url' => $link->url, ]; return $content; } $link_user_plan = get_user_plan($link->user_id); $views_hourly_limit = (int)$link_user_plan->views_hourly_limit; if ($views_hourly_limit > 0) { $time_zone = get_option('timezone', 'UTC'); $now = Time::now($time_zone); $hour = $now->hour; // Convert to UTC for database query $startOfHour = Time::now($time_zone)->setTimeFromTimeString($hour . ':00:00')->i18nFormat('yyyy-MM-dd HH:mm:ss', 'UTC', 'en'); $endOfHour = Time::now($time_zone)->setTimeFromTimeString($hour . ':59:59')->i18nFormat('yyyy-MM-dd HH:mm:ss', 'UTC', 'en'); $hourly_count = $this->Links->Statistics->find() ->where([ 'Statistics.user_id' => $link->user_id, 'Statistics.reason' => 1, 'Statistics.created BETWEEN :startOfHour AND :endOfHour', ]) ->bind(':startOfHour', $startOfHour, 'datetime') ->bind(':endOfHour', $endOfHour, 'datetime') ->count(); if ($hourly_count >= $views_hourly_limit) { // Update link hits $this->updateLinkHits($link); $this->addNormalStatisticEntry($link, $ad_type, $data, $cookie['ip'], 15); $content = [ 'status' => 'success', //'message' => 'Go without Earn, reached the hourly limit', 'message' => '', 'url' => $link->url, ]; return $content; } } $views_daily_limit = (int)$link_user_plan->views_daily_limit; if ($views_daily_limit > 0) { $time_zone = get_option('timezone', 'UTC'); // Convert to UTC for database query $startOfDay = Time::now($time_zone)->startOfDay()->i18nFormat('yyyy-MM-dd HH:mm:ss', 'UTC', 'en'); $endOfDay = Time::now($time_zone)->endOfDay()->i18nFormat('yyyy-MM-dd HH:mm:ss', 'UTC', 'en'); $daily_coun