zetta/menu-bundle

Admin menu

Installs: 272

Dependents: 0

Stars: 7

Watchers: 4

Forks: 1

Language: PHP

v1.1.5 2013-06-06 17:58 UTC

README

One Menu To Rule Them All

This bundle is an extension of KnpMenuBundle with which you can add a main menu for the system and this will be filtered depending on user role.

Features

  • The menus can be set from the configuration file app/config/config.yml
  • The menu links are automatically filtered by the rules defined in the firewall
  • JMSSecurityExtraBundle annotations are supported for creating the filter
  • Integration with existing menus on your bundle thanks to the @SecureMenu annotation

Requirements

Installation

In order to install the bundle you need to add the dependency in composer.json file.

    //composer.json
    "require": {
        "zetta/menu-bundle" : "1.1.*"
    }

Then you must register the bundle in the kernel of the application.

// app/AppKernel.php
    $bundles = array(
        ....
        new Knp\Bundle\MenuBundle\KnpMenuBundle(),
        new Zetta\MenuBundle\ZettaMenuBundle()

It is important that the ZettaMenuBundle statement is after KnpMenuBundle

Usage

There are two ways to filter our menus.

Simple way

If you use the simple method for creating menus

// src/Acme/DemoBundle/Menu/Builder.php
namespace Acme\DemoBundle\Menu;

use Knp\Menu\FactoryInterface;
use Symfony\Component\DependencyInjection\ContainerAware;

class Builder extends ContainerAware
{
    public function mainMenu(FactoryInterface $factory, array $options)
    {
        $menu = $factory->createItem('root');

        $menu->addChild('Home', array('route' => 'homepage'));
        $menu->addChild('About Me', array(
            'route' => 'page_show',
            'routeParameters' => array('id' => 42)
        ));
        // ... add more children

        return $menu;
    }
}

Simply add the annotation Zetta\MenuBundle\Annotation\SecureMenu to the method to filter the items.

// src/Acme/DemoBundle/Menu/Builder.php
namespace Acme\DemoBundle\Menu;

use Knp\Menu\FactoryInterface;
use Symfony\Component\DependencyInjection\ContainerAware;
use Zetta\MenuBundle\Annotation\SecureMenu;

class Builder extends ContainerAware
{
    /**
     * @SecureMenu
     */
    public function mainMenu(FactoryInterface $factory, array $options)
    {
        $menu = $factory->createItem('root');

        $menu->addChild('Home', array('route' => 'homepage'));
        $menu->addChild('About Me', array(
            'route' => 'page_show',
            'routeParameters' => array('id' => 42)
        ));
        // ... add more children

        return $menu;
    }
}

Configuration Method config.yml

We define a menu in the configuration file

#app/config/config.yml
zetta_menu:
    menus:
        admin:
            childrenAttributes:
                class: 'nav'
            children:
                dashboard:
                    label: 'Dashboard'
                    route: '_welcome'
                users:
                    label: '<i>Users</i>'
                    uri: '/user/'
                    extras:
                        safe_label: true
                    attributes:
                        id: 'user'
                    linkAttributes:
                        class: 'link'
                    children:
                        new:
                            label: 'New User'
                            uri: '/user/new'
                        archive:
                            label: 'User archive'
                            uri: '/user/archive'
                catalogs:
                    label: 'Catalogs'
                    route: 'catalogs'
                    children:
                        status:
                            label: 'Status'
                            uri: '/status/list'
                statistics:
                    label: 'Stats'
                    uri: '/admin/stats'

        sidebar:  #another one ...
            children:
                sidebar1:
                    label: "Sidebar 1"

Support KNP Menu Option

  • attributes
  • linkAttributes
  • childrenAttributes
  • labelAttributes
  • extras
  • displayChildren

Using the knp twig helper we can print it

    {{ knp_menu_render('admin') }}

By defailt if no deny rules exists in firewall or annotations the full menu will be printed

  • Dashboard
  • Users
    • New User
    • User Archive
  • Catalogs
    • Status
  • Stats

In order to affect the menu render we start to define rules in our firewall

#app/config/security.yml
security:

    role_hierarchy:
        ROLE_MANAGER:       ROLE_USER
        ROLE_ADMIN:         ROLE_MANAGER
    ...
    access_control:
        - { path: ^/admin/, role: ROLE_ADMIN }
        - { path: ^/user/new, role: ROLE_MANAGER }
        - { path: ^/$, role: ROLE_USER }

The system administrator can then see the full menu, however if a user authenticated with ROLE_USER can only view:

  • Dashboard
  • Usuarios
    • Usuarios históricos
  • Catálogos
    • Status
Annotations

Assuming we have catalogs route defined in routing.yml

#app/config/routing.yml
catalogs:
    pattern: /catalogs/
    defaults: {_controller: ExampleBundle:Catalogs:index}

We add the annotation in the controller's method

// src/Acme/ExampleBundle/Controller/CatalogsController.php
use JMS\SecurityExtraBundle\Annotation\Secure;

class CatalogsController{

    /**
     * @Secure(roles="ROLE_MANAGER")
     */
    public function indexAction()
    {
        // ... blah
    }

}

The same user with ROLE_USER will see:

  • Dashboard
  • Usuarios
    • Usuarios históricos