src/UploadsBundle/Subscriber/UploadSubscriber.php line 59

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace UploadsBundle\Subscriber;
  3. use InvalidArgumentException;
  4. use Oneup\UploaderBundle\Event\PostUploadEvent;
  5. use Oneup\UploaderBundle\Uploader\Response\AbstractResponse;
  6. use Oneup\UploaderBundle\UploadEvents;
  7. use Psr\Log\LoggerInterface;
  8. use RuntimeException;
  9. use Sindrive\ContentBundle\Resizer\Resizer;
  10. use Sindrive\ContentBundle\Thumbs\ThumbsManager;
  11. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  12. use Symfony\Component\HttpFoundation\File\File;
  13. use Symfony\Component\HttpFoundation\File\UploadedFile;
  14. use UploadsBundle\FileHandler\FileHandlerFactory;
  15. use UploadsBundle\FileHandler\ImageHandler;
  16. use UploadsBundle\FileHandler\LocalPathMapper;
  17. use UploadsBundle\Model\File as FileModel;
  18. use const PATHINFO_BASENAME;
  19. class UploadSubscriber implements EventSubscriberInterface
  20. {
  21.     private FileHandlerFactory $fileHandlerFactory;
  22.     private string $uploadsWebRoot;
  23.     private string $uploadsRealRoot;
  24.     private Resizer $resizer;
  25.     private LocalPathMapper $pathMapper;
  26.     private ThumbsManager $thumbsManager;
  27.     private LoggerInterface $logger;
  28.     /**
  29.      * @var string[]
  30.      */
  31.     private array $dbDomains;
  32.     /**
  33.      * @param string[] $dbDomains
  34.      */
  35.     public function __construct(FileHandlerFactory $fileHandlerFactoryResizer $resizerLocalPathMapper $pathMapperThumbsManager $thumbsManagerstring $uploadsWebRootstring $uploadsRealRoot, array $dbDomainsLoggerInterface $logger)
  36.     {
  37.         $this->fileHandlerFactory $fileHandlerFactory;
  38.         $this->resizer $resizer;
  39.         $this->pathMapper $pathMapper;
  40.         $this->thumbsManager $thumbsManager;
  41.         $this->uploadsWebRoot $uploadsWebRoot;
  42.         $this->uploadsRealRoot $uploadsRealRoot;
  43.         $this->dbDomains $dbDomains;
  44.         $this->logger $logger;
  45.     }
  46.     public function onPostUpload(PostUploadEvent $event): void
  47.     {
  48.         $request $event->getRequest();
  49.         if ((null === $uploadToken $request->get('uploadToken')) || (null === $domain $request->get('domain'))) {
  50.             return;
  51.         }
  52.         if (!is_string($uploadToken) || !is_string($domain)) {
  53.             return;
  54.         }
  55.         $requestedWidth $request->get('requestedWidth');
  56.         $requestedHeight $request->get('requestedHeight');
  57.         if (!is_scalar($requestedWidth) || !is_scalar($requestedHeight)) {
  58.             return;
  59.         }
  60.         $requestedWidth $this->fixJavascriptBug($requestedWidth);
  61.         $requestedHeight $this->fixJavascriptBug($requestedHeight);
  62.         $processingType = ((int) $requestedWidth || (int) $requestedHeight 0)
  63.             ? FileHandlerFactory::PROCESS_COPY_SOURCE
  64.             FileHandlerFactory::PROCESS_COPY;
  65.         $imageHandler $this->fileHandlerFactory->createFileHandler(
  66.             $domain,
  67.             $processingType,
  68.             FileHandlerFactory::TYPE_LOCAL_TO_LOCAL
  69.         );
  70.         $this->logger->debug('Created file handler with domain ' $domain ' and processingType ' $processingType);
  71.         /** @var File $file */
  72.         $file $event->getFile();
  73.         if (is_a($imageHandlerImageHandler::class)) {
  74.             $file = new File($this->thumbsManager->convertOriginal($domain$file->getPathname()));
  75.         }
  76.         /** @var string|null $coordsString */
  77.         $coordsString $request->get('coords');
  78.         if (null !== $coordsString && '' !== $coordsString) {
  79.             /** @var array<string> $coords */
  80.             $coords json_decode($coordsStringtrue512JSON_THROW_ON_ERROR);
  81.             $this->resizer->crop($file->getPathname(), $coords['x'], $coords['y'], $coords['width'], $coords['height']);
  82.         }
  83.         $extension $file->guessExtension() ?? $file->getExtension();
  84.         if (in_array($extension, ['asf''3gp'], true)) {
  85.             $extension $file->getExtension();
  86.         }
  87.         // workaround when .jpeg is above .jpg in mime.type
  88.         if ($extension === 'jpeg' && $file->getExtension() === 'jpg') {
  89.             $extension 'jpg';
  90.         }
  91.         $finalFilename $file->getBasename('.' $file->getExtension()) . '.' $extension;
  92.         $path sprintf('%s/%s/%s'$this->uploadsRealRoot$uploadToken$finalFilename);
  93.         $moveStatus $imageHandler->move($file->getPathname(), $path);
  94.         $this->logger->debug('Moved ' $file->getPathname() . ' to ' $path ' status ' . ($moveStatus 'true' 'false'));
  95.         /** @var AbstractResponse $response */
  96.         $response $event->getResponse();
  97.         $response['name'] = $finalFilename;
  98.         $response['webRoot'] = sprintf('%s/%s'$this->uploadsWebRoot$uploadToken);
  99.         $response['status'] = FileModel::STATUS_NEW;
  100.         if ($this->isDbFile($domain)) {
  101.             $requestFiles $request->files;
  102.             if ($requestFiles->has('file')) {
  103.                 $requestFile $requestFiles->get('file');
  104.                 if (!$requestFile instanceof UploadedFile) {
  105.                     throw new RuntimeException('Request should contain UploadedFile instances.');
  106.                 }
  107.                 $originalName pathinfo($requestFile->getClientOriginalName(), PATHINFO_BASENAME);
  108.             } elseif ($requestFiles->has('files')) {
  109.                 $originalName pathinfo($requestFiles->all('files')[0]->getClientOriginalName(), PATHINFO_BASENAME);
  110.             } else {
  111.                 throw new InvalidArgumentException('Can not file file or files[] argument');
  112.             }
  113.             $response['originalName'] = $originalName;
  114.         }
  115.         if ($processingType !== FileHandlerFactory::PROCESS_COPY_SOURCE) {
  116.             return;
  117.         }
  118.         $absolutePath $this->pathMapper->toAbsolute($path);
  119.         $this->resizer->resize(
  120.             $absolutePath,
  121.             $requestedWidth,
  122.             $requestedHeight
  123.         );
  124.     }
  125.     private function isDbFile(string $domain): bool
  126.     {
  127.         return in_array($domain$this->dbDomainstrue);
  128.     }
  129.     /**
  130.      * @param bool|float|int|string $value
  131.      */
  132.     private function fixJavascriptBug($value): ?int
  133.     {
  134.         if ($value === '' || $value === 'null') {
  135.             return null;
  136.         }
  137.         return (int) $value;
  138.     }
  139.     /**
  140.      * @return array<string, array<int|string, array<int|string, int|string>|int|string>|string>
  141.      */
  142.     public static function getSubscribedEvents(): array
  143.     {
  144.         return [
  145.             UploadEvents::POST_UPLOAD => 'onPostUpload',
  146.         ];
  147.     }
  148. }