src/EventSubscriber/KernelEventsSubscriber.php line 86

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber;
  3. use ApiPlatform\Core\EventListener\EventPriorities;
  4. use App\Entity\MediaObject;
  5. use Doctrine\ORM\EntityManagerInterface;
  6. use Psr\Log\LoggerInterface;
  7. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  8. use Symfony\Component\HttpKernel\Event\RequestEvent;
  9. use Symfony\Component\HttpKernel\Event\ViewEvent;
  10. use Symfony\Component\HttpKernel\KernelEvents;
  11. use Doctrine\Common\Annotations\AnnotationReader as DocReader;
  12. use Doctrine\ORM\Mapping as ORM;
  13. use Symfony\Component\PropertyAccess\PropertyAccess;
  14. class KernelEventsSubscriber implements EventSubscriberInterface
  15. {
  16.     /**
  17.      * @var LoggerInterface
  18.      */
  19.     private $logger;
  20.     /**
  21.      * @var EntityManagerInterface
  22.      */
  23.     private $manager;
  24.     /**
  25.      * List of media objects to be deleted
  26.      * @var array
  27.      */
  28.     private $suppress = [];
  29.     public function __construct(LoggerInterface $loggerEntityManagerInterface $manager)
  30.     {
  31.         $this->logger $logger;
  32.         $this->manager $manager;
  33.     }
  34.     public static function getSubscribedEvents()
  35.     {
  36.         return [
  37.             KernelEvents::VIEW => ['removeMediaObjects'EventPriorities::PRE_WRITE],
  38.             KernelEvents::REQUEST => ['logMediaObjects'EventPriorities::PRE_DESERIALIZE],
  39.         ];
  40.     }
  41.     /**
  42.      * Logs the media objects to be removed later
  43.      * @param RequestEvent $event
  44.      */
  45.     public function logMediaObjects(RequestEvent $event)
  46.     {
  47.         $params $event->getRequest()->attributes->get('_route_params', []);
  48.         if(isset($params['_api_item_operation_name']) && ($operation $params['_api_item_operation_name']) === 'PATCH'){
  49.             $class $params['_api_resource_class'];
  50.             $id $params['id'];
  51.             $object $this->manager->getRepository($class)->findOneBy(['id' => $id]);
  52.             try {
  53.                 $reflection = new \ReflectionClass($class);
  54.                 $reader = new DocReader();
  55.                 foreach ($reflection->getProperties() as $property) {
  56.                     $annotation $reader->getPropertyAnnotation($propertyORM\ManyToOne::class);
  57.                     if ($annotation instanceof ORM\ManyToOne && $annotation->targetEntity == MediaObject::class){
  58.                         $propertyAccessor PropertyAccess::createPropertyAccessor();
  59.                         $media $propertyAccessor->getValue($object$property->name);
  60.                         if ($media instanceof MediaObject){
  61.                             $this->suppress[$class][] = ['name' => $property->name"id" => $media->getId()];
  62.                         }
  63.                     }
  64.                 }
  65.             } catch (\ReflectionException $e) {
  66.                 $this->logger->error("Unable to register media object: {$e->getMessage()}");
  67.             }
  68.         }
  69.     }
  70.     /**
  71.      * Removes the media objects logged to be removed
  72.      * @param ViewEvent $event
  73.      */
  74.     public function removeMediaObjects(ViewEvent $event)
  75.     {
  76.         $object $event->getControllerResult();
  77.         if (is_object($object) && isset($this->suppress[get_class($object)])){
  78.             $propertyAccessor PropertyAccess::createPropertyAccessor();
  79.             $properties $this->suppress[get_class($object)];
  80.             foreach ($properties as $property) {
  81.                 $media $propertyAccessor->getValue($object$property['name']);
  82.                 if ($media instanceof MediaObject){
  83.                     $oldId $property['id'];
  84.                     if ($oldId !== $media->getId()){
  85.                         $this->manager->remove($this->manager->getRepository(MediaObject::class)->findOneBy(['id' => $oldId]));
  86.                         $this->logger->info("Marked media object #$oldId for removal");
  87.                     }
  88.                 }
  89.             }
  90.             $this->manager->flush();
  91.         }
  92.     }
  93. }