Переглянути джерело

Merge pull request #196 from adrienbrault/patch-2

Fix RegisterEventListenersAndSubscribersPass & event_subscribers service accessibility
Johannes 12 роки тому
батько
коміт
00e8f91427

+ 23 - 8
DependencyInjection/Compiler/RegisterEventListenersAndSubscribersPass.php

@@ -12,45 +12,60 @@ class RegisterEventListenersAndSubscribersPass implements CompilerPassInterface
     {
         $listeners = array();
         foreach ($container->findTaggedServiceIds('jms_serializer.event_listener') as $id => $tags) {
+            if (!$container->getDefinition($id)->isPublic()) {
+                throw new \RuntimeException(sprintf('The tag "jms_serializer.event_listener" of service "%s" requires the service to be public.', $id));
+            }
+
             foreach ($tags as $attributes) {
                 if ( ! isset($attributes['event'])) {
                     throw new \RuntimeException(sprintf('The tag "jms_serializer.event_listener" of service "%s" requires an attribute named "event".', $id));
                 }
 
-                $class = isset($attributes['class']) ? $attributes['class'] : null;
+                $class = isset($attributes['class']) ? strtolower($attributes['class']) : null;
                 $format = isset($attributes['format']) ? $attributes['format'] : null;
                 $method = isset($attributes['method']) ? $attributes['method'] : EventDispatcher::getDefaultMethodName($attributes['event']);
                 $priority = isset($attributes['priority']) ? (integer) $attributes['priority'] : 0;
 
-                $listeners[$priority][] = array($attributes['event'], array($id, $method), $class, $format);
+                $listeners[$attributes['event']][$priority][] = array(array($id, $method), $class, $format);
             }
         }
 
         foreach ($container->findTaggedServiceIds('jms_serializer.event_subscriber') as $id => $tags) {
-            $subscriberClass = $container->getDefinition($id)->getClass();
+            $subscriberDefinition = $container->getDefinition($id);
+            $subscriberClass = $subscriberDefinition->getClass();
             if ( ! is_subclass_of($subscriberClass, 'JMS\SerializerBundle\Serializer\EventDispatcher\EventSubscriberInterface')) {
                 throw new \RuntimeException(sprintf('The service "%s" (class: %s) does not implement the EventSubscriberInterface.', $id, $subscriberClass));
             }
 
+            if (!$subscriberDefinition->isPublic()) {
+                throw new \RuntimeException(sprintf('The tag "jms_serializer.event_listener" of service "%s" requires the service to be public.', $id));
+            }
+
             foreach (call_user_func(array($subscriberClass, 'getSubscribedEvents')) as $eventData) {
                 if ( ! isset($eventData['event'])) {
                     throw new \RuntimeException(sprintf('The service "%s" (class: %s) must return an event for each subscribed event.', $id, $subscriberClass));
                 }
 
-                $class = isset($eventData['class']) ? $eventData['class'] : null;
+                $class = isset($eventData['class']) ? strtolower($eventData['class']) : null;
                 $format = isset($eventData['format']) ? $eventData['format'] : null;
                 $method = isset($eventData['method']) ? $eventData['method'] : EventDispatcher::getDefaultMethodName($eventData['event']);
-                $priority = isset($attributes['priority']) ? (integer) $attributes['priority'] : 0;
+                $priority = isset($attributes['priority']) ? (integer) $attributes['priority'] : 0;
 
-                $listeners[$priority][] = array($eventData['event'], array($id, $method), $class, $format);
+                $listeners[$eventData['event']][$priority][] = array(array($id, $method), $class, $format);
             }
         }
 
         if ($listeners) {
-            ksort($listeners);
+            array_walk($listeners, function (&$value, $key) {
+                ksort($value);
+            });
+
+            foreach ($listeners as &$events) {
+                $events = call_user_func_array('array_merge', $events);
+            }
 
             $container->getDefinition('jms_serializer.event_dispatcher')
-                ->addMethodCall('setListeners', array(call_user_func_array('array_merge', $listeners)));
+                ->addMethodCall('setListeners', array($listeners));
         }
     }
 }

+ 1 - 1
Resources/config/services.xml

@@ -54,7 +54,7 @@
         <service id="jms_serializer.event_dispatcher" class="%jms_serializer.event_dispatcher.class%" public="false">
             <argument type="service" id="service_container" />
         </service>
-        <service id="jms_serializer.doctrine_proxy_subscriber" class="%jms_serializer.doctrine_proxy_subscriber.class%" public="false">
+        <service id="jms_serializer.doctrine_proxy_subscriber" class="%jms_serializer.doctrine_proxy_subscriber.class%">
             <tag name="jms_serializer.event_subscriber" />
         </service>