0
votes

I have this listener:

use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpFoundation\Request;

class ControllerListener
{
    public function onKernelController( FilterControllerEvent $event, Request $request )
    {
        if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
            $controllers = $event->getController();
            if (is_array( $controllers )) {
                $controller = $controllers[0];
                if (is_object( $controller )) {
                    if (method_exists( $controller, 'parControl' )) {
                        $controller->parControl(
                            $controller->getRequest(),
                            $controller->getRequest()->get( 'action' ),
                            $controller->getRequest()->get( 'context' ),
                            $controller->getRequest()->get( 'page' ),
                            $controller->getRequest()->get( 'case' ),
                            $controller->getRequest()->get( 'subset' )
                        );
                    }

                    if (method_exists( $controller, 'adminProjectControl' )) {
                        // to this method I need to pass Request $request  
                        $controller->adminProjectControl($request);
                    }

                    if (method_exists( $controller, 'accessControl' )) {
                        $controller->accessControl();
                    }
                }
            }
        }
    }

    public function onKernelResponse( FilterResponseEvent $event )
    {
        Utilities::flashDebugLoginMessage();
    }
}

And it's defined as a service at services.yml:

pdone.listener.preexecute:
    class: GroupDCA\PDOneBundle\Listener\ControllerListener
    arguments: [@request]
    public: true
    scope: request
    tags:
        - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
        - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }

But I should doing something wrong since I got this three errors:

ContextErrorException in ControllerListener.php line 12: Catchable Fatal Error: Argument 2 passed to GroupDCA\PDOneBundle\Listener\ControllerListener::onKernelController() must be an instance of Symfony\Component\HttpFoundation\Request, string given

ContextErrorException in ControllerListener.php line 12: Catchable Fatal Error: Argument 2 passed to GroupDCA\PDOneBundle\Listener\ControllerListener::onKernelController() must be an instance of Symfony\Component\HttpFoundation\Request, string given

LogicException in bootstrap.php.cache line 3118: No listeners of the "kernel.exception" event set a Response

So, how do I inject the Request to the listener? Can I do that? I have read also this post here but not get how to do this.

2
Each listener is passed 3 arguments - the event object being dispatched (FilterControllerEvent), the name of the event (kernel.controller) and the event dispatcher(@event_dispatcher) - this is why you are getting the error that the second argument is a string, as it's the event name. This can be useful if you want to chain event without needing to inject the @event_dispatcher into each listener/subscriber.qooplmao

2 Answers

12
votes

FilterControllerEvent already gives you access to the request:

public function onKernelController(FilterControllerEvent $event)
{
    $request = $event->getRequest();       

    // ...
}

If you need the request in listeners where event does not provide a request, always use the request stack:

use Symfony\Component\HttpFoundation\RequestStack;

class MyService
{
    private $requestStack;

    public function __construct(RequestStack $requestStack)
    {
        $this->requestStack = $requestStack;
    }

    public function doSomething()
    {
        $request = $this->requestStack->getCurrentRequest();

        // ...
    }
}

Injecting a request is deprecated and will be removed. Request stack is the way to go. Don't use the request scope either.

0
votes

You're passing request object to the ControllerListener constructor from your service definition, not to the onKernelController method.

Instead do:

protected $request;

public function __construct (Request $request) {

    $this->request = $request;
}

Which should fix your problem and make the request object available.