8e91be53c3
Часть 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>
54 lines
1.8 KiB
PHP
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;
|
|
}
|
|
}
|