Lectures/includes/site-upload.php

257 lines
9.2 KiB
PHP

<?php
class SiteUploadHandler {
private $uploadDir;
private $allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
private $maxFileSize = 5242880; // 5MB
public function __construct() {
$this->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';
}
}