Files
interface-kaznautes/src/Service/FileUploader.php

80 lines
2.3 KiB
PHP

<?php
namespace App\Service;
use RuntimeException;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\String\Slugger\SluggerInterface;
/**
* Service de gestion des envois et suppressions de fichiers.
*/
class FileUploader
{
/**
* @param string $targetDirectory Le chemin absolu vers le dossier de dépôt.
* @param SluggerInterface $slugger Le service de nettoyage des chaînes de caractères.
*/
public function __construct(
#[Autowire('%kernel.project_dir%/public/uploads/img')]
private readonly string $targetDirectory,
private readonly SluggerInterface $slugger,
)
{
}
/**
* Traite, sécurise et déplace un fichier déposé.
*
* @param UploadedFile $file Le fichier physique à déposer.
* @return string Le nom final sécurisé et unique du fichier.
* @throws RuntimeException En cas d'échec de l'écriture sur le disque.
*/
public function upload(UploadedFile $file): string
{
$originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = $this->slugger->slug($originalFilename);
// Utilisation de uniqid('', true) pour garantir une unicité absolue en production
$fileName = sprintf('%s-%s.%s', $safeFilename, uniqid('', true), $file->guessExtension());
try {
$file->move($this->getTargetDirectory(), $fileName);
} catch (FileException $e) {
throw new RuntimeException('Erreur lors du transfert de l\'image : ' . $e->getMessage(), 0, $e);
}
return $fileName;
}
/**
* Supprime physiquement un fichier du serveur.
*
* @param string|null $fileName Le nom du fichier à supprimer.
*/
public function delete(?string $fileName): void
{
if (null === $fileName) {
return;
}
$filePath = rtrim($this->getTargetDirectory(), '/') . '/' . $fileName;
if (file_exists($filePath)) {
unlink($filePath);
}
}
/**
* Retourne le chemin du répertoire de dépôt.
*
* @return string
*/
public function getTargetDirectory(): string
{
return $this->targetDirectory;
}
}