RegisterEventListenersAndSubscribersPass.php 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. <?php
  2. namespace JMS\SerializerBundle\DependencyInjection\Compiler;
  3. use JMS\SerializerBundle\Serializer\EventDispatcher\EventDispatcher;
  4. use Symfony\Component\DependencyInjection\ContainerBuilder;
  5. use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
  6. class RegisterEventListenersAndSubscribersPass implements CompilerPassInterface
  7. {
  8. public function process(ContainerBuilder $container)
  9. {
  10. $listeners = array();
  11. foreach ($container->findTaggedServiceIds('jms_serializer.event_listener') as $id => $tags) {
  12. if (!$container->getDefinition($id)->isPublic()) {
  13. throw new \RuntimeException(sprintf('The tag "jms_serializer.event_listener" of service "%s" requires the service to be public.', $id));
  14. }
  15. foreach ($tags as $attributes) {
  16. if ( ! isset($attributes['event'])) {
  17. throw new \RuntimeException(sprintf('The tag "jms_serializer.event_listener" of service "%s" requires an attribute named "event".', $id));
  18. }
  19. $class = isset($attributes['class']) ? strtolower($attributes['class']) : null;
  20. $format = isset($attributes['format']) ? $attributes['format'] : null;
  21. $method = isset($attributes['method']) ? $attributes['method'] : EventDispatcher::getDefaultMethodName($attributes['event']);
  22. $priority = isset($attributes['priority']) ? (integer) $attributes['priority'] : 0;
  23. $listeners[$attributes['event']][$priority][] = array(array($id, $method), $class, $format);
  24. }
  25. }
  26. foreach ($container->findTaggedServiceIds('jms_serializer.event_subscriber') as $id => $tags) {
  27. $subscriberDefinition = $container->getDefinition($id);
  28. $subscriberClass = $subscriberDefinition->getClass();
  29. if ( ! is_subclass_of($subscriberClass, 'JMS\SerializerBundle\Serializer\EventDispatcher\EventSubscriberInterface')) {
  30. throw new \RuntimeException(sprintf('The service "%s" (class: %s) does not implement the EventSubscriberInterface.', $id, $subscriberClass));
  31. }
  32. if (!$subscriberDefinition->isPublic()) {
  33. throw new \RuntimeException(sprintf('The tag "jms_serializer.event_listener" of service "%s" requires the service to be public.', $id));
  34. }
  35. foreach (call_user_func(array($subscriberClass, 'getSubscribedEvents')) as $eventData) {
  36. if ( ! isset($eventData['event'])) {
  37. throw new \RuntimeException(sprintf('The service "%s" (class: %s) must return an event for each subscribed event.', $id, $subscriberClass));
  38. }
  39. $class = isset($eventData['class']) ? strtolower($eventData['class']) : null;
  40. $format = isset($eventData['format']) ? $eventData['format'] : null;
  41. $method = isset($eventData['method']) ? $eventData['method'] : EventDispatcher::getDefaultMethodName($eventData['event']);
  42. $priority = isset($attributes['priority']) ? (integer) $attributes['priority'] : 0;
  43. $listeners[$eventData['event']][$priority][] = array(array($id, $method), $class, $format);
  44. }
  45. }
  46. if ($listeners) {
  47. array_walk($listeners, function (&$value, $key) {
  48. ksort($value);
  49. });
  50. foreach ($listeners as &$events) {
  51. $events = call_user_func_array('array_merge', $events);
  52. }
  53. $container->getDefinition('jms_serializer.event_dispatcher')
  54. ->addMethodCall('setListeners', array($listeners));
  55. }
  56. }
  57. }