diff --git a/src/Bundle/DependencyInjection/Compiler/RegisterFiltersPass.php b/src/Bundle/DependencyInjection/Compiler/RegisterFiltersPass.php index 71565417..7c6490f1 100644 --- a/src/Bundle/DependencyInjection/Compiler/RegisterFiltersPass.php +++ b/src/Bundle/DependencyInjection/Compiler/RegisterFiltersPass.php @@ -14,10 +14,12 @@ namespace Sylius\Bundle\GridBundle\DependencyInjection\Compiler; use InvalidArgumentException; +use Sylius\Component\Grid\Attribute\AsFilter; use Sylius\Component\Grid\Filtering\FormTypeAwareFilterInterface; use Sylius\Component\Grid\Filtering\TypeAwareFilterInterface; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; final class RegisterFiltersPass implements CompilerPassInterface @@ -28,10 +30,21 @@ public function process(ContainerBuilder $container): void return; } - $registry = $container->getDefinition('sylius.registry.grid_filter'); + $filterRegistry = $container->getDefinition('sylius.registry.grid_filter'); $formTypeRegistry = $container->getDefinition('sylius.form_registry.grid_filter'); - foreach ($container->findTaggedServiceIds('sylius.grid_filter') as $id => $attributes) { + foreach ($container->findTaggedServiceIds(AsFilter::SERVICE_TAG) as $id => $attributes) { + $this->registerFilter($filterRegistry, $formTypeRegistry, $id, $attributes); + } + + foreach ($container->findTaggedServiceIds('sylius.legacy_grid_filter') as $id => $attributes) { + $definition = $container->findDefinition($id); + + // Already configured with "sylius.grid_filter" tag. + if ($definition->hasTag(AsFilter::SERVICE_TAG)) { + continue; + } + $type = null; $formType = null; @@ -43,18 +56,29 @@ public function process(ContainerBuilder $container): void $formType = $id::getFormType(); } - foreach ($attributes as $attribute) { - if (null === $type && null === ($attribute['type'] ?? null)) { - throw new InvalidArgumentException(sprintf('Tagged grid filters needs to have "type" attributes or implements "%s".', TypeAwareFilterInterface::class)); - } + $this->registerFilter($filterRegistry, $formTypeRegistry, $id, $attributes, $type, $formType); + } + } - if (null === $formType && null === ($attribute['form_type'] ?? null)) { - throw new InvalidArgumentException(sprintf('Tagged grid filters needs to have "form_type" attributes or implements %s.', FormTypeAwareFilterInterface::class)); - } + private function registerFilter( + Definition $filterRegistry, + Definition $formTypeRegistry, + string $id, + array $attributes, + ?string $type = null, + ?string $formType = null, + ): void { + foreach ($attributes as $attribute) { + if (null === $type && null === ($attribute['type'] ?? null)) { + throw new InvalidArgumentException(sprintf('Tagged grid filters needs to have "type" attribute or implements "%s".', TypeAwareFilterInterface::class)); + } - $registry->addMethodCall('register', [$type ?? $attribute['type'], new Reference($id)]); - $formTypeRegistry->addMethodCall('add', [$type ?? $attribute['type'], 'default', $formType ?? $attribute['form_type']]); + if (null === $formType && null === ($attribute['form_type'] ?? null)) { + throw new InvalidArgumentException(sprintf('Tagged grid filters needs to have "form_type" attribute or implements "%s".', FormTypeAwareFilterInterface::class)); } + + $filterRegistry->addMethodCall('register', [$type ?? $attribute['type'], new Reference($id)]); + $formTypeRegistry->addMethodCall('add', [$type ?? $attribute['type'], 'default', $formType ?? $attribute['form_type']]); } } } diff --git a/src/Bundle/DependencyInjection/SyliusGridExtension.php b/src/Bundle/DependencyInjection/SyliusGridExtension.php index d12aa280..122108ac 100644 --- a/src/Bundle/DependencyInjection/SyliusGridExtension.php +++ b/src/Bundle/DependencyInjection/SyliusGridExtension.php @@ -78,7 +78,7 @@ static function (ChildDefinition $definition, AsFilter $attribute, \Reflector $r ); $container->registerForAutoconfiguration(FilterInterface::class) - ->addTag('sylius.grid_filter') + ->addTag('sylius.legacy_grid_filter') ; $container->registerForAutoconfiguration(DataProviderInterface::class) diff --git a/src/Bundle/Tests/DependencyInjection/Compiler/RegisterFiltersPassTest.php b/src/Bundle/Tests/DependencyInjection/Compiler/RegisterFiltersPassTest.php index 9e51fff7..2609f63d 100644 --- a/src/Bundle/Tests/DependencyInjection/Compiler/RegisterFiltersPassTest.php +++ b/src/Bundle/Tests/DependencyInjection/Compiler/RegisterFiltersPassTest.php @@ -13,11 +13,14 @@ namespace Sylius\Bundle\GridBundle\Tests\DependencyInjection\Compiler; +use App\Filter\AttributeNationalityFilter; use App\Filter\Foo; use App\Filter\NationalityFilter; use App\Grid\Type\NationalityFilterType; use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractCompilerPassTestCase; use Sylius\Bundle\GridBundle\DependencyInjection\Compiler\RegisterFiltersPass; +use Sylius\Component\Grid\Filtering\FormTypeAwareFilterInterface; +use Sylius\Component\Grid\Filtering\TypeAwareFilterInterface; use Sylius\Component\Registry\ServiceRegistry; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; @@ -73,15 +76,18 @@ public function it_registers_a_grid_filter_and_form_type_for_every_service_filte /** * @test */ - public function it_autoconfigures_a_grid_filter(): void + public function it_autoconfigures_a_legacy_grid_filter(): void { $this->registerService(NationalityFilter::class, NationalityFilter::class) - ->addTag('sylius.grid_filter') + ->addTag('sylius.legacy_grid_filter') ; - $this->registerService($filterRegistryServiceId = 'sylius.registry.grid_filter', ServiceRegistry::class); + $filterRegistryServiceId = 'sylius.registry.grid_filter'; + $filterFormTypeRegistryServiceId = 'sylius.form_registry.grid_filter'; + + $this->registerService($filterRegistryServiceId, ServiceRegistry::class); $this->registerService( - $filterFormTypeRegistryServiceId = 'sylius.form_registry.grid_filter', + $filterFormTypeRegistryServiceId, ServiceRegistry::class, ); @@ -109,6 +115,97 @@ public function it_autoconfigures_a_grid_filter(): void ); } + /** + * @test + */ + public function it_autoconfigures_a_grid_filter(): void + { + $this->registerService(AttributeNationalityFilter::class, AttributeNationalityFilter::class) + ->addTag('sylius.grid_filter', ['form_type' => NationalityFilterType::class, 'type' => AttributeNationalityFilter::class]) + ->addTag('sylius.legacy_grid_filter') + ; + + $filterRegistryServiceId = 'sylius.registry.grid_filter'; + $filterFormTypeRegistryServiceId = 'sylius.form_registry.grid_filter'; + + $this->registerService($filterRegistryServiceId, ServiceRegistry::class); + $this->registerService( + $filterFormTypeRegistryServiceId, + ServiceRegistry::class, + ); + + $this->compile(); + + // Filter + $this->assertContainerBuilderHasServiceDefinitionWithMethodCall( + $filterRegistryServiceId, + 'register', + [ + AttributeNationalityFilter::class, + new Reference(AttributeNationalityFilter::class), + ], + ); + + // Form Type + $this->assertContainerBuilderHasServiceDefinitionWithMethodCall( + $filterFormTypeRegistryServiceId, + 'add', + [ + AttributeNationalityFilter::class, + 'default', + NationalityFilterType::class, + ], + ); + } + + /** + * @test + */ + public function it_throws_an_exception_when_grid_filter_has_no_type_attribute(): void + { + $this->registerService(Foo::class, Foo::class) + ->addTag('sylius.grid_filter') + ; + + $filterRegistryServiceId = 'sylius.registry.grid_filter'; + $filterFormTypeRegistryServiceId = 'sylius.form_registry.grid_filter'; + + $this->registerService($filterRegistryServiceId, ServiceRegistry::class); + $this->registerService( + $filterFormTypeRegistryServiceId, + ServiceRegistry::class, + ); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage(sprintf('Tagged grid filters needs to have "type" attribute or implements "%s".', TypeAwareFilterInterface::class)); + + $this->compile(); + } + + /** + * @test + */ + public function it_throws_an_exception_when_grid_filter_has_no_form_type_attribute(): void + { + $this->registerService(Foo::class, Foo::class) + ->addTag('sylius.grid_filter', ['type' => Foo::class]) + ; + + $filterRegistryServiceId = 'sylius.registry.grid_filter'; + $filterFormTypeRegistryServiceId = 'sylius.form_registry.grid_filter'; + + $this->registerService($filterRegistryServiceId, ServiceRegistry::class); + $this->registerService( + $filterFormTypeRegistryServiceId, + ServiceRegistry::class, + ); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage(sprintf('Tagged grid filters needs to have "form_type" attribute or implements "%s".', FormTypeAwareFilterInterface::class)); + + $this->compile(); + } + protected function registerCompilerPass(ContainerBuilder $container): void { $container->addCompilerPass(new RegisterFiltersPass()); diff --git a/src/Component/Attribute/AsFilter.php b/src/Component/Attribute/AsFilter.php index 1bc79d52..6a39fb07 100644 --- a/src/Component/Attribute/AsFilter.php +++ b/src/Component/Attribute/AsFilter.php @@ -16,7 +16,7 @@ #[\Attribute(\Attribute::TARGET_CLASS)] final class AsFilter { - public const SERVICE_TAG = 'sylius.grid.filter'; + public const SERVICE_TAG = 'sylius.grid_filter'; /** * @param class-string $formType The form type class name to use for filter rendering diff --git a/tests/Application/config/services.yaml b/tests/Application/config/services.yaml index 8853a837..99d572df 100644 --- a/tests/Application/config/services.yaml +++ b/tests/Application/config/services.yaml @@ -25,6 +25,7 @@ services: - '@app.repository.author' public: true + App\Filter\AttributeNationalityFilter: null App\Filter\NationalityFilter: null App\BoardGameBlog\: