iPeleg
iPeleg

Reputation: 158

In Symfony2.4 container is null after using setController in onKernelController

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 }

Upvotes: 3

Views: 553

Answers (2)

iPeleg
iPeleg

Reputation: 158

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"));

Upvotes: 2

Cerad
Cerad

Reputation: 48865

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.

Upvotes: 2

Related Questions