RegisterEventListenersAndSubscribersPass.php 4.1 KB

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