src/EventSubscriber/KernelEventsSubscriber.php line 57

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