My user has countTasks
property, with corresponding setter and getter:
class User implements UserInterface, \Serializable
{
/**
* @var integer
*/
private $countTasks;
}
I want this property to be always shown in the application's navigation bar (the "14" number in red):
Obviously, this property should be set for every controller. (Actually, only for every that deals with rendering the navigation bar, but that's not the case here). So the application should count tasks for the currently logged-in user for every controller.
I found a relevant topic in the Symfony cookbook: How to Setup before and after Filters, and I managed to implement it:
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 }
It works as expected and I'm able to pull the property in a Twig template like this:
{{ app.user.countTasks }}
It works as expected in prod env.
In dev however, profiler throws UndefinedMethodException
:
UndefinedMethodException: Attempted to call method "get" on class "Symfony\Bundle\WebProfilerBundle\Controller\ProfilerController" in ...\src\Acme\TestBundle\EventListener\UserListener.php line 18.
where line 18 is this one:
$securityContext = $controller[0]->get('security.context');
As a quick patch I added additional check (before line 18) to prevent profiler from executing the further logic:
if (is_a($controller[0], '\Symfony\Bundle\WebProfilerBundle\Controller\ProfilerController'))
{
return;
}
$securityContext = $controller[0]->get('security.context');
and it has made the trick. But I'm afraid it's not the right way. I'm also afraid that I'm loosing some part of debug information in profiler.
Am I right with my concerns? Can you point me to a better way to prevent profiler from executing this listener? In config somehow?