src/Infrastructure/EventListener/ConvertImageEventListener.php line 102

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Infrastructure\EventListener;
  4. use App\Application\Manager\GenericManager;
  5. use App\Application\Service\Media\MediaService;
  6. use App\Domain\Entity\Media;
  7. use Doctrine\ORM\Event\PostRemoveEventArgs;
  8. use Imagick;
  9. use ImagickException;
  10. use League\Flysystem\FilesystemException;
  11. use RuntimeException;
  12. use Symfony\Component\HttpFoundation\File\UploadedFile;
  13. use Vich\UploaderBundle\Event\Event;
  14. class ConvertImageEventListener
  15. {
  16.     public function __construct(
  17.         public readonly GenericManager $genericManager,
  18.         private readonly MediaService $mediaService,
  19.         private readonly string $environment,
  20.         private readonly string $appAbsoluteUrl,
  21.     ) {}
  22.     /**
  23.      * @param Event $event
  24.      *
  25.      * @return void
  26.      * @throws ImagickException
  27.      * @throws FilesystemException
  28.      */
  29.     public function onVichUploaderPreUpload(Event $event): void
  30.     {
  31.         if (!$event->getObject() instanceof Media) {
  32.             return;
  33.         }
  34.         /** @var Media $media */
  35.         $media $event->getObject();
  36.         /** @var UploadedFile $file */
  37.         $file $media->file;
  38.         $mime $file->getMimeType();
  39.         // Si ce n'est pas une image ou si c'est un SVG, on utilise handleNonImageMedia
  40.         if (!str_starts_with($mime'image/') || $mime === 'image/svg+xml') {
  41.             $this->handleNonImageMedia($event);
  42.             return;
  43.         }
  44.         $imageName pathinfo($file->getClientOriginalName())['filename'] . '.' 'webp';
  45.         $filepath "/tmp/$imageName";
  46.         $img = new Imagick($file->getRealPath());
  47.         if (!$img->valid()) {
  48.             throw new RuntimeException('Invalid image');
  49.         }
  50.         $img->autoOrient();
  51.         $img->stripImage();
  52.         $img->setImageFormat('webp');
  53.         $this->mediaService->setDefaultCompression($img);
  54.         $this->mediaService->applyDefaultFilter($img);
  55.         $img->writeImage($filepath);
  56.         $file = new UploadedFile($filepath$imageName'image/webp');
  57.         $media->mimeType 'image/webp';
  58.         $media->originalName $imageName;
  59.         $media->file $file;
  60.     }
  61.     public function handleNonImageMedia(Event $event): void
  62.     {
  63.         /** @var Media $media */
  64.         $media $event->getObject();
  65.         /** @var UploadedFile $file */
  66.         $file $media->file;
  67.         $defaultName pathinfo($file->getClientOriginalName())['filename'] . '.' $file->getClientOriginalExtension();
  68.         $defaultMime $file->getMimeType();
  69.         // Si c'est un SVG, on le copie directement dans le cache/full
  70.         if ($defaultMime === 'image/svg+xml') {
  71.             $filepath "/tmp/$defaultName";
  72.             copy($file->getRealPath(), $filepath);
  73.             $file = new UploadedFile($filepath$defaultName$defaultMime);
  74.         } else {
  75.             $file = new UploadedFile($file->getRealPath(), $defaultName$defaultMime);
  76.         }
  77.         $media->mimeType $file->getMimeType();
  78.         $media->originalName $defaultName;
  79.         $media->file $file;
  80.     }
  81.     public function onVichUploaderPostUpload(Event $event): void
  82.     {
  83.         try {
  84.             /** @var Media $media */
  85.             $media $event->getObject();
  86.             if (!$media) {
  87.                 return;
  88.             }
  89.             $media->contentUrl "$this->appAbsoluteUrl/api/media/$media->uuid/download";
  90.             // Si c'est une image WebP ou un SVG, on l'enregistre dans le cache
  91.             if ($media->mimeType === 'image/webp' || $media->mimeType === 'image/svg+xml') {
  92.                 if ($media->mimeType === 'image/webp') {
  93.                     $this->mediaService->applyDefaultFilter($media);
  94.                     unlink("/tmp/{$media->originalName}");
  95.                 } else {
  96.                     // Pour les SVG, on les copie directement dans le cache/full
  97.                     $this->mediaService->writeToAwsFilesystem(
  98.                         "cache/full/{$media->filePath}",
  99.                         file_get_contents("/tmp/{$media->originalName}")
  100.                     );
  101.                     unlink("/tmp/{$media->originalName}");
  102.                 }
  103.             }
  104.         } catch (ImagickException FilesystemException $e) {
  105.             if ($this->environment === 'dev') {
  106.                 dump($e->getMessage(), $event->getObject()->filePath);
  107.             }
  108.         }
  109.     }
  110.     public function postRemove(PostRemoveEventArgs $event): void
  111.     {
  112.         $object $event->getObject();
  113.         if (!$object instanceof Media) {
  114.             return;
  115.         }
  116.         $this->mediaService->deleteAllFiles($object);
  117.     }
  118. }