diff --git a/src/DependencyInjection/Compiler/AddDependencyCallsCompilerPass.php b/src/DependencyInjection/Compiler/AddDependencyCallsCompilerPass.php index df5541da82..c4b4508e91 100644 --- a/src/DependencyInjection/Compiler/AddDependencyCallsCompilerPass.php +++ b/src/DependencyInjection/Compiler/AddDependencyCallsCompilerPass.php @@ -338,7 +338,7 @@ public function applyDefaults(ContainerBuilder $container, $serviceId, array $at $method = $this->generateSetterMethodName($attr); - if (isset($overwriteAdminConfiguration[$attr]) || !$definition->hasMethodCall($method)) { + if (!$definition->hasMethodCall($method)) { $args = [new Reference($overwriteAdminConfiguration[$attr] ?? $addServiceId)]; if ('translator' === $attr) { $args[] = false; @@ -386,7 +386,12 @@ public function applyDefaults(ContainerBuilder $container, $serviceId, array $at $definition->addMethodCall('setSecurityInformation', ['%sonata.admin.configuration.security.information%']); } - $definition->addMethodCall('initialize'); + if (!$definition->hasMethodCall('setFormTheme')) { + $definition->addMethodCall('setFormTheme', [$overwriteAdminConfiguration['templates']['form'] ?? []]); + } + if (!$definition->hasMethodCall('setFilterTheme')) { + $definition->addMethodCall('setFilterTheme', [$overwriteAdminConfiguration['templates']['filter'] ?? []]); + } return $definition; } diff --git a/src/DependencyInjection/Compiler/AdminAddInitializeCallCompilerPass.php b/src/DependencyInjection/Compiler/AdminAddInitializeCallCompilerPass.php new file mode 100644 index 0000000000..c47d7c89e3 --- /dev/null +++ b/src/DependencyInjection/Compiler/AdminAddInitializeCallCompilerPass.php @@ -0,0 +1,34 @@ + + * + * 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; + +/** + * this compiler pass is registered with low priority to make sure it runs after all the other passes + * as we want the "initialize()" calls to come after all the other calls. + * + * @internal + */ +final class AdminAddInitializeCallCompilerPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container): void + { + $admins = $container->findTaggedServiceIds('sonata.admin'); + foreach (array_keys($admins) as $id) { + $container->getDefinition($id)->addMethodCall('initialize'); + } + } +} diff --git a/src/SonataAdminBundle.php b/src/SonataAdminBundle.php index 8b7095a86e..d6cf2eea29 100644 --- a/src/SonataAdminBundle.php +++ b/src/SonataAdminBundle.php @@ -17,6 +17,7 @@ use Sonata\AdminBundle\DependencyInjection\Compiler\AddAuditReadersCompilerPass; use Sonata\AdminBundle\DependencyInjection\Compiler\AddDependencyCallsCompilerPass; use Sonata\AdminBundle\DependencyInjection\Compiler\AddFilterTypeCompilerPass; +use Sonata\AdminBundle\DependencyInjection\Compiler\AdminAddInitializeCallCompilerPass; use Sonata\AdminBundle\DependencyInjection\Compiler\AdminMakerCompilerPass; use Sonata\AdminBundle\DependencyInjection\Compiler\AdminSearchCompilerPass; use Sonata\AdminBundle\DependencyInjection\Compiler\AliasDeprecatedPublicServicesCompilerPass; @@ -63,6 +64,7 @@ public function build(ContainerBuilder $container) $container->addCompilerPass(new AdminMakerCompilerPass()); $container->addCompilerPass(new AddAuditReadersCompilerPass()); $container->addCompilerPass(new AliasDeprecatedPublicServicesCompilerPass(), PassConfig::TYPE_AFTER_REMOVING); + $container->addCompilerPass(new AdminAddInitializeCallCompilerPass(), PassConfig::TYPE_BEFORE_REMOVING, -100); $this->registerFormMapping(); } diff --git a/tests/DependencyInjection/Compiler/AddDependencyCallsCompilerPassTest.php b/tests/DependencyInjection/Compiler/AddDependencyCallsCompilerPassTest.php index 8faba6151e..c2af8d154b 100644 --- a/tests/DependencyInjection/Compiler/AddDependencyCallsCompilerPassTest.php +++ b/tests/DependencyInjection/Compiler/AddDependencyCallsCompilerPassTest.php @@ -27,6 +27,7 @@ use Symfony\Component\DependencyInjection\Compiler\ResolveEnvPlaceholdersPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; /** * @author Tiago Garcia @@ -200,6 +201,48 @@ public function testProcessResultingConfig(): void 'setRouteBuilder', ['sonata.admin.route.path_info_slashes'] ); + + $this->assertContainerBuilderHasServiceDefinitionWithMethodCall( + 'sonata_news_admin', + 'setFormTheme', + [[]] + ); + + $this->assertContainerBuilderHasServiceDefinitionWithMethodCall( + 'sonata_news_admin', + 'setFilterTheme', + [[]] + ); + + $this->assertContainerBuilderHasServiceDefinitionWithMethodCall( + 'sonata_news_admin', + 'setModelManager', + [new Reference('my.model.manager')] + ); + + $this->assertContainerBuilderHasServiceDefinitionWithMethodCall( + 'sonata_article_admin', + 'setFormTheme', + [['custom_form_theme.twig']] + ); + + $this->assertContainerBuilderHasServiceDefinitionWithMethodCall( + 'sonata_article_admin', + 'setFilterTheme', + [['custom_filter_theme.twig']] + ); + + $this->assertContainerBuilderHasServiceDefinitionWithMethodCall( + 'sonata_post_admin', + 'setFormTheme', + [['some_form_template.twig']] + ); + + $this->assertContainerBuilderHasServiceDefinitionWithMethodCall( + 'sonata_post_admin', + 'setFilterTheme', + [['some_filter_template.twig']] + ); } public function testProcessSortAdmins(): void @@ -591,6 +634,8 @@ protected function getConfig() 'sonata_post_admin' => [ 'templates' => [ 'view' => ['user_block' => 'foobar.twig.html'], + 'form' => ['some_form_template.twig'], + 'filter' => ['some_filter_template.twig'], ], ], 'sonata_news_admin' => [ @@ -600,6 +645,12 @@ protected function getConfig() 'view' => ['user_block' => 'foo.twig.html'], ], ], + 'sonata_article_admin' => [ + 'templates' => [ + 'form' => ['some_form_template.twig'], + 'filter' => ['some_filter_template.twig'], + ], + ], ], ]; } @@ -624,7 +675,8 @@ private function setUpContainer(): void ->setPublic(true) ->setClass(MockAdmin::class) ->setArguments(['', News::class, CRUDController::class]) - ->addTag('sonata.admin', ['group' => 'sonata_group_two', 'label' => '5 Entry', 'manager_type' => 'orm']); + ->addTag('sonata.admin', ['group' => 'sonata_group_two', 'label' => '5 Entry', 'manager_type' => 'orm']) + ->addMethodCall('setModelManager', [new Reference('my.model.manager')]); $this->container ->register('sonata_post_admin') ->setClass(MockAdmin::class) @@ -636,7 +688,9 @@ private function setUpContainer(): void ->setPublic(true) ->setClass(MockAdmin::class) ->setArguments(['', Article::class, CRUDController::class]) - ->addTag('sonata.admin', ['group' => 'sonata_group_one', 'label' => '1 Entry', 'manager_type' => 'doctrine_phpcr']); + ->addTag('sonata.admin', ['group' => 'sonata_group_one', 'label' => '1 Entry', 'manager_type' => 'doctrine_phpcr']) + ->addMethodCall('setFormTheme', [['custom_form_theme.twig']]) + ->addMethodCall('setFilterTheme', [['custom_filter_theme.twig']]); $this->container ->register('sonata_report_admin') ->setPublic(true) diff --git a/tests/DependencyInjection/Compiler/AdminAddInitializeCallCompilerPassTest.php b/tests/DependencyInjection/Compiler/AdminAddInitializeCallCompilerPassTest.php new file mode 100644 index 0000000000..4f21c4a5c0 --- /dev/null +++ b/tests/DependencyInjection/Compiler/AdminAddInitializeCallCompilerPassTest.php @@ -0,0 +1,33 @@ + + * + * 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 PHPUnit\Framework\TestCase; +use Sonata\AdminBundle\DependencyInjection\Compiler\AdminAddInitializeCallCompilerPass; +use Sonata\AdminBundle\Tests\App\Admin\FooAdmin; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +final class AdminAddInitializeCallCompilerPassTest extends TestCase +{ + public function testProcess(): void + { + $builder = new ContainerBuilder(); + $builder->register('foo', FooAdmin::class) + ->addTag('sonata.admin'); + + (new AdminAddInitializeCallCompilerPass())->process($builder); + + $this->assertSame([['initialize', []]], $builder->getDefinition('foo')->getMethodCalls()); + } +} diff --git a/tests/SonataAdminBundleTest.php b/tests/SonataAdminBundleTest.php index 48b4ec4ab4..560a7f7990 100644 --- a/tests/SonataAdminBundleTest.php +++ b/tests/SonataAdminBundleTest.php @@ -17,6 +17,7 @@ use Sonata\AdminBundle\DependencyInjection\Compiler\AddAuditReadersCompilerPass; use Sonata\AdminBundle\DependencyInjection\Compiler\AddDependencyCallsCompilerPass; use Sonata\AdminBundle\DependencyInjection\Compiler\AddFilterTypeCompilerPass; +use Sonata\AdminBundle\DependencyInjection\Compiler\AdminAddInitializeCallCompilerPass; use Sonata\AdminBundle\DependencyInjection\Compiler\AdminMakerCompilerPass; use Sonata\AdminBundle\DependencyInjection\Compiler\AdminSearchCompilerPass; use Sonata\AdminBundle\DependencyInjection\Compiler\AliasDeprecatedPublicServicesCompilerPass; @@ -37,7 +38,7 @@ public function testBuild(): void { $containerBuilder = $this->createMock(ContainerBuilder::class); - $containerBuilder->expects($this->exactly(11)) + $containerBuilder->expects($this->exactly(12)) ->method('addCompilerPass') ->withConsecutive( [new AddDependencyCallsCompilerPass()], @@ -51,6 +52,7 @@ public function testBuild(): void [new AdminMakerCompilerPass()], [new AddAuditReadersCompilerPass()], [new AliasDeprecatedPublicServicesCompilerPass()], + [new AdminAddInitializeCallCompilerPass()], ); $bundle = new SonataAdminBundle();