У моего пользователя есть свойство countTasks
с соответствующим сеттером и геттером:
class User implements UserInterface, \Serializable
{
/**
* @var integer
*/
private $countTasks;
}
Я хочу, чтобы это свойство всегда отображалось на панели навигации приложения (цифра "14" красного цвета):
Очевидно, что это свойство должно быть установлено для каждого контроллера. (На самом деле, только для всех, кто занимается рендерингом панели навигации, но здесь это не так). Таким образом, приложение должно подсчитывать задачи для текущего пользователя, вошедшего в систему, для каждого контроллера.
Я нашел соответствующую тему в поваренной книге Symfony: Как настроить до и после фильтров, и мне удалось это реализовать:
Acme\TestBundle\EventListener\UserListener.php
:
namespace Acme\TestBundle\EventListener;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
class UserListener
{
public function onKernelController(FilterControllerEvent $event)
{
$controller = $event->getController();
if ( ! is_array($controller)) {
return;
}
$securityContext = $controller[0]->get('security.context');
// now count tasks, but only if a user logged-in
if ($securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED') or $securityContext->isGranted('IS_AUTHENTICATED_FULLY'))
{
$user = $securityContext->getToken()->getUser();
// ...
// countig tasks and setting $countTasks var
// ...
$user->setCountTasks($countTasks);
}
}
}
services.yml
:
services:
acme.user.before_controller:
class: Acme\TestBundle\EventListener\UserListener
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
Он работает так, как ожидалось, и я могу получить свойство в шаблоне Twig следующим образом:
{{ app.user.countTasks }}
В prod env он работает так, как ожидалось.
Однако в dev профайлер выдает UndefinedMethodException
:
UndefinedMethodException: Попытка вызвать метод «get» для класса «Symfony\Bundle\WebProfilerBundle\Controller\ProfilerController» в ...\src\Acme\TestBundle\EventListener\UserListener.php, строка 18.
где строка 18 это:
$securityContext = $controller[0]->get('security.context');
В качестве быстрого патча я добавил дополнительную проверку (перед строкой 18), чтобы профилировщик не выполнял дальнейшую логику:
if (is_a($controller[0], '\Symfony\Bundle\WebProfilerBundle\Controller\ProfilerController'))
{
return;
}
$securityContext = $controller[0]->get('security.context');
и это сделало трюк. Но боюсь, это не правильный путь. Я также боюсь потерять часть отладочной информации в профилировщике.
Прав ли я в своих опасениях? Можете ли вы указать мне лучший способ предотвратить выполнение этого прослушивателя профилировщиком? В конфиге как-то?