Gist で共有されているこのコードを見つけました (どこかでリンクを失った)。そのようなものが必要だったので、アプリケーションで使用し始めましたが、まだ完全には理解していないため、いくつかの問題が発生しています。
KnpMenuBundle と動的手段を使用して動的メニューを作成しようとしています。ある時点で、データベースを介してアクセス許可を確認する必要があり、コントローラーからルートを読み取ることができれば理想的ですが、これは別のタスクであり、おそらく注釈を作成することができますその時が来たら、別のトピックを開きます。
現在、SecurityContext にアクセスして、ユーザーがログに記録されているかどうかを確認する必要がありますが、その方法はわかりません。
私はメニューをレンダリングしていますがRequestVoter
(私は思う)、これがコードです:
namespace PlantillaBundle\Menu;
use Knp\Menu\ItemInterface;
use Knp\Menu\Matcher\Voter\VoterInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\SecurityContextInterface;
class RequestVoter implements VoterInterface {
private $container;
private $securityContext;
public function __construct(ContainerInterface $container, SecurityContextInterface $securityContext)
{
$this->container = $container;
$this->securityContext = $securityContext;
}
public function matchItem(ItemInterface $item)
{
if ($item->getUri() === $this->container->get('request')->getRequestUri())
{
// URL's completely match
return true;
}
else if ($item->getUri() !== $this->container->get('request')->getBaseUrl() . '/' && (substr($this->container->get('request')->getRequestUri(), 0, strlen($item->getUri())) === $item->getUri()))
{
// URL isn't just "/" and the first part of the URL match
return true;
}
return null;
}
}
に関連するすべてのコードsecurityContext
は、menuBuilder
. これは、メニューを作成しているコードです。
namespace PlantillaBundle\Menu;
use Knp\Menu\FactoryInterface;
use Symfony\Component\DependencyInjection\ContainerAware;
class MenuBuilder extends ContainerAware {
public function mainMenu(FactoryInterface $factory, array $options)
{
// and here is where I need to access securityContext
// and in the near future EntityManger
$user = $this->securityContext->getToken()->getUser();
$logged_in = $this->securityContext->isGranted('IS_AUTHENTICATED_FULLY');
$menu = $factory->createItem('root');
$menu->setChildrenAttribute('class', 'nav');
if ($logged_in)
{
$menu->addChild('Home', array('route' => 'home'))->setAttribute('icon', 'fa fa-list');
}
else
{
$menu->addChild('Some Menu');
}
return $menu;
}
}
しかし、メソッドに渡していないため、これは完全に間違っていsecurityContext
ます。方法がわからず、このエラーが発生しています。
テンプレートのレンダリング中に例外がスローされました (「通知: 未定義のプロパティ: PlantillaBundle\Menu\MenuBuilder::$securityContext in /var/www/html/src/PlantillaBundle/Menu/MenuBuilder.php 12 行目」) / var/www/html/src/PlantillaBundle/Resources/views/menu.html.twig の 2 行目。
投票者は次のように定義さservices.yml
れます。
plantilla.menu.voter.request:
class: PlantillaBundle\Menu\RequestVoter
arguments:
- @service_container
- @security.context
tags:
- { name: knp_menu.voter }
では、どのように注入securityContext
し (同じ手順になると思われるので、EntityManager は要求しません)、menuBuilder からアクセスしますか?
更新: コードのリファクタリング
したがって、@Cerad の提案に従って、この変更を行いました。
services.yml
services:
plantilla.menu_builder:
class: PlantillaBundle\Menu\MenuBuilder
arguments: ["@knp_menu.factory", "@security.context"]
plantilla.frontend_menu_builder:
class: Knp\Menu\MenuItem # the service definition requires setting the class
factory_service: plantilla.menu_builder
factory_method: createMainMenu
arguments: ["@request_stack"]
tags:
- { name: knp_menu.menu, alias: frontend_menu }
MenuBuilder.php
namespace PlantillaBundle\Menu;
use Knp\Menu\FactoryInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class MenuBuilder {
/**
* @var Symfony\Component\Form\FormFactory $factory
*/
private $factory;
/**
* @var Symfony\Component\Security\Core\SecurityContext $securityContext
*/
private $securityContext;
/**
* @param FactoryInterface $factory
*/
public function __construct(FactoryInterface $factory, $securityContext)
{
$this->factory = $factory;
$this->securityContext = $securityContext;
}
public function createMainMenu(RequestStack $request)
{
$user = $this->securityContext->getToken()->getUser();
$logged_in = $this->securityContext->isGranted('IS_AUTHENTICATED_FULLY');
$menu = $this->factory->createItem('root');
$menu->setChildrenAttribute('class', 'nav');
if ($logged_in)
{
$menu->addChild('Home', array('route' => 'home'))->setAttribute('icon', 'fa fa-list');
}
else
{
$menu->addChild('Some Menu');
}
return $menu;
}
}
Abd ib 私のテンプレートはメニューをレンダリングするだけです{{ knp_menu_render('frontend_menu') }}
が、FontAwesome 部分が失われ、機能する前に、なぜですか?