Files
portal/app/app/Services/Advertising/CampaignBannerService.php
T
Дмитрий 8e91be53c3 feat(реклама): Часть 3b-1 — набор баннеров кампании (хранение + генерация)
Часть 3b-1 из 6. Из одной картинки клиента генерируется и сохраняется полный
набор баннеров кампании (15 размеров Яндекса).

- Таблица ad_campaign_banners (RLS tenant_isolation, GRANT crm_app_user SELECT/INSERT/DELETE,
  клиентская — srv_bypass не нужен). Модель AdCampaignBanner.
- CampaignBannerService::generate — прогон исходной картинки по BannerSizes через
  BannerGenerator, файлы на приватный диск local, строки в БД; перегенерация заменяет набор.
- CHANGELOG_schema v8.97 + предупреждение для Части 4 (джоб под crm_supplier_worker
  потребует GRANT + srv_bypass re-run, иначе тихий ноль).

Тесты: 9/9 зелёные (Storage::fake). rls-reviewer: PASS.
Spec: docs/superpowers/specs/2026-07-25-yandex-reklama-medijnaya-pokazy-design.md §4

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 11:35:31 +03:00

54 lines
1.8 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services\Advertising;
use App\Models\AdCampaign;
use App\Models\AdCampaignBanner;
use Illuminate\Support\Facades\Storage;
/**
* Генерация полного набора баннеров кампании из ОДНОЙ картинки клиента: прогон по всем
* размерам BannerSizes через BannerGenerator, файлы на приватном диске 'local', строки в БД.
* Повторная генерация заменяет прежний набор (файлы + строки).
*/
final class CampaignBannerService
{
private const DISK = 'local';
public function __construct(private readonly BannerGenerator $generator) {}
/** @return int число сгенерированных баннеров (= число размеров). */
public function generate(AdCampaign $campaign, string $sourceBinary): int
{
$disk = Storage::disk(self::DISK);
$old = AdCampaignBanner::where('tenant_id', $campaign->tenant_id)
->where('campaign_id', $campaign->id)->get();
foreach ($old as $banner) {
$disk->delete($banner->path);
$banner->delete();
}
$count = 0;
foreach (BannerSizes::all() as [$w, $h]) {
$jpeg = $this->generator->coverJpeg($sourceBinary, $w, $h);
$path = "ad-banners/{$campaign->tenant_id}/{$campaign->id}/{$w}x{$h}.jpg";
$disk->put($path, $jpeg);
AdCampaignBanner::create([
'tenant_id' => $campaign->tenant_id,
'campaign_id' => $campaign->id,
'width' => $w,
'height' => $h,
'path' => $path,
'bytes' => strlen($jpeg),
]);
$count++;
}
return $count;
}
}