bug #23014 [2.8]Fix optional cache warmers are always instantiated whereas they should be lazy-loaded (romainneutron)
This PR was merged into the 2.8 branch.
Discussion
----------
[2.8]Fix optional cache warmers are always instantiated whereas they should be lazy-loaded
| Q | A
| ------------- | ---
| Branch? | 2.8
| Bug fix? | yes
| New feature? | no <!-- don't forget updating src/**/CHANGELOG.md files -->
| BC breaks? | no
| Deprecations? | no <!-- don't forget updating UPGRADE-*.md files -->
| Tests pass? | yes
| Fixed tickets | N/A
| License | MIT
| Doc PR | N/A
Since version 2.8, if a Twig extension throws an exception in constructor, then the Kernel can not boot anymore because a service used by the Twig cache warmer instantiates Twig. As Twig cache warmer is optional, Twig should not be loaded at Kernel boot, and this patch fixes the issue
Commits
-------
3371db9
Fix optional cache warmers are always instantiated whereas they should be lazy-loaded
This commit is contained in:
commit
7a57644a8f
@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\CacheWarmer;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
|
||||
use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
|
||||
use Symfony\Component\Translation\TranslatorInterface;
|
||||
@ -22,11 +23,24 @@ use Symfony\Component\Translation\TranslatorInterface;
|
||||
*/
|
||||
class TranslationsCacheWarmer implements CacheWarmerInterface
|
||||
{
|
||||
private $container;
|
||||
private $translator;
|
||||
|
||||
public function __construct(TranslatorInterface $translator)
|
||||
/**
|
||||
* TranslationsCacheWarmer constructor.
|
||||
*
|
||||
* @param ContainerInterface|TranslatorInterface $container
|
||||
*/
|
||||
public function __construct($container)
|
||||
{
|
||||
$this->translator = $translator;
|
||||
// As this cache warmer is optional, dependencies should be lazy-loaded, that's why a container should be injected.
|
||||
if ($container instanceof ContainerInterface) {
|
||||
$this->container = $container;
|
||||
} elseif ($container instanceof TranslatorInterface) {
|
||||
$this->translator = $container;
|
||||
} else {
|
||||
throw new \InvalidArgumentException(sprintf('%s only accepts instance of Symfony\Component\DependencyInjection\ContainerInterface or Symfony\Component\Translation\TranslatorInterface as first argument.', __CLASS__));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -34,6 +48,10 @@ class TranslationsCacheWarmer implements CacheWarmerInterface
|
||||
*/
|
||||
public function warmUp($cacheDir)
|
||||
{
|
||||
if (null === $this->translator) {
|
||||
$this->translator = $this->container->get('translator');
|
||||
}
|
||||
|
||||
if ($this->translator instanceof WarmableInterface) {
|
||||
$this->translator->warmUp($cacheDir);
|
||||
}
|
||||
|
@ -159,7 +159,7 @@
|
||||
<service id="translation.writer" class="%translation.writer.class%"/>
|
||||
|
||||
<service id="translation.warmer" class="Symfony\Bundle\FrameworkBundle\CacheWarmer\TranslationsCacheWarmer" public="false">
|
||||
<argument type="service" id="translator" />
|
||||
<argument type="service" id="service_container" />
|
||||
<tag name="kernel.cache_warmer" />
|
||||
</service>
|
||||
</services>
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Bundle\TwigBundle\CacheWarmer;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
|
||||
use Twig\Environment;
|
||||
use Twig\Error\Error;
|
||||
@ -22,12 +23,27 @@ use Twig\Error\Error;
|
||||
*/
|
||||
class TemplateCacheWarmer implements CacheWarmerInterface
|
||||
{
|
||||
private $container;
|
||||
private $twig;
|
||||
private $iterator;
|
||||
|
||||
public function __construct(Environment $twig, \Traversable $iterator)
|
||||
/**
|
||||
* TemplateCacheWarmer constructor.
|
||||
*
|
||||
* @param ContainerInterface|Environment $container
|
||||
* @param \Traversable $iterator
|
||||
*/
|
||||
public function __construct($container, \Traversable $iterator)
|
||||
{
|
||||
$this->twig = $twig;
|
||||
// As this cache warmer is optional, dependencies should be lazy-loaded, that's why a container should be injected.
|
||||
if ($container instanceof ContainerInterface) {
|
||||
$this->container = $container;
|
||||
} elseif ($container instanceof Environment) {
|
||||
$this->twig = $container;
|
||||
} else {
|
||||
throw new \InvalidArgumentException(sprintf('%s only accepts instance of Symfony\Component\DependencyInjection\ContainerInterface or Environment as first argument.', __CLASS__));
|
||||
}
|
||||
|
||||
$this->iterator = $iterator;
|
||||
}
|
||||
|
||||
@ -36,6 +52,10 @@ class TemplateCacheWarmer implements CacheWarmerInterface
|
||||
*/
|
||||
public function warmUp($cacheDir)
|
||||
{
|
||||
if (null === $this->twig) {
|
||||
$this->twig = $this->container->get('twig');
|
||||
}
|
||||
|
||||
foreach ($this->iterator as $template) {
|
||||
try {
|
||||
$this->twig->loadTemplate($template);
|
||||
|
@ -60,7 +60,7 @@
|
||||
|
||||
<service id="twig.template_cache_warmer" class="Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheWarmer" public="false">
|
||||
<tag name="kernel.cache_warmer" />
|
||||
<argument type="service" id="twig" />
|
||||
<argument type="service" id="service_container" />
|
||||
<argument type="service" id="twig.template_iterator" />
|
||||
</service>
|
||||
|
||||
|
Reference in New Issue
Block a user