Skip to content
Browse files

Added a listener to inject the master request in voters

  • Loading branch information...
1 parent 8aee89d commit a061f571b4d9fbaae4adf045e99f7106f58deeee @stof stof committed
View
8 DependencyInjection/Compiler/AddVotersPass.php
@@ -18,10 +18,18 @@ public function process(ContainerBuilder $container)
if (!$container->hasDefinition('knp_menu.matcher')) {
return;
}
+
$definition = $container->getDefinition('knp_menu.matcher');
+ $listener = $container->getDefinition('knp_menu.listener.voters');
foreach ($container->findTaggedServiceIds('knp_menu.voter') as $id => $tags) {
$definition->addMethodCall('addVoter', array(new Reference($id)));
+
+ foreach ($tags as $tag) {
+ if (isset($tag['request']) && $tag['request']) {
+ $listener->addMethodCall('addVoter', array(new Reference($id)));
+ }
+ }
}
}
}
View
49 EventListener/VoterInitializerListener.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Knp\Bundle\MenuBundle\EventListener;
+
+use Knp\Menu\Matcher\Voter\VoterInterface;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
+
+/**
+ * VoterInitializerListener sets the master request in voters needing it.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class VoterInitializerListener implements EventSubscriberInterface
+{
+ protected $voters = array();
+
+ public function onKernelRequest(GetResponseEvent $event)
+ {
+ if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
+ return;
+ }
+
+ foreach ($this->voters as $voter) {
+ if (method_exists($voter, 'setRequest')) {
+ $voter->setRequest($event->getRequest());
+ }
+ }
+ }
+
+ /**
+ * Adds a voter in the matcher.
+ *
+ * @param VoterInterface $voter
+ */
+ public function addVoter(VoterInterface $voter)
+ {
+ $this->voters[] = $voter;
+ }
+
+ public static function getSubscribedEvents()
+ {
+ return array(
+ KernelEvents::REQUEST => 'onKernelRequest',
+ );
+ }
+}
View
4 Resources/config/menu.xml
@@ -55,6 +55,10 @@
<argument>%knp_menu.renderer.list.options%</argument>
<argument>%kernel.charset%</argument>
</service>
+
+ <service id="knp_menu.listener.voters" class="Knp\Bundle\MenuBundle\EventListener\VoterInitializerListener">
+ <tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" />
+ </service>
</services>
</container>
View
20 Tests/DependencyInjection/Compiler/AddVotersPassTest.php
@@ -26,9 +26,19 @@ public function testProcessWithAlias()
$definitionMock = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')
->disableOriginalConstructor()
->getMock();
- $definitionMock->expects($this->once())
+ $definitionMock->expects($this->at(0))
->method('addMethodCall')
->with($this->equalTo('addVoter'), $this->equalTo(array(new Reference('id'))));
+ $definitionMock->expects($this->at(1))
+ ->method('addMethodCall')
+ ->with($this->equalTo('addVoter'), $this->equalTo(array(new Reference('foo'))));
+
+ $listenerMock = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $listenerMock->expects($this->once())
+ ->method('addMethodCall')
+ ->with($this->equalTo('addVoter'), $this->equalTo(array(new Reference('foo'))));
$containerBuilderMock = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder');
$containerBuilderMock->expects($this->once())
@@ -37,11 +47,15 @@ public function testProcessWithAlias()
$containerBuilderMock->expects($this->once())
->method('findTaggedServiceIds')
->with($this->equalTo('knp_menu.voter'))
- ->will($this->returnValue(array('id' => array('tag1' => array()))));
- $containerBuilderMock->expects($this->once())
+ ->will($this->returnValue(array('id' => array('tag1' => array(), 'tag2' => array('request' => false)), 'foo' => array('tag1' => array('request' => true)))));
+ $containerBuilderMock->expects($this->at(1))
->method('getDefinition')
->with($this->equalTo('knp_menu.matcher'))
->will($this->returnValue($definitionMock));
+ $containerBuilderMock->expects($this->at(2))
+ ->method('getDefinition')
+ ->with($this->equalTo('knp_menu.listener.voters'))
+ ->will($this->returnValue($listenerMock));
$menuPass = new AddVotersPass();
$menuPass->process($containerBuilderMock);
View
59 Tests/EventListener/VoterInitializerListenerTest.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Knp\Bundle\MenuBundle\Tests\EventListener;
+
+use Knp\Bundle\MenuBundle\EventListener\VoterInitializerListener;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+
+class MenuPassTest extends \PHPUnit_Framework_TestCase
+{
+ public function testHandleSubRequest()
+ {
+ $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $event->expects($this->once())
+ ->method('getRequestType')
+ ->will($this->returnValue(HttpKernelInterface::SUB_REQUEST));
+
+ $voter = $this->getMockBuilder('Knp\Menu\Silex\Voter\RouteVoter')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $voter->expects($this->never())
+ ->method('setRequest');
+
+ $listener = new VoterInitializerListener();
+ $listener->addVoter($voter);
+
+ $listener->onKernelRequest($event);
+ }
+
+ public function testHandleMasterRequest()
+ {
+ $request = new Request();
+
+ $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $event->expects($this->once())
+ ->method('getRequestType')
+ ->will($this->returnValue(HttpKernelInterface::MASTER_REQUEST));
+ $event->expects($this->once())
+ ->method('getRequest')
+ ->will($this->returnValue($request));
+
+ $voter = $this->getMockBuilder('Knp\Menu\Silex\Voter\RouteVoter')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $voter->expects($this->once())
+ ->method('setRequest')
+ ->with($this->equalTo($request));
+
+ $listener = new VoterInitializerListener();
+ $listener->addVoter($voter);
+ $listener->addVoter($this->getMock('Knp\Menu\Matcher\Voter\VoterInterface'));
+
+ $listener->onKernelRequest($event);
+ }
+}

0 comments on commit a061f57

Please sign in to comment.
Something went wrong with that request. Please try again.