diff --git a/docs/custom_filter.md b/docs/custom_filter.md index 6b39abe3..850c602d 100644 --- a/docs/custom_filter.md +++ b/docs/custom_filter.md @@ -12,9 +12,11 @@ namespace App\Grid\Filter; use App\Form\Type\Filter\SuppliersStatisticsFilterType; use Sylius\Bundle\GridBundle\Doctrine\DataSourceInterface; -use Sylius\Component\Grid\Filtering\ConfiguragurableFilterInterface; +use Sylius\Component\Grid\Filtering\FilterInterface; +use Sylius\Component\Grid\Metadata\AsFilter; -class SuppliersStatisticsFilter implements ConfiguragurableFilterInterface +#[AsFilter(formType: SuppliersStatisticsFilterType::class)] +class SuppliersStatisticsFilter implements FilterInterface { public function apply(DataSourceInterface $dataSource, $name, $data, array $options = []): void { @@ -32,16 +34,6 @@ class SuppliersStatisticsFilter implements ConfiguragurableFilterInterface // here is an example $dataSource->restrict($dataSource->getExpressionBuilder()->equals('stats', $data['stats'])); } - - public static function getType() : string - { - return 'suppliers_statistics'; - } - - public static function getFormType() : string - { - return SuppliersStatisticsFilterType::class; - } } ``` @@ -116,7 +108,7 @@ sylius_grid: resource: app.tournament filters: stats: - type: suppliers_statistics + type: !php/const App\Grid\Filter\SuppliersStatisticsFilter::class form_options: range: [0, 100] templates: diff --git a/src/Bundle/DependencyInjection/Compiler/RegisterFiltersPass.php b/src/Bundle/DependencyInjection/Compiler/RegisterFiltersPass.php index 71565417..bc25a674 100644 --- a/src/Bundle/DependencyInjection/Compiler/RegisterFiltersPass.php +++ b/src/Bundle/DependencyInjection/Compiler/RegisterFiltersPass.php @@ -44,6 +44,10 @@ public function process(ContainerBuilder $container): void } foreach ($attributes as $attribute) { + if (isset($attribute['type'], $attribute['form_type'])) { + return; + } + if (null === $type && null === ($attribute['type'] ?? null)) { throw new InvalidArgumentException(sprintf('Tagged grid filters needs to have "type" attributes or implements "%s".', TypeAwareFilterInterface::class)); } diff --git a/src/Bundle/DependencyInjection/SyliusGridExtension.php b/src/Bundle/DependencyInjection/SyliusGridExtension.php index 493e1dab..da797a55 100644 --- a/src/Bundle/DependencyInjection/SyliusGridExtension.php +++ b/src/Bundle/DependencyInjection/SyliusGridExtension.php @@ -18,7 +18,9 @@ use Sylius\Bundle\GridBundle\SyliusGridBundle; use Sylius\Component\Grid\Data\DataProviderInterface; use Sylius\Component\Grid\Filtering\FilterInterface; +use Sylius\Component\Grid\Metadata\AsFilter; use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\Extension; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; @@ -60,6 +62,17 @@ public function load(array $configs, ContainerBuilder $container): void ->addTag('sylius.grid') ; + $container->registerAttributeForAutoconfiguration(AsFilter::class, function (ChildDefinition $definition, AsFilter $attribute, \Reflector $reflector): void { + if (!$reflector instanceof \ReflectionClass) { + throw new \LogicException(sprintf('The attribute "%s" can only be used on classes.', AsFilter::class)); + } + $tagAttributes = [ + 'type' => $attribute->type ?? $reflector->getName(), + 'form_type' => $attribute->formType, + ]; + $definition->addTag('sylius.grid_filter', $tagAttributes); + }); + $container->registerForAutoconfiguration(FilterInterface::class) ->addTag('sylius.grid_filter') ; diff --git a/src/Component/Metadata/AsFilter.php b/src/Component/Metadata/AsFilter.php new file mode 100644 index 00000000..ad41d42b --- /dev/null +++ b/src/Component/Metadata/AsFilter.php @@ -0,0 +1,28 @@ +addFilter(AttributeNationalityFilter::create( + AttributeNationalityFilter::class, + null, + ['author.nationality'], + )) ->addFilter(StringFilter::create( 'currencyCode', ['price.currencyCode'], diff --git a/tests/Application/src/Filter/AttributeNationalityFilter.php b/tests/Application/src/Filter/AttributeNationalityFilter.php new file mode 100644 index 00000000..9e9e830f --- /dev/null +++ b/tests/Application/src/Filter/AttributeNationalityFilter.php @@ -0,0 +1,35 @@ +decorated->apply($dataSource, $name, $data, $options); + } +} diff --git a/tests/Application/src/Grid/Builder/AttributeNationalityFilter.php b/tests/Application/src/Grid/Builder/AttributeNationalityFilter.php new file mode 100644 index 00000000..c6b8d7db --- /dev/null +++ b/tests/Application/src/Grid/Builder/AttributeNationalityFilter.php @@ -0,0 +1,39 @@ +setFormOptions(['class' => Nationality::class]); + + if (null !== $fields) { + $filter->setOptions(['fields' => $fields]); + } + + if (null !== $multiple) { + $filter->addFormOption('multiple', $multiple); + } + + return $filter; + } +}