Improve Translator caching

This commit is contained in:
Remon van de Kamp 2018-10-20 17:47:06 +02:00 committed by Fabien Potencier
parent 760bbd595b
commit a5246589cf
5 changed files with 89 additions and 8 deletions

View File

@ -1075,6 +1075,7 @@ class FrameworkExtension extends Extension
// Discover translation directories
$dirs = [];
$transPaths = [];
$nonExistingDirs = [];
if (class_exists('Symfony\Component\Validator\Validation')) {
$r = new \ReflectionClass('Symfony\Component\Validator\Validation');
@ -1093,18 +1094,21 @@ class FrameworkExtension extends Extension
$defaultDir = $container->getParameterBag()->resolveValue($config['default_path']);
$rootDir = $container->getParameter('kernel.root_dir');
foreach ($container->getParameter('kernel.bundles_metadata') as $name => $bundle) {
if ($container->fileExists($dir = $bundle['path'].'/Resources/translations')) {
if (\is_dir($dir = $bundle['path'].'/Resources/translations')) {
$dirs[] = $dir;
} else {
$nonExistingDirs[] = $dir;
}
if ($container->fileExists($dir = $rootDir.sprintf('/Resources/%s/translations', $name))) {
if (\is_dir($dir = $rootDir.sprintf('/Resources/%s/translations', $name))) {
@trigger_error(sprintf('Translations directory "%s" is deprecated since Symfony 4.2, use "%s" instead.', $dir, $defaultDir), E_USER_DEPRECATED);
$dirs[] = $dir;
} else {
$nonExistingDirs[] = $dir;
}
}
foreach ($config['paths'] as $dir) {
if ($container->fileExists($dir)) {
if (\is_dir($dir)) {
$dirs[] = $transPaths[] = $dir;
} else {
throw new \UnexpectedValueException(sprintf('%s defined in translator.paths does not exist or is not a directory', $dir));
@ -1119,15 +1123,20 @@ class FrameworkExtension extends Extension
$container->getDefinition('console.command.translation_update')->replaceArgument(6, $transPaths);
}
if ($container->fileExists($defaultDir)) {
if (\is_dir($defaultDir)) {
$dirs[] = $defaultDir;
} else {
$nonExistingDirs[] = $defaultDir;
}
if ($container->fileExists($dir = $rootDir.'/Resources/translations')) {
if (\is_dir($dir = $rootDir.'/Resources/translations')) {
if ($dir !== $defaultDir) {
@trigger_error(sprintf('Translations directory "%s" is deprecated since Symfony 4.2, use "%s" instead.', $dir, $defaultDir), E_USER_DEPRECATED);
}
$dirs[] = $dir;
} else {
$nonExistingDirs[] = $dir;
}
// Register translation resources
@ -1154,7 +1163,10 @@ class FrameworkExtension extends Extension
$options = array_merge(
$translator->getArgument(4),
['resource_files' => $files]
[
'resource_files' => $files,
'scanned_directories' => \array_merge($dirs, $nonExistingDirs),
]
);
$translator->replaceArgument(4, $options);

View File

@ -25,6 +25,8 @@ use Symfony\Component\Cache\Adapter\DoctrineAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\ProxyAdapter;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Config\Resource\DirectoryResource;
use Symfony\Component\Config\Resource\FileExistenceResource;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\ResolveInstanceofConditionalsPass;
@ -800,6 +802,26 @@ abstract class FrameworkExtensionTest extends TestCase
$calls = $container->getDefinition('translator.default')->getMethodCalls();
$this->assertEquals(['fr'], $calls[1][1][0]);
$nonExistingDirectories = array_filter(
$options['scanned_directories'],
function ($directory) {
return !file_exists($directory);
}
);
$this->assertNotEmpty($nonExistingDirectories, 'FrameworkBundle should pass non existing directories to Translator');
$resources = $container->getResources();
foreach ($resources as $resource) {
if ($resource instanceof DirectoryResource) {
$this->assertNotContains('translations', $resource->getResource());
}
if ($resource instanceof FileExistenceResource) {
$this->assertNotContains('translations', $resource->getResource());
}
}
}
/**

View File

@ -14,6 +14,8 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Translation;
use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;
use Symfony\Bundle\FrameworkBundle\Translation\Translator;
use Symfony\Component\Config\Resource\DirectoryResource;
use Symfony\Component\Config\Resource\FileExistenceResource;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Translation\Formatter\MessageFormatter;
use Symfony\Component\Translation\MessageCatalogue;
@ -223,6 +225,29 @@ class TranslatorTest extends TestCase
];
}
public function testCatalogResourcesAreAddedForScannedDirectories()
{
$loader = new \Symfony\Component\Translation\Loader\YamlFileLoader();
$resourceFiles = [
'fr' => [
__DIR__.'/../Fixtures/Resources/translations/messages.fr.yml',
],
];
/** @var Translator $translator */
$translator = $this->getTranslator($loader, [
'resource_files' => $resourceFiles,
'scanned_directories' => [__DIR__, '/tmp/I/sure/hope/this/does/not/exist'],
], 'yml');
$catalogue = $translator->getCatalogue('fr');
$resources = $catalogue->getResources();
$this->assertEquals(new DirectoryResource(__DIR__), $resources[1]);
$this->assertEquals(new FileExistenceResource('/tmp/I/sure/hope/this/does/not/exist'), $resources[2]);
}
protected function getCatalogue($locale, $messages, $resources = [])
{
$catalogue = new MessageCatalogue($locale);

View File

@ -12,6 +12,8 @@
namespace Symfony\Bundle\FrameworkBundle\Translation;
use Psr\Container\ContainerInterface;
use Symfony\Component\Config\Resource\DirectoryResource;
use Symfony\Component\Config\Resource\FileExistenceResource;
use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
use Symfony\Component\Translation\Exception\InvalidArgumentException;
use Symfony\Component\Translation\Formatter\MessageFormatterInterface;
@ -31,6 +33,7 @@ class Translator extends BaseTranslator implements WarmableInterface
'cache_dir' => null,
'debug' => false,
'resource_files' => [],
'scanned_directories' => [],
];
/**
@ -48,6 +51,11 @@ class Translator extends BaseTranslator implements WarmableInterface
private $resourceFiles;
/**
* @var string[]
*/
private $scannedDirectories;
/**
* Constructor.
*
@ -78,6 +86,7 @@ class Translator extends BaseTranslator implements WarmableInterface
$this->options = array_merge($this->options, $options);
$this->resourceLocales = array_keys($this->options['resource_files']);
$this->resourceFiles = $this->options['resource_files'];
$this->scannedDirectories = $this->options['scanned_directories'];
parent::__construct($defaultLocale, $formatter, $this->options['cache_dir'], $this->options['debug']);
}
@ -120,6 +129,16 @@ class Translator extends BaseTranslator implements WarmableInterface
parent::initializeCatalogue($locale);
}
protected function doLoadCatalogue($locale): void
{
parent::doLoadCatalogue($locale);
foreach ($this->scannedDirectories as $directory) {
$resourceClass = file_exists($directory) ? DirectoryResource::class : FileExistenceResource::class;
$this->catalogues[$locale]->addResource(new $resourceClass($directory));
}
}
protected function initialize()
{
if ($this->resourceFiles) {

View File

@ -395,7 +395,10 @@ EOF
return $this->cacheDir.'/catalogue.'.$locale.'.'.strtr(substr(base64_encode(hash('sha256', serialize($this->fallbackLocales), true)), 0, 7), '/', '_').'.php';
}
private function doLoadCatalogue($locale): void
/**
* @internal
*/
protected function doLoadCatalogue($locale): void
{
$this->catalogues[$locale] = new MessageCatalogue($locale);