Skip to content

Commit

Permalink
feat(attributes): AsFilter attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
vasilvestre committed Oct 22, 2024
1 parent d654fe3 commit 81ae79d
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 13 deletions.
18 changes: 5 additions & 13 deletions docs/custom_filter.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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;
}
}
```

Expand Down Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
13 changes: 13 additions & 0 deletions src/Bundle/DependencyInjection/SyliusGridExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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')
;
Expand Down
28 changes: 28 additions & 0 deletions src/Component/Metadata/AsFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Sylius\Component\Grid\Metadata;

#[\Attribute(\Attribute::TARGET_CLASS)]
final class AsFilter
{
/**
* @param string $formType The form type class name to use for filter rendering
* @param string|null $type The filter type (defaults to FQCN of the class)
*/
public function __construct(
public string $formType,
public ?string $type = null,
) {
}
}
6 changes: 6 additions & 0 deletions tests/Application/config/sylius/grids/book.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use App\Entity\Author;
use App\Entity\Book;
use App\Grid\Builder\AttributeNationalityFilter;
use App\Grid\Builder\NationalityFilter;
use Sylius\Bundle\GridBundle\Builder\Field\StringField;
use Sylius\Bundle\GridBundle\Builder\Filter\EntityFilter;
Expand All @@ -31,6 +32,11 @@
null,
['author.nationality'],
))
->addFilter(AttributeNationalityFilter::create(
AttributeNationalityFilter::class,
null,
['author.nationality'],
))
->addFilter(StringFilter::create(
'currencyCode',
['price.currencyCode'],
Expand Down
35 changes: 35 additions & 0 deletions tests/Application/src/Filter/AttributeNationalityFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace App\Filter;

use App\Grid\Type\NationalityFilterType;
use Sylius\Component\Grid\Data\DataSourceInterface;
use Sylius\Component\Grid\Filter\EntityFilter;
use Sylius\Component\Grid\Filtering\FilterInterface;
use Sylius\Component\Grid\Metadata\AsFilter;

#[AsFilter(
formType: NationalityFilterType::class,
)]
final class AttributeNationalityFilter implements FilterInterface
{
public function __construct(private EntityFilter $decorated)
{
}

public function apply(DataSourceInterface $dataSource, string $name, $data, array $options): void
{
$this->decorated->apply($dataSource, $name, $data, $options);
}
}
39 changes: 39 additions & 0 deletions tests/Application/src/Grid/Builder/AttributeNationalityFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace App\Grid\Builder;

use App\Entity\Nationality;
use App\Filter\AttributeNationalityFilter as GridNationalityFilter;
use Sylius\Bundle\GridBundle\Builder\Filter\Filter;
use Sylius\Bundle\GridBundle\Builder\Filter\FilterInterface;

final class AttributeNationalityFilter
{
public static function create(string $name, ?bool $multiple = null, ?array $fields = null): FilterInterface
{
$filter = Filter::create($name, GridNationalityFilter::class);

$filter->setFormOptions(['class' => Nationality::class]);

if (null !== $fields) {
$filter->setOptions(['fields' => $fields]);
}

if (null !== $multiple) {
$filter->addFormOption('multiple', $multiple);
}

return $filter;
}
}

0 comments on commit 81ae79d

Please sign in to comment.