3

I'm trying to redirect from the onKernelController event listener to another controller in my bundle. The redirection succeed but in the $newController the container is NULL so I can't really do any thing with it like rendering pages. Why is the container NULL when it's been created like this? and how can I inject the container service to the $newController in this case?

Thanks! :)

The final working version of the event listener:

namespace MyApp\MainBundle\EventListener;

use MyApp\MainBundle\Interfaces\UserCheckInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class ControllerListener
{
    private $resolver;

    /**
     * @param ControllerResolver $resolver The injected controller_resolver service
     */
    public function __construct($resolver)
    {
        $this->resolver = $resolver;
    }

    public function onKernelController(FilterControllerEvent $event)
    {
        $controller = $event->getController();

        if (!is_array($controller))
        {
            // not an object but a different kind of callable. Do nothing
            return;
        }

        /* @var $controllerObject Controller  */
        $controllerObject = $controller[0];

        if ( $controllerObject instanceof UserCheckInterface )
        {
            $newRequest = $event->getRequest()->duplicate(null, null, array('_controller' => 'MyApp\MainBundle\Controller\ErrorController::notLoggedInAction'));

            /* @var $newController Controller  */
            $newController = $this->resolver->getController($newRequest);
            $event->setController($newController);
        }
    }
}

Here is the config.yml

kernel.listener.ControllerListener:
        class: MyApp\MainBundle\EventListener\ControllerListener
        arguments: [ "@controller_resolver" ]
        tags:
            - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }

2 Answers 2

2

The component resolver (Symfony\Component\HttpKernel\Controller\ControllerResolver) does not know anything about the container.

Instead, the Symfony FrameworkBundle provides Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver which is container aware. It's worth taking a look at the code to see where setContainer is being called.

Inject the controller_resolver service into your listener then use it instead of creating a new resolver.

Sign up to request clarification or add additional context in comments.

1 Comment

OK I changed the code so the controller_resolver will be injected to the event listener. I guess that's the proper way to this also edited my example.
2

OK... I found the answer...

When creating the $newController like I did the container by default is NULL and need to be set with the container of the original controller like this

$newController[0]->setContainer($controllerObject->get("service_container"));

2 Comments

Nope. You still have something wrong. The framework resolver will set the container for you. I suspect you still have a new ControllerReolver statement in your code.
Hey!!! :) Thank you so much!! you are right... the framework does set the container now without me needing to set it I fixed the code and uploaded the entire event listener.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.