From d245055bf4772c026c0ce832f3143d9c10bd40a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Cmit=20Tun=C3=A7?= Date: Tue, 2 Jun 2026 06:44:57 +0300 Subject: [PATCH] feat: add automated WebP conversion and resizing for hero background images --- app/Models/Setting.php | 108 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 5 deletions(-) diff --git a/app/Models/Setting.php b/app/Models/Setting.php index 5961497..a2b318a 100644 --- a/app/Models/Setting.php +++ b/app/Models/Setting.php @@ -75,17 +75,115 @@ class Setting extends Model $this->attributes['value'] = $value ? '1' : '0'; } - /** - * Set value from different field names - */ public function setValueFileAttribute($value) { // Filament bazen dosya yolunu array olarak döndürebilir, bu durumda ilk elemanı alıyoruz if (is_array($value)) { - $this->attributes['value'] = array_values($value)[0] ?? null; + $filePath = array_values($value)[0] ?? null; } else { - $this->attributes['value'] = $value; + $filePath = $value; } + + if ($filePath && $this->key === 'hero_bg') { + $filePath = $this->processHeroBackground($filePath); + } + + $this->attributes['value'] = $filePath; + } + + /** + * Process the hero background image: convert to webp, resize if necessary, and compress. + */ + protected function processHeroBackground($filePath) + { + try { + $disk = \Illuminate\Support\Facades\Storage::disk('public'); + if (!$disk->exists($filePath)) { + return $filePath; + } + + $absolutePath = $disk->path($filePath); + + // Get image info + $imageInfo = @getimagesize($absolutePath); + if (!$imageInfo) { + return $filePath; + } + + $mimeType = $imageInfo['mime']; + + // Create GD image resource based on mime type + switch ($mimeType) { + case 'image/jpeg': + case 'image/jpg': + $image = @imagecreatefromjpeg($absolutePath); + break; + case 'image/png': + $image = @imagecreatefrompng($absolutePath); + break; + case 'image/webp': + $image = @imagecreatefromwebp($absolutePath); + break; + case 'image/gif': + $image = @imagecreatefromgif($absolutePath); + break; + default: + return $filePath; + } + + if (!$image) { + return $filePath; + } + + // Preserve transparency or handle it for webp if needed + imagealphablending($image, true); + imagesavealpha($image, true); + + $originalWidth = imagesx($image); + $originalHeight = imagesy($image); + + // Target dimensions: Hero bg size, max width 1920px + $maxWidth = 1920; + if ($originalWidth > $maxWidth) { + $newWidth = $maxWidth; + $newHeight = (int) (($originalHeight / $originalWidth) * $maxWidth); + + $resizedImage = imagecreatetruecolor($newWidth, $newHeight); + + // Preserve transparency + imagealphablending($resizedImage, false); + imagesavealpha($resizedImage, true); + + // Resize + imagecopyresampled($resizedImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $originalWidth, $originalHeight); + imagedestroy($image); + $image = $resizedImage; + } + + // Generate new webp path + $pathInfo = pathinfo($filePath); + $newWebpPath = $pathInfo['dirname'] . '/' . $pathInfo['filename'] . '.webp'; + $absoluteWebpPath = $disk->path($newWebpPath); + + // Save as webp with 80% quality (excellent quality-to-size ratio) + if (imagewebp($image, $absoluteWebpPath, 80)) { + imagedestroy($image); + + // If the file extension changed, delete the original file + if ($newWebpPath !== $filePath) { + $disk->delete($filePath); + } + + return $newWebpPath; + } + + imagedestroy($image); + } catch (\Exception $e) { + // Log error or fallback to original + \Illuminate\Support\Facades\Log::error('Hero background image processing failed: ' . $e->getMessage()); + } + + return $filePath; } /**