Skip to content

Commit

Permalink
Added support for events in menu builder
Browse files Browse the repository at this point in the history
  • Loading branch information
hason committed May 28, 2015
1 parent 3f6874f commit 6a02714
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 8 deletions.
55 changes: 55 additions & 0 deletions Event/ConfigureMenuEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

/*
* This file is part of the Sonata package.
*
* (c) Thomas Rabaix <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\AdminBundle\Event;

use Knp\Menu\FactoryInterface;
use Knp\Menu\ItemInterface;
use Symfony\Component\EventDispatcher\Event;

/**
* Menu builder event. Used for extending the menus.
*
* @author Martin Hasoň <[email protected]>
*/
class ConfigureMenuEvent extends Event
{
const SIDEBAR = 'sonata.admin.event.configure.menu.sidebar';

private $factory;
private $menu;

/**
* @param FactoryInterface $factory
* @param ItemInterface $menu
*/
public function __construct(FactoryInterface $factory, ItemInterface $menu)
{
$this->factory = $factory;
$this->menu = $menu;
}

/**
* @return FactoryInterface
*/
public function getFactory()
{
return $this->factory;
}

/**
* @return ItemInterface
*/
public function getMenu()
{
return $this->menu;
}
}
18 changes: 13 additions & 5 deletions Menu/MenuBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
use Knp\Menu\ItemInterface;
use Knp\Menu\Provider\MenuProviderInterface;
use Sonata\AdminBundle\Admin\Pool;
use Sonata\AdminBundle\Event\ConfigureMenuEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;

/**
Expand All @@ -28,19 +30,22 @@ class MenuBuilder
private $factory;
private $provider;
private $request;
private $eventDispatcher;

/**
* Constructor.
*
* @param Pool $pool
* @param FactoryInterface $factory
* @param MenuProviderInterface $provider
* @param Pool $pool
* @param FactoryInterface $factory
* @param MenuProviderInterface $provider
* @param EventDispatcherInterface $eventDispatcher
*/
public function __construct(Pool $pool, FactoryInterface $factory, MenuProviderInterface $provider)
public function __construct(Pool $pool, FactoryInterface $factory, MenuProviderInterface $provider, EventDispatcherInterface $eventDispatcher)
{
$this->pool = $pool;
$this->factory = $factory;
$this->provider = $provider;
$this->eventDispatcher = $eventDispatcher;
}

/**
Expand Down Expand Up @@ -120,7 +125,10 @@ public function createSidebarMenu()
}
}

return $menu;
$event = new ConfigureMenuEvent($this->factory, $menu);
$this->eventDispatcher->dispatch(ConfigureMenuEvent::SIDEBAR, $event);

return $event->getMenu();
}

/**
Expand Down
1 change: 1 addition & 0 deletions Resources/config/menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<argument type="service" id="sonata.admin.pool" />
<argument type="service" id="knp_menu.factory" />
<argument type="service" id="knp_menu.menu_provider" />
<argument type="service" id="event_dispatcher" />
<call method="setRequest"><argument type="service" id="request" on-invalid="null" strict="false" /></call>
</service>

Expand Down
43 changes: 41 additions & 2 deletions Resources/doc/cookbook/recipe_knp_menu.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
KnpMenu
=======

The admin comes with `KnpMenu <https://github.com/KnpLabs/KnpMenu>`_ integration.
The admin comes with `KnpMenu`_ integration.
It integrates a menu with the KnpMenu library. This menu can be a SonataAdmin service, a menu created with a Knp menu provider or a route of a custom controller.

Add a custom controller entry in the menu
Expand Down Expand Up @@ -81,7 +81,7 @@ The following configuration uses a menu provider to populate the menu group ``my
provider: 'MyBundle:MyMenuProvider:getMyMenu'
icon: '<i class="fa fa-edit"></i>'
With KnpMenuBundle you can create a custom menu by using a builder class or by declaring it as a service. Please see the `Knp documentation <http://symfony.com/doc/current/bundles/KnpMenuBundle/index.html#create-your-first-menu>`_ for further information.
With KnpMenuBundle you can create a custom menu by using a builder class or by declaring it as a service. Please see the `Knp documentation`_ for further information.

In sonata, whatever the implementation you choose, you only have to provide the menu alias to the provider config key:

Expand All @@ -94,3 +94,42 @@ In sonata, whatever the implementation you choose, you only have to provide the
</service>
Please note that when using the provider option, you can't set the menu label via the configuration. It is done in your custom menu.

Extending the menu
------------------

You can modify the menu via events easily. You can register as many listeners as you want for the event with name ``sonata.admin.event.configure.menu.sidebar``:

.. code-block:: php
// src/AppBundle/EventListener/MenuBuilderListener.php
namespace AppBundle\EventListener;
use Sonata\AdminBundle\Event\ConfigureMenuEvent;
class MenuBuilderListener
{
public function addMenuItems(ConfigureMenuEvent $event)
{
$menu = $event->getMenu();
$menu->addChild('reports', array(
'route' => 'app_reports_index',
'labelAttributes' => array('icon' => 'glyphicon glyphicon-stats'),
))->setLabel('Daily and monthly reports');
}
}
.. code-block:: yaml
services:
app.menu_listener:
class: AppBundle\EventListener\MenuBuilderListener
tags:
- { name: kernel.event_listener, event: sonata.admin.event.configure.menu.sidebar, method: addMenuItems }
Please see the `Using events to allow a menu to be extended`_ for further information.

.. _KnpMenu: https://github.com/KnpLabs/KnpMenu
.. _Knp documentation: http://symfony.com/doc/current/bundles/KnpMenuBundle/index.html#create-your-first-menu
.. _Using events to allow a menu to be extended: http://symfony.com/doc/master/bundles/KnpMenuBundle/events.html
28 changes: 27 additions & 1 deletion Tests/Menu/MenuBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,17 @@ class MenuBuilderTest extends \PHPUnit_Framework_TestCase
private $pool;
private $provider;
private $factory;
private $eventDispatcher;
private $builder;

protected function setUp()
{
$this->pool = $this->getMockBuilder('Sonata\AdminBundle\Admin\Pool')->disableOriginalConstructor()->getMock();
$this->provider = $this->getMock('Knp\Menu\Provider\MenuProviderInterface');
$this->factory = new MenuFactory();
$this->eventDispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');

$this->builder = new MenuBuilder($this->pool, $this->factory, $this->provider);
$this->builder = new MenuBuilder($this->pool, $this->factory, $this->provider, $this->eventDispatcher);
}

public function testGetKnpMenu()
Expand Down Expand Up @@ -243,6 +245,30 @@ public function testGetKnpMenuWithProvider()
}
}

public function testGetKnpMenuAndDispatchEvent()
{
$adminGroups = array(
"bar" => array(
"label" => "foo",
"icon" => '<i class="fa fa-edit"></i>',
"label_catalogue" => 'SonataAdminBundle',
"items" => array(),
"item_adds" => array(),
"roles" => array(),
),
);

$this->preparePool($adminGroups);

$this->eventDispatcher
->expects($this->once())
->method('dispatch')
->with($this->equalTo('sonata.admin.event.configure.menu.sidebar'), $this->isInstanceOf('Sonata\AdminBundle\Event\ConfigureMenuEvent'))
;

$this->builder->createSidebarMenu();
}

private function preparePool($adminGroups, $admin = null)
{
$this->pool->expects($this->once())
Expand Down

0 comments on commit 6a02714

Please sign in to comment.