uploadDir = __DIR__ . '/../assets/images/site/'; $this->ensureUploadDirectory(); } public function handleLogoUpload($file) { try { if ($file['error'] !== UPLOAD_ERR_OK) { throw new Exception($this->getUploadErrorMessage($file['error'])); } $finfo = new finfo(FILEINFO_MIME_TYPE); $mimeType = $finfo->file($file['tmp_name']); if (!in_array($mimeType, $this->allowedTypes)) { throw new Exception('Type de fichier non autorisé. Types acceptés : JPG, PNG, GIF, WEBP'); } if ($file['size'] > $this->maxFileSize) { throw new Exception('Fichier trop volumineux. Taille maximum : 5MB'); } $extension = $this->getExtensionFromMimeType($mimeType); $filename = 'logo.' . $extension; $targetPath = $this->uploadDir . $filename; $this->removeOldLogo(); if (!move_uploaded_file($file['tmp_name'], $targetPath)) { throw new Exception('Erreur lors du déplacement du fichier uploadé'); } // Créer le favicon si ce n'est pas un SVG if ($mimeType !== 'image/svg+xml') { $this->createFavicon($targetPath, $mimeType); } return 'assets/images/site/' . $filename; } catch (Exception $e) { throw $e; } } public function handleBackgroundUpload($file) { try { if ($file['error'] !== UPLOAD_ERR_OK) { throw new Exception($this->getUploadErrorMessage($file['error'])); } $finfo = new finfo(FILEINFO_MIME_TYPE); $mimeType = $finfo->file($file['tmp_name']); if (!in_array($mimeType, $this->allowedTypes)) { throw new Exception('Type de fichier non autorisé. Types acceptés : JPG, PNG, GIF, WEBP'); } if ($file['size'] > $this->maxFileSize) { throw new Exception('Fichier trop volumineux. Taille maximum : 5MB'); } // Vérifier les dimensions de l'image list($width, $height) = getimagesize($file['tmp_name']); $minWidth = 1200; $minHeight = 250; if ($width < $minWidth || $height < $minHeight) { throw new Exception("L'image doit faire au moins {$minWidth}x{$minHeight} pixels"); } $extension = $this->getExtensionFromMimeType($mimeType); $filename = 'about-bg.' . $extension; $targetPath = $this->uploadDir . $filename; // Supprimer l'ancien background s'il existe $this->removeOldBackground(); // Redimensionner l'image si nécessaire $maxWidth = 1920; $maxHeight = 1080; if ($width > $maxWidth || $height > $maxHeight) { $this->resizeImage( $file['tmp_name'], $targetPath, $mimeType, $maxWidth, $maxHeight ); } else { if (!move_uploaded_file($file['tmp_name'], $targetPath)) { throw new Exception('Erreur lors du déplacement du fichier uploadé'); } } return 'assets/images/site/' . $filename; } catch (Exception $e) { throw $e; } } private function removeOldBackground() { foreach (glob($this->uploadDir . 'about-bg.*') as $file) { unlink($file); } } private function resizeImage($sourcePath, $targetPath, $mimeType, $maxWidth, $maxHeight) { list($width, $height) = getimagesize($sourcePath); // Calculer les nouvelles dimensions en conservant le ratio $ratio = min($maxWidth / $width, $maxHeight / $height); $newWidth = round($width * $ratio); $newHeight = round($height * $ratio); // Créer la nouvelle image $sourceImage = $this->createImageFromFile($sourcePath, $mimeType); $newImage = imagecreatetruecolor($newWidth, $newHeight); // Préserver la transparence pour PNG if ($mimeType === 'image/png') { imagealphablending($newImage, false); imagesavealpha($newImage, true); } // Redimensionner imagecopyresampled( $newImage, $sourceImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height ); // Sauvegarder l'image redimensionnée $this->saveImage($newImage, $targetPath, $mimeType); // Libérer la mémoire imagedestroy($sourceImage); imagedestroy($newImage); } private function ensureUploadDirectory() { if (!file_exists($this->uploadDir)) { if (!mkdir($this->uploadDir, 0755, true)) { throw new Exception('Impossible de créer le dossier d\'upload'); } } } private function removeOldLogo() { foreach (glob($this->uploadDir . 'logo.*') as $file) { unlink($file); } $faviconPath = $this->uploadDir . 'favicon.png'; if (file_exists($faviconPath)) { unlink($faviconPath); } } private function createFavicon($sourcePath, $mimeType) { try { $source = $this->createImageFromFile($sourcePath, $mimeType); if (!$source) { throw new Exception('Impossible de créer l\'image source pour le favicon'); } $favicon = imagecreatetruecolor(32, 32); if (!$favicon) { imagedestroy($source); throw new Exception('Impossible de créer l\'image de destination pour le favicon'); } imagealphablending($favicon, false); imagesavealpha($favicon, true); if (!imagecopyresampled( $favicon, $source, 0, 0, 0, 0, 32, 32, imagesx($source), imagesy($source) )) { imagedestroy($source); imagedestroy($favicon); throw new Exception('Erreur lors du redimensionnement du favicon'); } $faviconPath = $this->uploadDir . 'favicon.png'; if (!imagepng($favicon, $faviconPath, 9)) { throw new Exception('Impossible de sauvegarder le favicon'); } imagedestroy($source); imagedestroy($favicon); } catch (Exception $e) { error_log('Erreur lors de la création du favicon : ' . $e->getMessage()); } } private function createImageFromFile($file, $mimeType) { switch ($mimeType) { case 'image/jpeg': return imagecreatefromjpeg($file); case 'image/png': return imagecreatefrompng($file); case 'image/gif': return imagecreatefromgif($file); case 'image/webp': return imagecreatefromwebp($file); default: throw new Exception('Type d\'image non supporté'); } } private function saveImage($image, $path, $mimeType) { switch ($mimeType) { case 'image/jpeg': return imagejpeg($image, $path, 85); case 'image/png': return imagepng($image, $path, 9); case 'image/gif': return imagegif($image, $path); case 'image/webp': return imagewebp($image, $path, 85); default: throw new Exception('Type d\'image non supporté'); } } private function getExtensionFromMimeType($mimeType) { $map = [ 'image/jpeg' => 'jpg', 'image/png' => 'png', 'image/gif' => 'gif', 'image/webp' => 'webp' ]; return $map[$mimeType] ?? 'jpg'; } private function getUploadErrorMessage($error) { $errors = [ UPLOAD_ERR_INI_SIZE => 'Le fichier dépasse la taille maximale autorisée par PHP', UPLOAD_ERR_FORM_SIZE => 'Le fichier dépasse la taille maximale autorisée par le formulaire', UPLOAD_ERR_PARTIAL => 'Le fichier n\'a été que partiellement uploadé', UPLOAD_ERR_NO_FILE => 'Aucun fichier n\'a été uploadé', UPLOAD_ERR_NO_TMP_DIR => 'Dossier temporaire manquant', UPLOAD_ERR_CANT_WRITE => 'Échec de l\'écriture du fichier sur le disque', UPLOAD_ERR_EXTENSION => 'Une extension PHP a arrêté l\'upload' ]; return $errors[$error] ?? 'Erreur inconnue lors de l\'upload'; } }