Sylius version affected: 1.12.14
Description
We use several themes on our project.
By using the symfony/messenger component with Redis to process messages asynchronously, we noticed that certain emails do not have the right template.
We have a generic email in named templates/bundles/SyliusShop/Bundle/Email/orderAdminConfirmationEmail.html.twig.
This file extends @SyliusShop/Email/layout.html.twig (This file is present in both themes.)
The Sylius\Bundle\ThemeBundle\Twig\Loader\ThemedTemplateLoader service searches for the @SyliusShop/Email/layout.html.twig template based on the ThemeContextInterface. He finds this template in theme A.
But the cache key created for this template is based on the template name.
It should be the template name + the theme name, in order to differentiate the cache between the two themes.
Without this, it will always load the template of the first loaded theme.
Steps to reproduce
I don't know if the description is enough here, I will complete it if necessary
Possible Solution
Currently we have decorated
Sylius\Bundle\ThemeBundle\Twig\Loader\ThemedTemplateLoader in order to modify the behavior of the getCacheKey() method in order to add the name of the theme in the cache key and resolve the problem.
Here the final code of the decorated class :
<?php
declare(strict_types=1);
namespace App\Twig\Loader;
use Sylius\Bundle\ThemeBundle\Context\ThemeContextInterface;
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
use Symfony\Component\DependencyInjection\Attribute\AutowireDecorated;
use Twig\Loader\LoaderInterface;
use Twig\Loader\LoaderInterface as TwigLoaderInterface;
use Twig\Source;
#[AsDecorator(decorates: 'twig.loader', priority: 128)]
final readonly class ThemeTwigLoader implements LoaderInterface
{
public function __construct(
#[AutowireDecorated]
private TwigLoaderInterface $decorated,
private ThemeContextInterface $themeContext,
)
{
}
public function getSourceContext($name): Source
{
return $this->decorated->getSourceContext($name);
}
public function getCacheKey($name): string
{
$theme = $this->themeContext->getTheme();
$cacheKey = $this->decorated->getCacheKey($name);
if (null !== $theme) {
$cacheKey .= '___' . $theme->getName();
}
return $cacheKey;
}
public function isFresh($name, $time): bool
{
return $this->decorated->isFresh($name, $time);
}
public function exists($name): bool
{
return $this->decorated->exists($name);
}
}
Sylius version affected: 1.12.14
Description
We use several themes on our project.
By using the symfony/messenger component with Redis to process messages asynchronously, we noticed that certain emails do not have the right template.
We have a generic email in named
templates/bundles/SyliusShop/Bundle/Email/orderAdminConfirmationEmail.html.twig.This file extends
@SyliusShop/Email/layout.html.twig(This file is present in both themes.)The
Sylius\Bundle\ThemeBundle\Twig\Loader\ThemedTemplateLoaderservice searches for the@SyliusShop/Email/layout.html.twigtemplate based on theThemeContextInterface. He finds this template in theme A.But the cache key created for this template is based on the template name.
It should be the template name + the theme name, in order to differentiate the cache between the two themes.
Without this, it will always load the template of the first loaded theme.
Steps to reproduce
I don't know if the description is enough here, I will complete it if necessary
Possible Solution
Currently we have decorated
Sylius\Bundle\ThemeBundle\Twig\Loader\ThemedTemplateLoaderin order to modify the behavior of thegetCacheKey()method in order to add the name of the theme in the cache key and resolve the problem.Here the final code of the decorated class :