如何在Symfony2中为每个匹配的路由进行公共呼叫?

时间:2013-06-19 07:30:11

标签: symfony

我有这样的路线:

events_print:
    pattern:  /list
    defaults:
        _controller: AcmeCompanyBundle:Events:list
        activeMenu: conferences_events_list

events_edit:
    pattern:  /edit/{id}
    defaults:
        _controller: AcmeCompanyBundle:Events:edit
        activeMenu: conferences_events_edit

在控制器的每个动作中我都要这样做:

$menuBuilder = $this->container->get('acme.menu_builder');
$menuBuilder->setActiveMenu($activeMenu);

如果我能以某种方式拦截匹配的路线并在一个地方而不是在每个动作中呼叫setActiveMenu(),那将是很好的。这有什么好办法吗?

更新:我已经简化了一些示例,因此您不会对不必要的细节感到困惑。

2 个答案:

答案 0 :(得分:1)

我终于找到了可能对其他人有用的解决方案。 我们可以监听kernel.controller事件:

acme.kernel_listener:
    class: Acme\Company\Bundle\EventListener\KernelListener
    arguments:
        container: "@service_container"
    tags:
        - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }

在事件听众中:

public function onKernelController(FilterControllerEvent $event)
{
    $route = $this->container->get('request')->get('_route');
    if ($routeObj = $this->container->get('router')->getRouteCollection()->get($route)) {
        $defaults = $routeObj->getDefaults();
    }
    // do some common stuff
}

现在我们可以在一个地方做所有常见的事情。

答案 1 :(得分:1)

我猜你需要的是一个控制器监听器

services.yml

services:
    acme_controller.listener:
        class: Acme\CompanyBundle\Listener\ControllerListener
        arguments: [ @acme.menu_builder ]
        tags:
            - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }

ControllerListener.php

<?php

namespace Acme\CompanyBundle\Listener;

use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

/**
 * Controller listener
 */
class ControllerListener
{
    protected $menuBuilder;

    /**
     * Constructor
     *
     * @param Object $menuBuilder A Menu Builder instance
     */
    public function __construct($menuBuilder)
    {
        $this->menuBuilder = $menuBuilder;
    }

    /**
     * Sets the active menu
     *
     * @param  FilterControllerEvent $event
     */
    public function onKernelController(FilterControllerEvent $event)
    {
        $controller = $event->getController();
        $request    = $event->getRequest();

        /**
         * Your logic
         */

        $this->menuBuilder->setActiveMenu($activeMenu);
    }
}