vendor/jms/serializer-bundle/DependencyInjection/Compiler/RegisterEventListenersAndSubscribersPass.php line 70

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace JMS\SerializerBundle\DependencyInjection\Compiler;
  4. use JMS\Serializer\EventDispatcher\EventDispatcher;
  5. use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
  6. use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
  7. use Symfony\Component\DependencyInjection\ContainerBuilder;
  8. use Symfony\Component\DependencyInjection\Reference;
  9. /**
  10.  * @internal
  11.  */
  12. final class RegisterEventListenersAndSubscribersPass implements CompilerPassInterface
  13. {
  14.     public function process(ContainerBuilder $container)
  15.     {
  16.         $listeners $this->findListeners($container);
  17.         $dispatcherDef $container->findDefinition('jms_serializer.event_dispatcher');
  18.         $listenerServices = [];
  19.         foreach ($listeners as &$events) {
  20.             $events array_merge(...$events);
  21.         }
  22.         foreach ($listeners as $event => $listenersPerEvent) {
  23.             foreach ($listenersPerEvent as $singleListener) {
  24.                 $id = (string) $singleListener[0][0];
  25.                 $listenerServices[$id] = new ServiceClosureArgument($singleListener[0][0]);
  26.                 $singleListener[0][0] = $id;
  27.                 $dispatcherDef->addMethodCall('addListener'array_merge([$event], $singleListener));
  28.             }
  29.         }
  30.         $container->findDefinition('jms_serializer.event_dispatcher.service_locator')
  31.             ->setArgument(0$listenerServices);
  32.     }
  33.     private function findListeners(ContainerBuilder $container): array
  34.     {
  35.         $listeners = [];
  36.         foreach ($container->findTaggedServiceIds('jms_serializer.event_listener') as $id => $tags) {
  37.             foreach ($tags as $attributes) {
  38.                 if (!isset($attributes['event'])) {
  39.                     throw new \RuntimeException(sprintf('The tag "jms_serializer.event_listener" of service "%s" requires an attribute named "event".'$id));
  40.                 }
  41.                 $class = isset($attributes['class'])
  42.                     ? $container->getParameterBag()->resolveValue($attributes['class'])
  43.                     : null;
  44.                 $format $attributes['format'] ?? null;
  45.                 $method $attributes['method'] ?? EventDispatcher::getDefaultMethodName($attributes['event']);
  46.                 $priority = isset($attributes['priority']) ? (int) $attributes['priority'] : 0;
  47.                 $interface $attributes['interface'] ?? null;
  48.                 $listeners[$attributes['event']][$priority][] = [[new Reference($id), $method], $class$format$interface];
  49.             }
  50.         }
  51.         foreach ($container->findTaggedServiceIds('jms_serializer.event_subscriber') as $id => $tags) {
  52.             $subscriberClass $container->getDefinition($id)->getClass();
  53.             $subscriberClassReflectionObj = new \ReflectionClass($subscriberClass);
  54.             if (!$subscriberClassReflectionObj->implementsInterface('JMS\Serializer\EventDispatcher\EventSubscriberInterface')) {
  55.                 throw new \RuntimeException(sprintf('The service "%s" (class: %s) does not implement the EventSubscriberInterface.'$id$subscriberClass));
  56.             }
  57.             foreach (call_user_func([$subscriberClass'getSubscribedEvents']) as $eventData) {
  58.                 if (!isset($eventData['event'])) {
  59.                     throw new \RuntimeException(sprintf('The service "%s" (class: %s) must return an event for each subscribed event.'$id$subscriberClass));
  60.                 }
  61.                 $class $eventData['class'] ?? null;
  62.                 $format $eventData['format'] ?? null;
  63.                 $method $eventData['method'] ?? EventDispatcher::getDefaultMethodName($eventData['event']);
  64.                 $priority = isset($eventData['priority']) ? (int) $eventData['priority'] : 0;
  65.                 $interface $eventData['interface'] ?? null;
  66.                 $listeners[$eventData['event']][$priority][] = [[new Reference($id), $method], $class$format$interface];
  67.             }
  68.         }
  69.         array_walk($listeners, static function (&$value$key) {
  70.             ksort($value);
  71.         });
  72.         return $listeners;
  73.     }
  74. }