I've been reading through the internals chapter in the Symfony2 docs and it says if I add a listener to the kernel.controller event I can swap the controller that gets run, I've got something that works a bit like this:
public function onKernelController(FilterControllerEvent $event)
{
$controller = $event->getController();
$replacementControllerName = .... //Some logic to work out the name of the new controller
$replacementController = ?? //Not sure what goes here
$event->setController($replacementController);
}
The bit I'm unsure if is once I've worked out the name of the replacement controller, how do I get an instance of it that I can pass to setController?
You can set your controller to any callable, which means something like
array('class', 'method')
array($instance, 'method')
function() { ... }
'function'
;__invoke()
method new MyClassImplementingInvoke()
'class::method'
which forces the ControllerResolver
to create a new instance of class
(calling the constructor without any argument) and returning a callable array($instanceOfClass, 'method')
EDIT:
I looked up the wrong ControllerResolver
. When running Symfony in a standard setup it'll use the Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver
(and not the Symfony\Component\HttpKernel\Controller\ControllerResolver
). So the controller name will be handled a little bit different to what I wrote above.
The following example sums up all the possible options you have when setting your controller.
public function onKernelController(FilterControllerEvent $event)
{
$controller = $event->getController();
// call method in Controller class in YourBundle
$replacementController = 'YourBundle:Controller:method';
// call method in service (which is a service registered in the DIC)
$replacementController = 'service:method';
// call method on an instance of Class (created by calling the constructor without any argument)
$replacementController = 'Class::method';
// call method on Class statically (static method)
$replacementController = array('Class', 'method');
// call method on $controller
$controller = new YourController(1, 2, 3);
$replacementController = array($controller, 'method');
// call __invoke on $controller
$replacementController = new YourController(1, 2, 3);
$event->setController($replacementController);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With