diff --git a/composer.json b/composer.json index b2f9d9f155b..2db0c2cc3e0 100644 --- a/composer.json +++ b/composer.json @@ -54,7 +54,6 @@ "symfony/twig-bridge": "^4.3", "symfony/twig-bundle": "^4.3", "symfony/validator": "^4.3", - "twig/extra-bundle": "^3.0", "twig/string-extra": "^3.0", "twig/twig": "^2.12.1" }, @@ -81,7 +80,8 @@ }, "suggest": { "jms/translation-bundle": "Extract message keys from Admins", - "kunicmarko/sonata-auto-configure-bundle": "Auto configures Admin classes" + "kunicmarko/sonata-auto-configure-bundle": "Auto configures Admin classes", + "twig/extra-bundle": "Auto configures the Twig Intl extension" }, "config": { "sort-packages": true diff --git a/src/DependencyInjection/Compiler/TwigStringExtensionCompilerPass.php b/src/DependencyInjection/Compiler/TwigStringExtensionCompilerPass.php new file mode 100644 index 00000000000..cd4004d6030 --- /dev/null +++ b/src/DependencyInjection/Compiler/TwigStringExtensionCompilerPass.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\AdminBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Twig\Extra\String\StringExtension; + +final class TwigStringExtensionCompilerPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container): void + { + foreach ($container->findTaggedServiceIds('twig.extension') as $id => $attributes) { + if (StringExtension::class === $container->getDefinition($id)->getClass()) { + return; + } + } + + $definition = new Definition(StringExtension::class); + $definition->addTag('twig.extension'); + $container->setDefinition(StringExtension::class, $definition); + } +} diff --git a/src/SonataAdminBundle.php b/src/SonataAdminBundle.php index 808a771c984..6042be6f1cd 100644 --- a/src/SonataAdminBundle.php +++ b/src/SonataAdminBundle.php @@ -20,6 +20,7 @@ use Sonata\AdminBundle\DependencyInjection\Compiler\GlobalVariablesCompilerPass; use Sonata\AdminBundle\DependencyInjection\Compiler\ModelManagerCompilerPass; use Sonata\AdminBundle\DependencyInjection\Compiler\ObjectAclManipulatorCompilerPass; +use Sonata\AdminBundle\DependencyInjection\Compiler\TwigStringExtensionCompilerPass; use Sonata\AdminBundle\Form\Type\AdminType; use Sonata\AdminBundle\Form\Type\ChoiceFieldMaskType; use Sonata\AdminBundle\Form\Type\CollectionType; @@ -52,6 +53,7 @@ public function build(ContainerBuilder $container) $container->addCompilerPass(new GlobalVariablesCompilerPass()); $container->addCompilerPass(new ModelManagerCompilerPass()); $container->addCompilerPass(new ObjectAclManipulatorCompilerPass()); + $container->addCompilerPass(new TwigStringExtensionCompilerPass()); $this->registerFormMapping(); } diff --git a/tests/App/AppKernel.php b/tests/App/AppKernel.php index b2f9369fd12..69afc92b998 100644 --- a/tests/App/AppKernel.php +++ b/tests/App/AppKernel.php @@ -26,9 +26,10 @@ use Symfony\Bundle\TwigBundle\TwigBundle; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\Routing\RouteCollectionBuilder; -use Twig\Extra\TwigExtraBundle\TwigExtraBundle; +use Twig\Extra\String\StringExtension; final class AppKernel extends Kernel { @@ -44,7 +45,6 @@ public function registerBundles() $bundles = [ new FrameworkBundle(), new TwigBundle(), - new TwigExtraBundle(), new SecurityBundle(), new KnpMenuBundle(), new SonataBlockBundle(), @@ -103,6 +103,10 @@ protected function configureContainer(ContainerBuilder $containerBuilder, Loader ]); $loader->load($this->getProjectDir().'/config/services.yml'); + + $definition = new Definition(StringExtension::class); + $definition->addTag('twig.extension'); + $containerBuilder->setDefinition(StringExtension::class, $definition); } private function getBaseDir(): string diff --git a/tests/DependencyInjection/Compiler/TwigStringExtensionCompilerPassTest.php b/tests/DependencyInjection/Compiler/TwigStringExtensionCompilerPassTest.php new file mode 100644 index 00000000000..b84b7ef9ac4 --- /dev/null +++ b/tests/DependencyInjection/Compiler/TwigStringExtensionCompilerPassTest.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\AdminBundle\Tests\DependencyInjection\Compiler; + +use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractCompilerPassTestCase; +use Sonata\AdminBundle\DependencyInjection\Compiler\TwigStringExtensionCompilerPass; +use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TwigEnvironmentPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Twig\Extra\String\StringExtension; + +class TwigStringExtensionCompilerPassTest extends AbstractCompilerPassTestCase +{ + public function testLoadTwigStringExtension(): void + { + $this->compile(); + + $this->assertContainerBuilderHasServiceDefinitionWithTag(StringExtension::class, 'twig.extension'); + } + + public function testLoadTwigStringExtensionWithExtraBundle(): void + { + $definition = new Definition(StringExtension::class); + $definition->addTag('twig.extension'); + $this->container->setDefinition('twig.extension.string', $definition); + $this->compile(); + + $this->assertContainerBuilderHasServiceDefinitionWithTag('twig.extension.string', 'twig.extension'); + $this->assertContainerBuilderNotHasService(StringExtension::class); + } + + protected function registerCompilerPass(ContainerBuilder $container): void + { + $container->addCompilerPass(new TwigEnvironmentPass()); + $container->addCompilerPass(new TwigStringExtensionCompilerPass()); + } +} diff --git a/tests/SonataAdminBundleTest.php b/tests/SonataAdminBundleTest.php index a7dd69ed892..6dbaaa37905 100644 --- a/tests/SonataAdminBundleTest.php +++ b/tests/SonataAdminBundleTest.php @@ -20,6 +20,7 @@ use Sonata\AdminBundle\DependencyInjection\Compiler\GlobalVariablesCompilerPass; use Sonata\AdminBundle\DependencyInjection\Compiler\ModelManagerCompilerPass; use Sonata\AdminBundle\DependencyInjection\Compiler\ObjectAclManipulatorCompilerPass; +use Sonata\AdminBundle\DependencyInjection\Compiler\TwigStringExtensionCompilerPass; use Sonata\AdminBundle\SonataAdminBundle; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\PassConfig; @@ -36,7 +37,7 @@ public function testBuild(): void ->setMethods(['addCompilerPass']) ->getMock(); - $containerBuilder->expects($this->exactly(6)) + $containerBuilder->expects($this->exactly(7)) ->method('addCompilerPass') ->willReturnCallback(function (CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION): void { if ($pass instanceof AddDependencyCallsCompilerPass) { @@ -63,14 +64,19 @@ public function testBuild(): void return; } + if ($pass instanceof TwigStringExtensionCompilerPass) { + return; + } + $this->fail(sprintf( - 'CompilerPass is not one of the expected types. Expects "%s", "%s", "%s", "%s", "%s" or "%s", but got "%s".', + 'CompilerPass is not one of the expected types. Expects "%s", "%s", "%s", "%s", "%s", "%s" or "%s", but got "%s".', AddDependencyCallsCompilerPass::class, AddFilterTypeCompilerPass::class, ExtensionCompilerPass::class, GlobalVariablesCompilerPass::class, ModelManagerCompilerPass::class, ObjectAclManipulatorCompilerPass::class, + TwigStringExtensionCompilerPass::class, \get_class($pass) )); });