Skip to content
This repository has been archived by the owner on Feb 24, 2023. It is now read-only.

Commit

Permalink
minor #681 Fetch Twig lazily in TemplateListener (nicolas-grekas)
Browse files Browse the repository at this point in the history
This PR was merged into the 5.5.x-dev branch.

Discussion
----------

Fetch Twig lazily in TemplateListener

I spotted this when playing with a controller that doesn't use Twig:

`TemplateListener` always instantiate twig. But twig is kinda heavy to create. This makes its instantiation lazy.

Commits
-------

d10fce5 Fetch Twig lazily in TemplateListener
  • Loading branch information
fabpot committed May 6, 2020
2 parents efc3921 + d10fce5 commit c76bb1c
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 6 deletions.
21 changes: 19 additions & 2 deletions src/EventListener/TemplateListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Sensio\Bundle\FrameworkExtraBundle\EventListener;

use Psr\Container\ContainerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Sensio\Bundle\FrameworkExtraBundle\Templating\TemplateGuesser;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
Expand All @@ -19,6 +20,7 @@
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\Event\KernelEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Contracts\Service\ServiceSubscriberInterface;
use Twig\Environment;

/**
Expand All @@ -28,17 +30,23 @@
*
* @author Fabien Potencier <[email protected]>
*/
class TemplateListener implements EventSubscriberInterface
class TemplateListener implements EventSubscriberInterface, ServiceSubscriberInterface
{
private $templateGuesser;
private $twig;
private $container;

public function __construct(TemplateGuesser $templateGuesser, Environment $twig = null)
{
$this->templateGuesser = $templateGuesser;
$this->twig = $twig;
}

public function setContainer(ContainerInterface $container): void
{
$this->container = $container;
}

/**
* Guesses the template name to render and its variables and adds them to
* the request object.
Expand Down Expand Up @@ -79,7 +87,11 @@ public function onKernelView(KernelEvent $event)
}

if (null === $this->twig) {
throw new \LogicException('You can not use the "@Template" annotation if the Twig Bundle is not available.');
if (!$this->container || !$this->container->has('twig')) {
throw new \LogicException('You can not use the "@Template" annotation if the Twig Bundle is not available.');
}

$this->twig = $this->container->get('twig');
}

$parameters = $event->getControllerResult();
Expand Down Expand Up @@ -118,6 +130,11 @@ public static function getSubscribedEvents()
];
}

public static function getSubscribedServices(): array
{
return ['twig' => '?'.Environment::class];
}

private function resolveDefaultParameters(Request $request, Template $template, $controller, $action)
{
$parameters = [];
Expand Down
5 changes: 4 additions & 1 deletion src/Resources/config/view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@

<service id="sensio_framework_extra.view.listener" class="Sensio\Bundle\FrameworkExtraBundle\EventListener\TemplateListener">
<tag name="kernel.event_subscriber" />
<tag name="container.service_subscriber" id="twig" />
<argument type="service" id="sensio_framework_extra.view.guesser" />
<argument type="service" id="twig" on-invalid="null" />
<call method="setContainer">
<argument type="service" id="Psr\Container\ContainerInterface" on-invalid="ignore" />
</call>
</service>
</services>
</container>
5 changes: 2 additions & 3 deletions src/Templating/TemplateGuesser.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

use Doctrine\Common\Persistence\Proxy;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\HttpKernel\KernelInterface;

/**
Expand Down Expand Up @@ -59,7 +58,7 @@ public function guessTemplateName($controller, Request $request)
if (\is_object($controller) && method_exists($controller, '__invoke')) {
$controller = [$controller, '__invoke'];
} elseif (!\is_array($controller)) {
throw new \InvalidArgumentException(sprintf('First argument of %s must be an array callable or an object defining the magic method __invoke. "%s" given.', __METHOD__, \gettype($controller)));
throw new \InvalidArgumentException(sprintf('First argument of "%s" must be an array callable or an object defining the magic method __invoke. "%s" given.', __METHOD__, \gettype($controller)));
}

$className = $this->getRealClass(\get_class($controller[0]));
Expand All @@ -72,7 +71,7 @@ public function guessTemplateName($controller, Request $request)
}
}
if (null === $matchController) {
throw new \InvalidArgumentException(sprintf('The "%s" class does not look like a controller class (its FQN must match one of the following regexps: "%s")', \get_class($controller[0]), implode('", "', $this->controllerPatterns)));
throw new \InvalidArgumentException(sprintf('The "%s" class does not look like a controller class (its FQN must match one of the following regexps: "%s").', \get_class($controller[0]), implode('", "', $this->controllerPatterns)));
}

if ('__invoke' === $controller[1]) {
Expand Down

0 comments on commit c76bb1c

Please sign in to comment.