所以这毕竟是可能的。满足我需求的解决方案如下:
- 通过树枝传递当前路径:
AppBundle/Resources/views/base.html.twig
{{ render_esi(controller('AppBundle:Menu:mainESI', { 'currentPath': currentPath })) }}
- 获取控制器动作中的变量:
AppBundle/Controller/MenuAdminController.php
public function mainESIAction($currentPath = null)
{
return $this->render('menu/main_menu_esi.html.twig', [
'currentPath' => $currentPath,
]);
}
- 使用 Matcher/Voter 类:
AppBundle/Matcher/Voter/PathVoter.php
<?php
namespace AppBundle\Matcher\Voter;
use Knp\Menu\ItemInterface;
use Knp\Menu\Matcher\Voter\VoterInterface;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Class PathVoter
*/
class PathVoter implements VoterInterface
{
protected $uri;
/**
* @param RequestStack $requestStack
*/
public function setRequest(RequestStack $requestStack)
{
if (($request = $requestStack->getCurrentRequest())) {
$pathInfo = $request->getPathInfo();
$requestUri = $request->getRequestUri();
if (!empty($pathInfo) && '/_fragment' === $pathInfo && !empty($request->attributes->get('currentPath'))) {
$this->uri = $request->attributes->get('currentPath');
} else {
$this->uri = $pathInfo;
}
}
}
/**
* @param ItemInterface $item
* @return bool|void
*/
public function matchItem(ItemInterface $item)
{
$uri = $item->getUri();
if ((null === $this->uri) || (null === $uri)) {
return;
}
if ($item->getUri() === $this->uri) {
return true;
}
return;
}
}
- 登记选民
AppBundle/Resources/config/services.yml
parameters:
app.menu.voter.class: AppBundle\MenuBundle\Matcher\Voter\PathVoter
services:
app.menu.voter:
class: %app.menu.voter.class%
calls:
- [setRequest, [@request_stack]]
tags:
- { name: knp_menu.voter }