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

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\Compiler\CompilerPassInterface;
  6. use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
  7. use Symfony\Component\DependencyInjection\ContainerBuilder;
  8. use Symfony\Component\DependencyInjection\Reference;
  9. class RegisterEventListenersAndSubscribersPass implements CompilerPassInterface
  10. {
  11.     public function process(ContainerBuilder $container)
  12.     {
  13.         $listeners = [];
  14.         $listenerServices = [];
  15.         foreach ($container->findTaggedServiceIds('jms_serializer.event_listener') as $id => $tags) {
  16.             foreach ($tags as $attributes) {
  17.                 if (!isset($attributes['event'])) {
  18.                     throw new \RuntimeException(sprintf('The tag "jms_serializer.event_listener" of service "%s" requires an attribute named "event".'$id));
  19.                 }
  20.                 $class = isset($attributes['class'])
  21.                     ? $container->getParameterBag()->resolveValue($attributes['class'])
  22.                     : null;
  23.                 $format $attributes['format'] ?? null;
  24.                 $method $attributes['method'] ?? EventDispatcher::getDefaultMethodName($attributes['event']);
  25.                 $priority = isset($attributes['priority']) ? (int) $attributes['priority'] : 0;
  26.                 if (class_exists(ServiceLocatorTagPass::class) || $container->getDefinition($id)->isPublic()) {
  27.                     $listenerServices[$id] = new Reference($id);
  28.                     $listeners[$attributes['event']][$priority][] = [[$id$method], $class$format];
  29.                 } else {
  30.                     $listeners[$attributes['event']][$priority][] = [[new Reference($id), $method], $class$format];
  31.                 }
  32.             }
  33.         }
  34.         foreach ($container->findTaggedServiceIds('jms_serializer.event_subscriber') as $id => $tags) {
  35.             $subscriberClass $container->getDefinition($id)->getClass();
  36.             $subscriberClassReflectionObj = new \ReflectionClass($subscriberClass);
  37.             if (!$subscriberClassReflectionObj->implementsInterface('JMS\Serializer\EventDispatcher\EventSubscriberInterface')) {
  38.                 throw new \RuntimeException(sprintf('The service "%s" (class: %s) does not implement the EventSubscriberInterface.'$id$subscriberClass));
  39.             }
  40.             foreach (call_user_func([$subscriberClass'getSubscribedEvents']) as $eventData) {
  41.                 if (!isset($eventData['event'])) {
  42.                     throw new \RuntimeException(sprintf('The service "%s" (class: %s) must return an event for each subscribed event.'$id$subscriberClass));
  43.                 }
  44.                 $class $eventData['class'] ?? null;
  45.                 $format $eventData['format'] ?? null;
  46.                 $method $eventData['method'] ?? EventDispatcher::getDefaultMethodName($eventData['event']);
  47.                 $priority = isset($eventData['priority']) ? (int) $eventData['priority'] : 0;
  48.                 $interface $eventData['interface'] ?? null;
  49.                 if (class_exists(ServiceLocatorTagPass::class) || $container->getDefinition($id)->isPublic()) {
  50.                     $listenerServices[$id] = new Reference($id);
  51.                     $listeners[$eventData['event']][$priority][] = [[$id$method], $class$format$interface];
  52.                 } else {
  53.                     $listeners[$eventData['event']][$priority][] = [[new Reference($id), $method], $class$format$interface];
  54.                 }
  55.             }
  56.         }
  57.         if ($listeners) {
  58.             array_walk($listeners, static function (&$value$key) {
  59.                 ksort($value);
  60.             });
  61.             foreach ($listeners as &$events) {
  62.                 $events call_user_func_array('array_merge'$events);
  63.             }
  64.             $container->findDefinition('jms_serializer.event_dispatcher')
  65.                 ->addMethodCall('setListeners', [$listeners]);
  66.         }
  67.         if (class_exists(ServiceLocatorTagPass::class)) {
  68.             $serviceLocator ServiceLocatorTagPass::register($container$listenerServices);
  69.             $container->getDefinition('jms_serializer.event_dispatcher')->replaceArgument(0$serviceLocator);
  70.         }
  71.     }
  72. }