Question

I have a custom TemplatingProvider Service which I use in my controllers to output the view.

namespace Acme\FrontEndBundle\Templating;

class TemplatingProvider
{
    private $templating;
    private $request;

    function __construct($templating, $request)
    {
        $this->templating = $templating;
        $this->request = $request;
    }

    function getTemplate($name)
    {
        $controller = $this->request->attributes->get('_controller');
        preg_match('/Controller\\\([a-zA-Z]*)Controller/', $controller, $matches);
        $controller = 'AcmeFrontEndBundle:' . $matches[1] . ':';
        $template = $controller . $name;
        // ...

On a normal request this works fine, but not on subrequest like when I render a controller in a template with twigs render(controller(...)) function. It seems that $this->request->attributes->get('_controller') is NULL. I understand that for _route since the controller isn't accessed through one but why is _controller not set and how can I get around that?

I know that the use of render(path(...)) in twig would solve this, but this is no option for me, I really need render(controller(...)).

Thanks in advance for any advices.

UPDATE:

Thanks to Vadim Ashikhmans answer I found the solution:

Inject `@service_container into the service and then use the container to get the request and there you have it. But with a little obstacle which i solved in a helper function:

function getController()
{
    $controller = $this->container->get('request')->get('_controller');

    // on mainrequest (calling the controller through its route)
    // $controller follows the namespacelike schema: Vendor\Bundle\Controller\ControllerController:actionAction
    preg_match('/Controller\\\([a-zA-Z]*)Controller/', $controller, $matches);
    if (isset($matches[1]))
    {
        $controller = 'AcmeFrontEndBundle:' . $matches[1] . ':';
    }
    else
    {
        // on subrequests (e.g. render(controller(...)) in a template)
        // $controller looks like Bundle:Controller:action
        preg_match('/:([a-zA-Z]*):/', $controller, $matches);
        $controller = 'AcmeFrontEndBundle:' . $matches[1] . ':';
    }

    return $controller;
}

Thanks you very much! :)

Was it helpful?

Solution

I suppose _controller attribute is empty because for every sub requests current request object is duplicated, so in subrequest TemplateProvider tries to operate on old data.

You could try to pass the container to TemplateProvider constructor and retrieve request object in getTemplate method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top