| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- <?php
- namespace App\Services;
- /*
- * ImageUploadService — загрузка, ресайз и хранение изображений блоков.
- *
- * Сохраняет в disk 'public' → storage/app/public/blocks/{folder}/uuid.webp
- * Публичный URL: asset('storage/blocks/{folder}/uuid.webp')
- *
- * Размеры из определения поля макета:
- * width + height → обрезать по центру (cover crop)
- * только width → уменьшить до ширины, сохранить пропорции
- * ничего → уменьшить до 1200px по ширине, сохранить пропорции
- *
- * Формат вывода всегда WebP (качество 85).
- */
- use Illuminate\Http\UploadedFile;
- use Illuminate\Support\Facades\Storage;
- use Illuminate\Support\Str;
- use Intervention\Image\Drivers\Gd\Driver;
- use Intervention\Image\ImageManager;
- class ImageUploadService
- {
- private ImageManager $manager;
- public function __construct()
- {
- $this->manager = new ImageManager(new Driver());
- }
- /**
- * Сохраняет загруженный файл, возвращает путь относительно диска 'public'.
- * Например: 'blocks/steps_section/550e8400-e29b-41d4-a716-446655440000.webp'
- *
- * @param array{width?:int, height?:int} $fieldDef — определение поля из BlockLayoutRegistry
- */
- public function store(UploadedFile $file, string $folder, array $fieldDef = []): string
- {
- $image = $this->manager->read($file->getRealPath());
- $w = $fieldDef['width'] ?? null;
- $h = $fieldDef['height'] ?? null;
- if ($w && $h) {
- // Cover-кроп: обрезаем по центру до точных размеров
- $image->cover($w, $h);
- } elseif ($w) {
- // Масштабируем до ширины (не увеличиваем)
- $image->scaleDown(width: $w);
- } else {
- // По умолчанию: не шире 1200px
- $image->scaleDown(width: 1200);
- }
- $filename = Str::uuid() . '.webp';
- $path = "blocks/{$folder}/{$filename}";
- Storage::disk('public')->put($path, $image->toWebp(85));
- return $path;
- }
- /**
- * Удаляет старый файл из диска 'public', если это внутренний файл (не внешний URL).
- */
- public function delete(string $oldPath): void
- {
- if ($oldPath && !str_starts_with($oldPath, 'http') && Storage::disk('public')->exists($oldPath)) {
- Storage::disk('public')->delete($oldPath);
- }
- }
- }
|