store($directory, 'public'); $originalName = method_exists($file, 'getClientOriginalName') ? (string) $file->getClientOriginalName() : basename($path); $mime = TicketAttachment::normalizeMimeType( method_exists($file, 'getClientMimeType') ? (string) $file->getClientMimeType() : '', $originalName, $path, ); if (str_starts_with($mime, 'image/')) { $this->optimizeImage($path, $mime); $mime = TicketAttachment::normalizeMimeType($mime, $originalName, $path); } $size = 0; try { $size = (int) Storage::disk('public')->size($path); } catch (\Throwable) { $size = (int) (method_exists($file, 'getSize') ? $file->getSize() : 0); } return [ 'path' => $path, 'mime' => $mime, 'size' => $size, 'original_name' => $originalName, ]; } private function optimizeImage(string $path, string $mime): void { $absolutePath = Storage::disk('public')->path($path); if (! is_file($absolutePath) || ! function_exists('getimagesize')) { return; } $size = @getimagesize($absolutePath); if (! is_array($size)) { return; } [$width, $height] = $size; if ($width <= 0 || $height <= 0) { return; } $maxWidth = 1600; $maxHeight = 1600; $ratio = min($maxWidth / $width, $maxHeight / $height, 1); $targetW = (int) max(1, round($width * $ratio)); $targetH = (int) max(1, round($height * $ratio)); $source = $this->createImageResource($absolutePath, $mime); if (! $source) { return; } $target = imagecreatetruecolor($targetW, $targetH); if ($target === false) { imagedestroy($source); return; } if (in_array($mime, ['image/png', 'image/webp'], true)) { imagealphablending($target, false); imagesavealpha($target, true); $transparent = imagecolorallocatealpha($target, 255, 255, 255, 127); imagefilledrectangle($target, 0, 0, $targetW, $targetH, $transparent); } imagecopyresampled($target, $source, 0, 0, 0, 0, $targetW, $targetH, $width, $height); switch ($mime) { case 'image/png': imagepng($target, $absolutePath, 6); break; case 'image/webp': if (function_exists('imagewebp')) { imagewebp($target, $absolutePath, 82); } break; default: imagejpeg($target, $absolutePath, 82); break; } imagedestroy($target); imagedestroy($source); } private function createImageResource(string $absolutePath, string $mime) { return match ($mime) { 'image/png' => function_exists('imagecreatefrompng') ? @imagecreatefrompng($absolutePath) : false, 'image/webp' => function_exists('imagecreatefromwebp') ? @imagecreatefromwebp($absolutePath) : false, default => function_exists('imagecreatefromjpeg') ? @imagecreatefromjpeg($absolutePath) : false, }; } }