vendor/sulu/form-bundle/Event/ProtectedMediaSubscriber.php line 73

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of Sulu.
  4.  *
  5.  * (c) Sulu GmbH
  6.  *
  7.  * This source file is subject to the MIT license that is bundled
  8.  * with this source code in the file LICENSE.
  9.  */
  10. namespace Sulu\Bundle\FormBundle\Event;
  11. use Doctrine\ORM\EntityManagerInterface;
  12. use Doctrine\ORM\NoResultException;
  13. use Sulu\Bundle\MediaBundle\Entity\MediaInterface;
  14. use Sulu\Bundle\MediaBundle\Media\FormatCache\FormatCacheInterface;
  15. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  16. use Symfony\Component\HttpFoundation\RedirectResponse;
  17. use Symfony\Component\HttpKernel\Event\RequestEvent;
  18. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  19. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  20. /**
  21.  * @internal
  22.  */
  23. class ProtectedMediaSubscriber implements EventSubscriberInterface
  24. {
  25.     /**
  26.      * @var UrlGeneratorInterface
  27.      */
  28.     private $urlGenerator;
  29.     /**
  30.      * @var EntityManagerInterface
  31.      */
  32.     private $entityManager;
  33.     /**
  34.      * @var FormatCacheInterface
  35.      */
  36.     private $formatCache;
  37.     /**
  38.      * @var string[]
  39.      */
  40.     protected $protectedCollectionKeys = [];
  41.     /**
  42.      * @param string[] $protectedCollectionKeys
  43.      */
  44.     public function __construct(
  45.         UrlGeneratorInterface $urlGenerator,
  46.         EntityManagerInterface $entityManager,
  47.         FormatCacheInterface $formatCache,
  48.         array $protectedCollectionKeys = [
  49.             'sulu_form',
  50.         ]
  51.     ) {
  52.         $this->urlGenerator $urlGenerator;
  53.         $this->entityManager $entityManager;
  54.         $this->formatCache $formatCache;
  55.         $this->protectedCollectionKeys $protectedCollectionKeys;
  56.     }
  57.     public static function getSubscribedEvents()
  58.     {
  59.         return [
  60.             'kernel.request' => 'onRequest',
  61.         ];
  62.     }
  63.     public function onRequest(RequestEvent $event): void
  64.     {
  65.         if (\method_exists($event'isMainRequest') ? !$event->isMainRequest() : !$event->isMasterRequest()) {
  66.             return;
  67.         }
  68.         $request $event->getRequest();
  69.         $routeName $request->attributes->get('_route');
  70.         if ('sulu_media.website.image.proxy' !== $routeName
  71.             && 'sulu_media.website.media.download' !== $routeName
  72.         ) {
  73.             return;
  74.         }
  75.         $mediaId null;
  76.         if ('sulu_media.website.image.proxy' === $routeName) {
  77.             $slug $request->attributes->get('slug');
  78.             if (!$slug) {
  79.                 return;
  80.             }
  81.             $mediaProperties $this->formatCache->analyzedMediaUrl($request->getPathInfo());
  82.             $mediaId $mediaProperties['id'];
  83.         }
  84.         if (!$mediaId) {
  85.             /** @var string|null $mediaId */
  86.             $mediaId $request->attributes->get('id');
  87.         }
  88.         if (!\is_numeric($mediaId) || !$this->isProtectedCollection((int) $mediaId)) {
  89.             return;
  90.         }
  91.         if ('sulu_media.website.image.proxy' === $routeName) {
  92.             throw new AccessDeniedHttpException();
  93.         }
  94.         $url $this->urlGenerator->generate(
  95.             'sulu_media.website.media.download_admin',
  96.             \array_merge(
  97.                 $request->query->all(),
  98.                 $request->attributes->get('_route_params')
  99.             )
  100.         );
  101.         $event->setResponse(new RedirectResponse($url));
  102.     }
  103.     private function isProtectedCollection(int $mediaId): bool
  104.     {
  105.         $queryBuilder $this->entityManager->createQueryBuilder()
  106.             ->from(MediaInterface::class, 'media')
  107.             ->innerJoin('media.collection''collection')
  108.             ->select('collection.key')
  109.             ->where('media.id = :id')
  110.             ->setParameter('id'$mediaId);
  111.         try {
  112.             /** @var string $collectionKey */
  113.             $collectionKey $queryBuilder->getQuery()->getSingleScalarResult();
  114.         } catch (NoResultException $e) {
  115.             return false;
  116.         }
  117.         foreach ($this->protectedCollectionKeys as $protectedCollectionKey) {
  118.             if (=== \strpos($collectionKey$protectedCollectionKey)) {
  119.                 return true;
  120.             }
  121.         }
  122.         return false;
  123.     }
  124. }