diff --git a/composer.json b/composer.json index 8bc8a42..c4bfed2 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "translation" ], "require": { - "php": "~7.4 | ^8.0", + "php": "^8.2", "doctrine/orm": "~2.5", "symfony/framework-bundle": "*", "symfony/translation-contracts": "*", diff --git a/src/CacheFlag.php b/src/CacheFlag.php new file mode 100644 index 0000000..547cbc7 --- /dev/null +++ b/src/CacheFlag.php @@ -0,0 +1,33 @@ +cache->getItem($this->key); + if (!$item->isHit()) { + $item->set(0); + } + + return $item; + } + + public function increment(CacheItemInterface $item): void + { + $item->set($item->get() + 1); + $this->cache->save($item); + } +} diff --git a/src/DependencyInjection/ArxyTranslationsExtension.php b/src/DependencyInjection/ArxyTranslationsExtension.php index e3f25db..0e5c8b1 100644 --- a/src/DependencyInjection/ArxyTranslationsExtension.php +++ b/src/DependencyInjection/ArxyTranslationsExtension.php @@ -4,10 +4,12 @@ namespace Arxy\TranslationsBundle\DependencyInjection; +use Arxy\TranslationsBundle\CacheFlag; use Arxy\TranslationsBundle\Repository; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Loader; +use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpKernel\DependencyInjection\Extension; /** @@ -25,9 +27,10 @@ public function load(array $configs, ContainerBuilder $container): void $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); - $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); - $loader->load('services.xml'); + $loader = new Loader\PhpFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('services.php'); $container->setAlias(Repository::class, $config['repository']); + $container->getDefinition(CacheFlag::class)->setArgument('$cache', new Reference($config['cache_flag'])); } } diff --git a/src/DependencyInjection/CompilerPass/OverrideTranslatorPass.php b/src/DependencyInjection/CompilerPass/OverrideTranslatorPass.php index 8d7f6cc..ded4c37 100644 --- a/src/DependencyInjection/CompilerPass/OverrideTranslatorPass.php +++ b/src/DependencyInjection/CompilerPass/OverrideTranslatorPass.php @@ -4,13 +4,14 @@ namespace Arxy\TranslationsBundle\DependencyInjection\CompilerPass; +use Arxy\TranslationsBundle\CacheFlag; use Arxy\TranslationsBundle\Repository; use Arxy\TranslationsBundle\Translator; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; -class OverrideTranslatorPass implements CompilerPassInterface +final readonly class OverrideTranslatorPass implements CompilerPassInterface { /** * {@inheritdoc} @@ -20,6 +21,7 @@ public function process(ContainerBuilder $container): void $container->getDefinition('translator.default') ->setClass(Translator::class) ->addTag('kernel.reset', ['method' => 'reset']) - ->addMethodCall('setRepository', [new Reference(Repository::class)]); + ->addMethodCall('setRepository', [new Reference(Repository::class)]) + ->addMethodCall('setCacheFlag', [new Reference(CacheFlag::class)]); } } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 66cf7b1..aa0b5a8 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -14,7 +14,7 @@ * * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class} */ -class Configuration implements ConfigurationInterface +final readonly class Configuration implements ConfigurationInterface { /** * {@inheritDoc} @@ -37,6 +37,7 @@ public function getConfigTreeBuilder() */ $root->children() ->scalarNode('repository')->isRequired()->cannotBeEmpty()->end() + ->scalarNode('cache_flag')->isRequired()->cannotBeEmpty()->end() ->end(); // @formatter:on diff --git a/src/Dumper/DatabaseDumper.php b/src/Dumper/DatabaseDumper.php index 86f03af..f7e2d5b 100644 --- a/src/Dumper/DatabaseDumper.php +++ b/src/Dumper/DatabaseDumper.php @@ -11,13 +11,11 @@ /** * @internal */ -final class DatabaseDumper implements DumperInterface +final readonly class DatabaseDumper implements DumperInterface { - private Repository $repository; - - public function __construct(Repository $repository) - { - $this->repository = $repository; + public function __construct( + private Repository $repository + ) { } public function dump(MessageCatalogue $messages, $options = []): void diff --git a/src/Model/TranslationModel.php b/src/Model/TranslationModel.php index 5183a2d..671f353 100644 --- a/src/Model/TranslationModel.php +++ b/src/Model/TranslationModel.php @@ -7,7 +7,7 @@ /** * Lightweight DTO to avoid heavy hydrating of ORM */ -class TranslationModel implements Translation +final readonly class TranslationModel implements Translation { private string $translation; private string $token; diff --git a/src/Resources/config/services.php b/src/Resources/config/services.php new file mode 100644 index 0000000..29f7233 --- /dev/null +++ b/src/Resources/config/services.php @@ -0,0 +1,46 @@ +services() + ->defaults() + ->autoconfigure() + ->autowire(); + + $services->set(DatabaseDumper::class)->args([ + service(Repository::class), + ]) + ->tag('translation.dumper', ['alias' => 'db']); + + $services->set(CacheFlag::class); +}; diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml deleted file mode 100644 index ad702eb..0000000 --- a/src/Resources/config/services.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/src/Translator.php b/src/Translator.php index d9c064d..5b144e1 100644 --- a/src/Translator.php +++ b/src/Translator.php @@ -13,7 +13,11 @@ */ class Translator extends OriginalTranslator implements ResetInterface { - private Repository $repository; + private Repository|null $repository = null; + + private CacheFlag|null $cacheFlag = null; + + private int $version = 0; private bool $warmUp = false; /** @@ -24,6 +28,14 @@ public function setRepository(Repository $repository): void $this->repository = $repository; } + /** + * @required + */ + public function setCacheFlag(CacheFlag $cacheFlag): void + { + $this->cacheFlag = $cacheFlag; + } + protected function loadCatalogue(string $locale): void { parent::loadCatalogue($locale); @@ -38,7 +50,7 @@ protected function loadCatalogue(string $locale): void private function fetchTranslations(string $locale): void { - $translations = $this->repository->findByLocale($locale); + $translations = $this->repository?->findByLocale($locale) ?? []; $catalogue = $this->catalogues[$locale]; foreach ($translations as $translation) { $catalogue->set( @@ -67,6 +79,11 @@ private function loadFallbackTranslations(MessageCatalogueInterface $catalogue): public function reset(): void { + $version = $this->cacheFlag?->getVersion(); + if (null !== $version && $version->get() === $this->version) { + return; + } + foreach ($this->catalogues as $locale => $catalogue) { $translations = $this->repository->findByLocale($locale); foreach ($translations as $translation) { @@ -77,6 +94,7 @@ public function reset(): void ); } } + $this->version = $version->get(); } public function warmUp(string $cacheDir): array