From 9bde6ce6cc5fd16de0e63120df150d7b3164ad75 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Fri, 13 Oct 2023 10:59:13 +0200 Subject: [PATCH] [FrameworkBundle][Routing][Translation][Workflow] Move some compiler passes from FrameworkBundle to components --- .../Bundle/FrameworkBundle/CHANGELOG.md | 4 + .../AddExpressionLanguageProvidersPass.php | 4 + .../Compiler/DataCollectorTranslatorPass.php | 4 + .../Compiler/LoggingTranslatorPass.php | 4 + .../Compiler/WorkflowGuardListenerPass.php | 4 + .../FrameworkBundle/FrameworkBundle.php | 10 +- ...AddExpressionLanguageProvidersPassTest.php | 3 + .../DataCollectorTranslatorPassTest.php | 3 + .../Compiler/LoggingTranslatorPassTest.php | 3 + .../WorkflowGuardListenerPassTest.php | 3 + .../Bundle/FrameworkBundle/composer.json | 8 +- src/Symfony/Component/Routing/CHANGELOG.md | 1 + .../AddExpressionLanguageProvidersPass.php | 36 ++++++ ...AddExpressionLanguageProvidersPassTest.php | 60 +++++++++ .../Component/Translation/CHANGELOG.md | 1 + .../DataCollectorTranslatorPass.php | 36 ++++++ .../LoggingTranslatorPass.php | 59 +++++++++ .../DataCollectorTranslatorPassTest.php | 121 ++++++++++++++++++ .../LoggingTranslatorPassTest.php | 82 ++++++++++++ src/Symfony/Component/Workflow/CHANGELOG.md | 1 + .../WorkflowGuardListenerPass.php | 45 +++++++ .../WorkflowGuardListenerPassTest.php | 107 ++++++++++++++++ 22 files changed, 590 insertions(+), 9 deletions(-) create mode 100644 src/Symfony/Component/Routing/DependencyInjection/AddExpressionLanguageProvidersPass.php create mode 100644 src/Symfony/Component/Routing/Tests/DependencyInjection/AddExpressionLanguageProvidersPassTest.php create mode 100644 src/Symfony/Component/Translation/DependencyInjection/DataCollectorTranslatorPass.php create mode 100644 src/Symfony/Component/Translation/DependencyInjection/LoggingTranslatorPass.php create mode 100644 src/Symfony/Component/Translation/Tests/DependencyInjection/DataCollectorTranslatorPassTest.php create mode 100644 src/Symfony/Component/Translation/Tests/DependencyInjection/LoggingTranslatorPassTest.php create mode 100644 src/Symfony/Component/Workflow/DependencyInjection/WorkflowGuardListenerPass.php create mode 100644 src/Symfony/Component/Workflow/Tests/DependencyInjection/WorkflowGuardListenerPassTest.php diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index 57bd310a5a042..949aad31c3472 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -38,6 +38,10 @@ CHANGELOG * Deprecate the `routing.loader.annotation.directory` service, use the `routing.loader.attribute.directory` service instead * Deprecate the `routing.loader.annotation.file` service, use the `routing.loader.attribute.file` service instead * Deprecate `AnnotatedRouteControllerLoader`, use `AttributeRouteControllerLoader` instead + * Deprecate `AddExpressionLanguageProvidersPass`, use `Symfony\Component\Routing\DependencyInjection\AddExpressionLanguageProvidersPass` instead + * Deprecate `DataCollectorTranslatorPass`, use `Symfony\Component\Translation\DependencyInjection\DataCollectorTranslatorPass` instead + * Deprecate `LoggingTranslatorPass`, use `Symfony\Component\Translation\DependencyInjection\LoggingTranslatorPass` instead + * Deprecate `WorkflowGuardListenerPass`, use `Symfony\Component\Workflow\DependencyInjection\WorkflowGuardListenerPass` instead 6.3 --- diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddExpressionLanguageProvidersPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddExpressionLanguageProvidersPass.php index 5442b277348e3..dabf1d6ffdae7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddExpressionLanguageProvidersPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddExpressionLanguageProvidersPass.php @@ -15,10 +15,14 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; +trigger_deprecation('symfony/framework-bundle', '6.4', 'The "%s" class is deprecated, use "%s" instead.', AddExpressionLanguageProvidersPass::class, \Symfony\Component\Routing\DependencyInjection\AddExpressionLanguageProvidersPass::class); + /** * Registers the expression language providers. * * @author Fabien Potencier + * + * @deprecated since Symfony 6.4, use Symfony\Component\Routing\DependencyInjection\AddExpressionLanguageProvidersPass instead. */ class AddExpressionLanguageProvidersPass implements CompilerPassInterface { diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/DataCollectorTranslatorPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/DataCollectorTranslatorPass.php index e66e98b451d6c..7c6ca5d5a928a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/DataCollectorTranslatorPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/DataCollectorTranslatorPass.php @@ -15,8 +15,12 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\Translation\TranslatorBagInterface; +trigger_deprecation('symfony/framework-bundle', '6.4', 'The "%s" class is deprecated, use "%s" instead.', DataCollectorTranslatorPass::class, \Symfony\Component\Translation\DependencyInjection\DataCollectorTranslatorPass::class); + /** * @author Christian Flothmann + * + * @deprecated since Symfony 6.4, use Symfony\Component\Translation\DependencyInjection\DataCollectorTranslatorPass instead. */ class DataCollectorTranslatorPass implements CompilerPassInterface { diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/LoggingTranslatorPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/LoggingTranslatorPass.php index b7cb920bf7434..5b31f2884e5de 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/LoggingTranslatorPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/LoggingTranslatorPass.php @@ -17,8 +17,12 @@ use Symfony\Component\Translation\TranslatorBagInterface; use Symfony\Contracts\Translation\TranslatorInterface; +trigger_deprecation('symfony/framework-bundle', '6.4', 'The "%s" class is deprecated, use "%s" instead.', LoggingTranslatorPass::class, \Symfony\Component\Translation\DependencyInjection\LoggingTranslatorPass::class); + /** * @author Abdellatif Ait boudad + * + * @deprecated since Symfony 6.4, use Symfony\Component\Translation\DependencyInjection\LoggingTranslatorPass instead. */ class LoggingTranslatorPass implements CompilerPassInterface { diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php index bda9ca9515258..c072083112f99 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php @@ -15,9 +15,13 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Exception\LogicException; +trigger_deprecation('symfony/framework-bundle', '6.4', 'The "%s" class is deprecated, use "%s" instead.', WorkflowGuardListenerPass::class, \Symfony\Component\Workflow\DependencyInjection\WorkflowGuardListenerPass::class); + /** * @author Christian Flothmann * @author Grégoire Pineau + * + * @deprecated since Symfony 6.4, use Symfony\Component\Workflow\DependencyInjection\WorkflowGuardListenerPass instead. */ class WorkflowGuardListenerPass implements CompilerPassInterface { diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php index 58c7ba068810c..688014feae103 100644 --- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php @@ -13,18 +13,14 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddAnnotationsCachedReaderPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddDebugLogProcessorPass; -use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddExpressionLanguageProvidersPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AssetsContextPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ContainerBuilderDebugDumpPass; -use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\DataCollectorTranslatorPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ErrorLoggerCompilerPass; -use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\LoggingTranslatorPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RemoveUnusedSessionMarshallingHandlerPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TestServiceContainerRealRefPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TestServiceContainerWeakRefPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\UnusedTagsPass; -use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\WorkflowGuardListenerPass; use Symfony\Component\Cache\Adapter\ApcuAdapter; use Symfony\Component\Cache\Adapter\ArrayAdapter; use Symfony\Component\Cache\Adapter\ChainAdapter; @@ -59,9 +55,12 @@ use Symfony\Component\Messenger\DependencyInjection\MessengerPass; use Symfony\Component\Mime\DependencyInjection\AddMimeTypeGuesserPass; use Symfony\Component\PropertyInfo\DependencyInjection\PropertyInfoPass; +use Symfony\Component\Routing\DependencyInjection\AddExpressionLanguageProvidersPass; use Symfony\Component\Routing\DependencyInjection\RoutingResolverPass; use Symfony\Component\Scheduler\DependencyInjection\AddScheduleMessengerPass; use Symfony\Component\Serializer\DependencyInjection\SerializerPass; +use Symfony\Component\Translation\DependencyInjection\DataCollectorTranslatorPass; +use Symfony\Component\Translation\DependencyInjection\LoggingTranslatorPass; use Symfony\Component\Translation\DependencyInjection\TranslationDumperPass; use Symfony\Component\Translation\DependencyInjection\TranslationExtractorPass; use Symfony\Component\Translation\DependencyInjection\TranslatorPass; @@ -71,6 +70,7 @@ use Symfony\Component\Validator\DependencyInjection\AddValidatorInitializersPass; use Symfony\Component\VarExporter\Internal\Hydrator; use Symfony\Component\VarExporter\Internal\Registry; +use Symfony\Component\Workflow\DependencyInjection\WorkflowGuardListenerPass; // Help opcache.preload discover always-needed symbols class_exists(ApcuAdapter::class); @@ -157,7 +157,7 @@ public function build(ContainerBuilder $container) $this->addCompilerPassIfExists($container, TranslatorPass::class, PassConfig::TYPE_BEFORE_OPTIMIZATION, -32); $this->addCompilerPassIfExists($container, TranslatorPathsPass::class, PassConfig::TYPE_AFTER_REMOVING); $container->addCompilerPass(new LoggingTranslatorPass()); - $container->addCompilerPass(new AddExpressionLanguageProvidersPass(false)); + $container->addCompilerPass(new AddExpressionLanguageProvidersPass()); $this->addCompilerPassIfExists($container, TranslationExtractorPass::class); $this->addCompilerPassIfExists($container, TranslationDumperPass::class); $container->addCompilerPass(new FragmentRendererPass()); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddExpressionLanguageProvidersPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddExpressionLanguageProvidersPassTest.php index aaba736255f1d..d159057c60f79 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddExpressionLanguageProvidersPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddExpressionLanguageProvidersPassTest.php @@ -17,6 +17,9 @@ use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; +/** + * @group legacy + */ class AddExpressionLanguageProvidersPassTest extends TestCase { public function testProcessForRouter() diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/DataCollectorTranslatorPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/DataCollectorTranslatorPassTest.php index 87b4dce148ffe..805f2ca849527 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/DataCollectorTranslatorPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/DataCollectorTranslatorPassTest.php @@ -20,6 +20,9 @@ use Symfony\Component\Translation\Translator; use Symfony\Contracts\Translation\TranslatorInterface; +/** + * @group legacy + */ class DataCollectorTranslatorPassTest extends TestCase { private ContainerBuilder $container; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LoggingTranslatorPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LoggingTranslatorPassTest.php index 9204212169a46..e15c622076f20 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LoggingTranslatorPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LoggingTranslatorPassTest.php @@ -17,6 +17,9 @@ use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\Translation\Translator; +/** + * @group legacy + */ class LoggingTranslatorPassTest extends TestCase { public function testProcess() diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/WorkflowGuardListenerPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/WorkflowGuardListenerPassTest.php index 908f92bc4cedd..4c3327847c3af 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/WorkflowGuardListenerPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/WorkflowGuardListenerPassTest.php @@ -21,6 +21,9 @@ use Symfony\Component\Security\Core\Role\RoleHierarchy; use Symfony\Component\Validator\Validator\ValidatorInterface; +/** + * @group legacy + */ class WorkflowGuardListenerPassTest extends TestCase { private ContainerBuilder $container; diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index a85663e3d79b1..fc2e73ac9163b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -62,10 +62,10 @@ "symfony/serializer": "^6.4|^7.0", "symfony/stopwatch": "^5.4|^6.0|^7.0", "symfony/string": "^5.4|^6.0|^7.0", - "symfony/translation": "^6.2.8|^7.0", + "symfony/translation": "^6.4|^7.0", "symfony/twig-bundle": "^5.4|^6.0|^7.0", "symfony/validator": "^6.4|^7.0", - "symfony/workflow": "^5.4|^6.0|^7.0", + "symfony/workflow": "^6.4|^7.0", "symfony/yaml": "^5.4|^6.0|^7.0", "symfony/property-info": "^5.4|^6.0|^7.0", "symfony/uid": "^5.4|^6.0|^7.0", @@ -96,12 +96,12 @@ "symfony/security-csrf": "<5.4", "symfony/security-core": "<5.4", "symfony/stopwatch": "<5.4", - "symfony/translation": "<6.2.8", + "symfony/translation": "<6.4", "symfony/twig-bridge": "<5.4", "symfony/twig-bundle": "<5.4", "symfony/validator": "<6.4", "symfony/web-profiler-bundle": "<5.4", - "symfony/workflow": "<5.4" + "symfony/workflow": "<6.4" }, "autoload": { "psr-4": { "Symfony\\Bundle\\FrameworkBundle\\": "" }, diff --git a/src/Symfony/Component/Routing/CHANGELOG.md b/src/Symfony/Component/Routing/CHANGELOG.md index 516f84e855ca1..ef1a218e53c05 100644 --- a/src/Symfony/Component/Routing/CHANGELOG.md +++ b/src/Symfony/Component/Routing/CHANGELOG.md @@ -11,6 +11,7 @@ CHANGELOG * Deprecate `AnnotationClassLoader`, use `AttributeClassLoader` instead * Deprecate `AnnotationDirectoryLoader`, use `AttributeDirectoryLoader` instead * Deprecate `AnnotationFileLoader`, use `AttributeFileLoader` instead + * Add `AddExpressionLanguageProvidersPass` (moved from `FrameworkBundle`) 6.2 --- diff --git a/src/Symfony/Component/Routing/DependencyInjection/AddExpressionLanguageProvidersPass.php b/src/Symfony/Component/Routing/DependencyInjection/AddExpressionLanguageProvidersPass.php new file mode 100644 index 0000000000000..619fa67f432be --- /dev/null +++ b/src/Symfony/Component/Routing/DependencyInjection/AddExpressionLanguageProvidersPass.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\DependencyInjection; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Registers the expression language providers. + * + * @author Fabien Potencier + */ +class AddExpressionLanguageProvidersPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container): void + { + if (!$container->has('router.default')) { + return; + } + + $definition = $container->findDefinition('router.default'); + foreach ($container->findTaggedServiceIds('routing.expression_language_provider', true) as $id => $attributes) { + $definition->addMethodCall('addExpressionLanguageProvider', [new Reference($id)]); + } + } +} diff --git a/src/Symfony/Component/Routing/Tests/DependencyInjection/AddExpressionLanguageProvidersPassTest.php b/src/Symfony/Component/Routing/Tests/DependencyInjection/AddExpressionLanguageProvidersPassTest.php new file mode 100644 index 0000000000000..4f5c4c48c3874 --- /dev/null +++ b/src/Symfony/Component/Routing/Tests/DependencyInjection/AddExpressionLanguageProvidersPassTest.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Tests\DependencyInjection; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\Routing\DependencyInjection\AddExpressionLanguageProvidersPass; + +class AddExpressionLanguageProvidersPassTest extends TestCase +{ + public function testProcessForRouter() + { + $container = new ContainerBuilder(); + $container->addCompilerPass(new AddExpressionLanguageProvidersPass()); + + $definition = new Definition(\stdClass::class); + $definition->addTag('routing.expression_language_provider'); + $container->setDefinition('some_routing_provider', $definition->setPublic(true)); + + $container->register('router.default', \stdClass::class)->setPublic(true); + $container->compile(); + + $router = $container->getDefinition('router.default'); + $calls = $router->getMethodCalls(); + $this->assertCount(1, $calls); + $this->assertEquals('addExpressionLanguageProvider', $calls[0][0]); + $this->assertEquals(new Reference('some_routing_provider'), $calls[0][1][0]); + } + + public function testProcessForRouterAlias() + { + $container = new ContainerBuilder(); + $container->addCompilerPass(new AddExpressionLanguageProvidersPass()); + + $definition = new Definition(\stdClass::class); + $definition->addTag('routing.expression_language_provider'); + $container->setDefinition('some_routing_provider', $definition->setPublic(true)); + + $container->register('my_router', \stdClass::class)->setPublic(true); + $container->setAlias('router.default', 'my_router'); + $container->compile(); + + $router = $container->getDefinition('my_router'); + $calls = $router->getMethodCalls(); + $this->assertCount(1, $calls); + $this->assertEquals('addExpressionLanguageProvider', $calls[0][0]); + $this->assertEquals(new Reference('some_routing_provider'), $calls[0][1][0]); + } +} diff --git a/src/Symfony/Component/Translation/CHANGELOG.md b/src/Symfony/Component/Translation/CHANGELOG.md index 1b49d989ddf2a..1c8acb4351522 100644 --- a/src/Symfony/Component/Translation/CHANGELOG.md +++ b/src/Symfony/Component/Translation/CHANGELOG.md @@ -7,6 +7,7 @@ CHANGELOG * Give current locale to `LocaleSwitcher::runWithLocale()`'s callback * Add `--as-tree` option to `translation:pull` command to write YAML messages as a tree-like structure * [BC BREAK] Add argument `$buildDir` to `DataCollectorTranslator::warmUp()` + * Add `DataCollectorTranslatorPass` and `LoggingTranslatorPass` (moved from `FrameworkBundle`) 6.3 --- diff --git a/src/Symfony/Component/Translation/DependencyInjection/DataCollectorTranslatorPass.php b/src/Symfony/Component/Translation/DependencyInjection/DataCollectorTranslatorPass.php new file mode 100644 index 0000000000000..cdf63be4bc28e --- /dev/null +++ b/src/Symfony/Component/Translation/DependencyInjection/DataCollectorTranslatorPass.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\DependencyInjection; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Translation\TranslatorBagInterface; + +/** + * @author Christian Flothmann + */ +class DataCollectorTranslatorPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container): void + { + if (!$container->has('translator')) { + return; + } + + $translatorClass = $container->getParameterBag()->resolveValue($container->findDefinition('translator')->getClass()); + + if (!is_subclass_of($translatorClass, TranslatorBagInterface::class)) { + $container->removeDefinition('translator.data_collector'); + $container->removeDefinition('data_collector.translation'); + } + } +} diff --git a/src/Symfony/Component/Translation/DependencyInjection/LoggingTranslatorPass.php b/src/Symfony/Component/Translation/DependencyInjection/LoggingTranslatorPass.php new file mode 100644 index 0000000000000..c21552f975627 --- /dev/null +++ b/src/Symfony/Component/Translation/DependencyInjection/LoggingTranslatorPass.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\DependencyInjection; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\Translation\TranslatorBagInterface; +use Symfony\Contracts\Translation\TranslatorInterface; + +/** + * @author Abdellatif Ait boudad + */ +class LoggingTranslatorPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container): void + { + if (!$container->hasAlias('logger') || !$container->hasAlias('translator')) { + return; + } + + if (!$container->hasParameter('translator.logging') || !$container->getParameter('translator.logging')) { + return; + } + + $translatorAlias = $container->getAlias('translator'); + $definition = $container->getDefinition((string) $translatorAlias); + $class = $container->getParameterBag()->resolveValue($definition->getClass()); + + if (!$r = $container->getReflectionClass($class)) { + throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $translatorAlias)); + } + + if (!$r->isSubclassOf(TranslatorInterface::class) || !$r->isSubclassOf(TranslatorBagInterface::class)) { + return; + } + + $container->getDefinition('translator.logging')->setDecoratedService('translator'); + $warmer = $container->getDefinition('translation.warmer'); + $subscriberAttributes = $warmer->getTag('container.service_subscriber'); + $warmer->clearTag('container.service_subscriber'); + + foreach ($subscriberAttributes as $k => $v) { + if ((!isset($v['id']) || 'translator' !== $v['id']) && (!isset($v['key']) || 'translator' !== $v['key'])) { + $warmer->addTag('container.service_subscriber', $v); + } + } + $warmer->addTag('container.service_subscriber', ['key' => 'translator', 'id' => 'translator.logging.inner']); + } +} diff --git a/src/Symfony/Component/Translation/Tests/DependencyInjection/DataCollectorTranslatorPassTest.php b/src/Symfony/Component/Translation/Tests/DependencyInjection/DataCollectorTranslatorPassTest.php new file mode 100644 index 0000000000000..e61165047138d --- /dev/null +++ b/src/Symfony/Component/Translation/Tests/DependencyInjection/DataCollectorTranslatorPassTest.php @@ -0,0 +1,121 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Tests\DependencyInjection; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\Translation\DataCollector\TranslationDataCollector; +use Symfony\Component\Translation\DataCollectorTranslator; +use Symfony\Component\Translation\DependencyInjection\DataCollectorTranslatorPass; +use Symfony\Component\Translation\Translator; +use Symfony\Contracts\Translation\TranslatorInterface; + +class DataCollectorTranslatorPassTest extends TestCase +{ + private ContainerBuilder $container; + private DataCollectorTranslatorPass $dataCollectorTranslatorPass; + + protected function setUp(): void + { + $this->container = new ContainerBuilder(); + $this->dataCollectorTranslatorPass = new DataCollectorTranslatorPass(); + + $this->container->setParameter('translator_implementing_bag', Translator::class); + $this->container->setParameter('translator_not_implementing_bag', 'Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler\TranslatorWithoutTranslatorBag'); + + $this->container->register('translator.data_collector', DataCollectorTranslator::class) + ->setDecoratedService('translator') + ->setArguments([new Reference('translator.data_collector.inner')]) + ; + + $this->container->register('data_collector.translation', TranslationDataCollector::class) + ->setArguments([new Reference('translator.data_collector')]) + ; + } + + /** + * @dataProvider getImplementingTranslatorBagInterfaceTranslatorClassNames + */ + public function testProcessKeepsDataCollectorTranslatorIfItImplementsTranslatorBagInterface($class) + { + $this->container->register('translator', $class); + + $this->dataCollectorTranslatorPass->process($this->container); + + $this->assertTrue($this->container->hasDefinition('translator.data_collector')); + } + + /** + * @dataProvider getImplementingTranslatorBagInterfaceTranslatorClassNames + */ + public function testProcessKeepsDataCollectorIfTranslatorImplementsTranslatorBagInterface($class) + { + $this->container->register('translator', $class); + + $this->dataCollectorTranslatorPass->process($this->container); + + $this->assertTrue($this->container->hasDefinition('data_collector.translation')); + } + + public static function getImplementingTranslatorBagInterfaceTranslatorClassNames() + { + return [ + [Translator::class], + ['%translator_implementing_bag%'], + ]; + } + + /** + * @dataProvider getNotImplementingTranslatorBagInterfaceTranslatorClassNames + */ + public function testProcessRemovesDataCollectorTranslatorIfItDoesNotImplementTranslatorBagInterface($class) + { + $this->container->register('translator', $class); + + $this->dataCollectorTranslatorPass->process($this->container); + + $this->assertFalse($this->container->hasDefinition('translator.data_collector')); + } + + /** + * @dataProvider getNotImplementingTranslatorBagInterfaceTranslatorClassNames + */ + public function testProcessRemovesDataCollectorIfTranslatorDoesNotImplementTranslatorBagInterface($class) + { + $this->container->register('translator', $class); + + $this->dataCollectorTranslatorPass->process($this->container); + + $this->assertFalse($this->container->hasDefinition('data_collector.translation')); + } + + public static function getNotImplementingTranslatorBagInterfaceTranslatorClassNames() + { + return [ + ['Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler\TranslatorWithoutTranslatorBag'], + ['%translator_not_implementing_bag%'], + ]; + } +} + +class TranslatorWithoutTranslatorBag implements TranslatorInterface +{ + public function trans(string $id, array $parameters = [], string $domain = null, string $locale = null): string + { + } + + public function getLocale(): string + { + return 'en'; + } +} diff --git a/src/Symfony/Component/Translation/Tests/DependencyInjection/LoggingTranslatorPassTest.php b/src/Symfony/Component/Translation/Tests/DependencyInjection/LoggingTranslatorPassTest.php new file mode 100644 index 0000000000000..96e8bbcf9bcd2 --- /dev/null +++ b/src/Symfony/Component/Translation/Tests/DependencyInjection/LoggingTranslatorPassTest.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Tests\DependencyInjection; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\Translation\DependencyInjection\LoggingTranslatorPass; +use Symfony\Component\Translation\Translator; + +class LoggingTranslatorPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + $container->setParameter('translator.logging', true); + $container->setParameter('translator.class', Translator::class); + $container->register('monolog.logger'); + $container->setAlias('logger', 'monolog.logger'); + $container->register('translator.default', '%translator.class%'); + $container->register('translator.logging', '%translator.class%'); + $container->setAlias('translator', 'translator.default'); + $translationWarmerDefinition = $container->register('translation.warmer') + ->addArgument(new Reference('translator')) + ->addTag('container.service_subscriber', ['id' => 'translator']) + ->addTag('container.service_subscriber', ['id' => 'foo']); + + $pass = new LoggingTranslatorPass(); + $pass->process($container); + + $this->assertEquals( + ['container.service_subscriber' => [ + ['id' => 'foo'], + ['key' => 'translator', 'id' => 'translator.logging.inner'], + ]], + $translationWarmerDefinition->getTags() + ); + } + + public function testThatCompilerPassIsIgnoredIfThereIsNotLoggerDefinition() + { + $container = new ContainerBuilder(); + $container->register('identity_translator'); + $container->setAlias('translator', 'identity_translator'); + + $definitionsBefore = \count($container->getDefinitions()); + $aliasesBefore = \count($container->getAliases()); + + $pass = new LoggingTranslatorPass(); + $pass->process($container); + + // the container is untouched (i.e. no new definitions or aliases) + $this->assertCount($definitionsBefore, $container->getDefinitions()); + $this->assertCount($aliasesBefore, $container->getAliases()); + } + + public function testThatCompilerPassIsIgnoredIfThereIsNotTranslatorDefinition() + { + $container = new ContainerBuilder(); + $container->register('monolog.logger'); + $container->setAlias('logger', 'monolog.logger'); + + $definitionsBefore = \count($container->getDefinitions()); + $aliasesBefore = \count($container->getAliases()); + + $pass = new LoggingTranslatorPass(); + $pass->process($container); + + // the container is untouched (i.e. no new definitions or aliases) + $this->assertCount($definitionsBefore, $container->getDefinitions()); + $this->assertCount($aliasesBefore, $container->getAliases()); + } +} diff --git a/src/Symfony/Component/Workflow/CHANGELOG.md b/src/Symfony/Component/Workflow/CHANGELOG.md index da2bcd241f8fb..009bb3e09a475 100644 --- a/src/Symfony/Component/Workflow/CHANGELOG.md +++ b/src/Symfony/Component/Workflow/CHANGELOG.md @@ -12,6 +12,7 @@ CHANGELOG * Add PHP attributes to register listeners and guards * Deprecate `GuardEvent::getContext()` method that will be removed in 7.0 * Revert: Mark `Symfony\Component\Workflow\Registry` as internal + * Add `WorkflowGuardListenerPass` (moved from `FrameworkBundle`) 6.2 --- diff --git a/src/Symfony/Component/Workflow/DependencyInjection/WorkflowGuardListenerPass.php b/src/Symfony/Component/Workflow/DependencyInjection/WorkflowGuardListenerPass.php new file mode 100644 index 0000000000000..ba81a7bf1d50b --- /dev/null +++ b/src/Symfony/Component/Workflow/DependencyInjection/WorkflowGuardListenerPass.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Workflow\DependencyInjection; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\LogicException; + +/** + * @author Christian Flothmann + * @author Grégoire Pineau + */ +class WorkflowGuardListenerPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container): void + { + if (!$container->hasParameter('workflow.has_guard_listeners')) { + return; + } + + $container->getParameterBag()->remove('workflow.has_guard_listeners'); + + $servicesNeeded = [ + 'security.token_storage', + 'security.authorization_checker', + 'security.authentication.trust_resolver', + 'security.role_hierarchy', + ]; + + foreach ($servicesNeeded as $service) { + if (!$container->has($service)) { + throw new LogicException(sprintf('The "%s" service is needed to be able to use the workflow guard listener.', $service)); + } + } + } +} diff --git a/src/Symfony/Component/Workflow/Tests/DependencyInjection/WorkflowGuardListenerPassTest.php b/src/Symfony/Component/Workflow/Tests/DependencyInjection/WorkflowGuardListenerPassTest.php new file mode 100644 index 0000000000000..4e69a9cc0cf91 --- /dev/null +++ b/src/Symfony/Component/Workflow/Tests/DependencyInjection/WorkflowGuardListenerPassTest.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Workflow\Tests\DependencyInjection; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\LogicException; +use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; +use Symfony\Component\Security\Core\Role\RoleHierarchy; +use Symfony\Component\Validator\Validator\ValidatorInterface; +use Symfony\Component\Workflow\DependencyInjection\WorkflowGuardListenerPass; + +class WorkflowGuardListenerPassTest extends TestCase +{ + private ContainerBuilder $container; + private WorkflowGuardListenerPass $compilerPass; + + protected function setUp(): void + { + $this->container = new ContainerBuilder(); + $this->compilerPass = new WorkflowGuardListenerPass(); + } + + public function testNoExeptionIfParameterIsNotSet() + { + $this->compilerPass->process($this->container); + + $this->assertFalse($this->container->hasParameter('workflow.has_guard_listeners')); + } + + public function testNoExeptionIfAllDependenciesArePresent() + { + $this->container->setParameter('workflow.has_guard_listeners', true); + $this->container->register('security.token_storage', TokenStorageInterface::class); + $this->container->register('security.authorization_checker', AuthorizationCheckerInterface::class); + $this->container->register('security.authentication.trust_resolver', AuthenticationTrustResolverInterface::class); + $this->container->register('security.role_hierarchy', RoleHierarchy::class); + $this->container->register('validator', ValidatorInterface::class); + + $this->compilerPass->process($this->container); + + $this->assertFalse($this->container->hasParameter('workflow.has_guard_listeners')); + } + + public function testExceptionIfTheTokenStorageServiceIsNotPresent() + { + $this->container->setParameter('workflow.has_guard_listeners', true); + $this->container->register('security.authorization_checker', AuthorizationCheckerInterface::class); + $this->container->register('security.authentication.trust_resolver', AuthenticationTrustResolverInterface::class); + $this->container->register('security.role_hierarchy', RoleHierarchy::class); + + $this->expectException(LogicException::class); + $this->expectExceptionMessage('The "security.token_storage" service is needed to be able to use the workflow guard listener.'); + + $this->compilerPass->process($this->container); + } + + public function testExceptionIfTheAuthorizationCheckerServiceIsNotPresent() + { + $this->container->setParameter('workflow.has_guard_listeners', true); + $this->container->register('security.token_storage', TokenStorageInterface::class); + $this->container->register('security.authentication.trust_resolver', AuthenticationTrustResolverInterface::class); + $this->container->register('security.role_hierarchy', RoleHierarchy::class); + + $this->expectException(LogicException::class); + $this->expectExceptionMessage('The "security.authorization_checker" service is needed to be able to use the workflow guard listener.'); + + $this->compilerPass->process($this->container); + } + + public function testExceptionIfTheAuthenticationTrustResolverServiceIsNotPresent() + { + $this->container->setParameter('workflow.has_guard_listeners', true); + $this->container->register('security.token_storage', TokenStorageInterface::class); + $this->container->register('security.authorization_checker', AuthorizationCheckerInterface::class); + $this->container->register('security.role_hierarchy', RoleHierarchy::class); + + $this->expectException(LogicException::class); + $this->expectExceptionMessage('The "security.authentication.trust_resolver" service is needed to be able to use the workflow guard listener.'); + + $this->compilerPass->process($this->container); + } + + public function testExceptionIfTheRoleHierarchyServiceIsNotPresent() + { + $this->container->setParameter('workflow.has_guard_listeners', true); + $this->container->register('security.token_storage', TokenStorageInterface::class); + $this->container->register('security.authorization_checker', AuthorizationCheckerInterface::class); + $this->container->register('security.authentication.trust_resolver', AuthenticationTrustResolverInterface::class); + + $this->expectException(LogicException::class); + $this->expectExceptionMessage('The "security.role_hierarchy" service is needed to be able to use the workflow guard listener.'); + + $this->compilerPass->process($this->container); + } +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy