JMSDiExtraBundle
JMSDiExtraBundle copied to clipboard
Error when using @Service on a controller class
[2013-02-13 06:44:28] request.CRITICAL: ErrorException: Warning: call_user_func() expects parameter 1 to be a valid callback, no array or string given in app/cache/dev/classes.php line 244 (uncaught exception) at app/cache/dev/classes.php line 244
When commenting this code it's working. if (null !== $metadata->getOutsideClassMetadata()->id && 0 !== strpos($metadata->getOutsideClassMetadata()->id, '_jms_di_extra.unnamed.service')) { return; }
strpos($metadata->getOutsideClassMetadata()->id, '_jms_di_extra.unnamed.service') is returning false.
Do you use the controller as a non-service controller? Is the controller class inheriting from another class?
/** @Service("controller.catalog") **/ class CatalogController extends Controller { ... }
Im trying to call a method of the controller, doing : $container->get('controller.catalog')->indexAction();
I also had the same issue with my controllers. Did you find a way to prevent this for good ? Note when removing the @Service annotation from my controller I get a exception saying that the service I'm trying to call from the controller (user defined service via @Service annotation) does not exist.
EDIT : Found how to solve this : The @Route annotation now has a service attribute in wich one needs to had the service id.
I.e : /**
- @Service("test")
- @Route ("/test", service="test") **/
ControllerResolver#createInjector can return null, but ControllerResolver#instantiateController(the caller) does not handle the case when null is returned.
I just stumbled upon this issue again:
My SecurityController is a service
/**
* @DI\Service("app.controller.security")
* @Route(service="app.controller.security")
*/
class SecurityController
{
/** ...stuff... */
/**
* @Route("/login", name="login")
* @Template("security/login.html.twig")
*/
public function loginAction(): array { ... }
}
And in my template I have
{% if not is_granted('IS_AUTHENTICATED_FULLY') %}
{{ render(controller('AppBundle:Security:loginAction')) }}
{% endif %}
Which results in the following szenario (see comments):
# JMS\DiExtraBundle\HttpKernel\ControllerResolver
protected function instantiateController($class)
{
if ($this->container->has($class)) { // nope!
return $this->container->get($class);
}
// $class = 'AppBundle\Controller\SecurityController'
$injector = $this->createInjector($class);
// $injector = null, because the class is not listed in cache/dev/jsm_diextra/controller_injectors
$controller = call_user_func($injector, $this->container); // -> An exception has been thrown during the rendering of a template ("Warning: call_user_func() expects parameter 1 to be a valid callback, no array or string given").
if ($controller instanceof ContainerAwareInterface) {
$controller->setContainer($this->container);
}
return $controller;
}
Github was my rubberduck :duck: :smirk:
After writing this down, I figured it out by myself. For anyone with the same issue, here's the solution:
{% if not is_granted('IS_AUTHENTICATED_FULLY') %}
{{ render(controller('app.controller.security:loginAction')) }}
{% endif %}
Where would be a nice place to document that?
Edit: Makes perfect sense now... http://symfony.com/doc/current/controller/service.html#referring-to-the-service