File: /home/xedaptot/ai.naniguide.com/app/Jobs/Ads/PauseAdCampaign.php
<?php
namespace App\Jobs\Ads;
use App\Model\AdCampaign;
use App\Services\Ads\AdActivityLogger;
use App\Services\Ads\AdPublishingService;
use Illuminate\Support\Facades\Log;
use Throwable;
/**
* Bulk-pause helper used by `AdsEmergencyController::pauseAllCustomerCampaigns`
* (R11 emergency controls). One job per active campaign so a single hung
* platform call doesn't block the bulk operation.
*
* Wraps `AdPublishingService::pause()` — same path the customer's "pause"
* button uses. Decorator chain handles retries / idempotency / circuit
* breaker on the underlying platform calls.
*/
class PauseAdCampaign extends AbstractAdsJob
{
public function __construct(
public int $adCampaignId,
public ?string $reason = null,
) {
parent::__construct();
}
public function handle(AdPublishingService $service): void
{
$campaign = AdCampaign::find($this->adCampaignId);
if (!$campaign) {
return;
}
$this->customerId = (int) $campaign->customer_id;
try {
$service->pause($campaign);
AdActivityLogger::log(
entity: $campaign,
action: 'campaign.bulk_paused',
status: 'info',
title: 'Campaign paused by admin emergency action',
description: $this->reason ?: 'Bulk pause triggered from /rui/admin/ads/emergency',
);
} catch (Throwable $e) {
Log::channel((string) config('ads.observability.log_channel', 'stack'))->error(
'ads.emergency.bulk_pause_failed',
[
'campaign_id' => $campaign->id,
'customer_id' => $campaign->customer_id,
'error' => $e->getMessage(),
]
);
throw $e; // surfaces to AbstractAdsJob retry pipeline
}
}
public function failed(Throwable $exception): void
{
$this->logFailure($exception);
}
}