From 7b6a5c297be65414a393298385a16ef8e70e23a5 Mon Sep 17 00:00:00 2001 From: Martin Eiber Date: Thu, 19 Sep 2024 09:06:04 +0200 Subject: [PATCH 1/2] Add PQL Query Filter. --- config/data_index_filters.yaml | 3 ++ doc/03_Grid.md | 30 ++++++------ src/DataIndex/Adapter/AssetSearchAdapter.php | 6 ++- .../Adapter/AssetSearchAdapterInterface.php | 3 +- src/DataIndex/AssetSearchService.php | 3 +- src/DataIndex/AssetSearchServiceInterface.php | 3 +- src/DataIndex/Filter/PqlFilter.php | 49 +++++++++++++++++++ src/DataIndex/Filter/TagFilter.php | 15 ++++-- src/DataIndex/Grid/GridSearch.php | 3 +- src/DataIndex/Query/AssetQuery.php | 10 +++- src/DataIndex/Query/DataObjectQuery.php | 10 +++- src/DataIndex/Query/QueryInterface.php | 2 + .../MappedParameter/FilterParameter.php | 24 ++++----- src/Grid/Column/ColumnType.php | 1 + src/MappedParameter/Filter/ColumnFilter.php | 13 +---- ...erParameter.php => SimpleColumnFilter.php} | 17 +++---- ...SimpleColumnFiltersParameterInterface.php} | 7 ++- 17 files changed, 138 insertions(+), 61 deletions(-) create mode 100644 src/DataIndex/Filter/PqlFilter.php rename src/MappedParameter/Filter/{TagFilterParameter.php => SimpleColumnFilter.php} (67%) rename src/MappedParameter/Filter/{TagFilterParameterInterface.php => SimpleColumnFiltersParameterInterface.php} (73%) diff --git a/config/data_index_filters.yaml b/config/data_index_filters.yaml index 53fdfc0b7..f056e893a 100644 --- a/config/data_index_filters.yaml +++ b/config/data_index_filters.yaml @@ -35,6 +35,9 @@ services: Pimcore\Bundle\StudioBackendBundle\DataIndex\Filter\TagFilter: tags: [ 'pimcore.studio_backend.open_search.filter' ] + Pimcore\Bundle\StudioBackendBundle\DataIndex\Filter\PqlFilter: + tags: [ 'pimcore.studio_backend.open_search.filter' ] + # DataObject Pimcore\Bundle\StudioBackendBundle\DataIndex\Filter\DataObject\ClassNameFilter: tags: [ 'pimcore.studio_backend.open_search.data_object.filter' ] diff --git a/doc/03_Grid.md b/doc/03_Grid.md index d5621523d..ca02c8754 100644 --- a/doc/03_Grid.md +++ b/doc/03_Grid.md @@ -24,23 +24,25 @@ Here you can define `page`, `pageSize` and `includeDescendants`. ### ColumnFilter It is also possible to filter the data by a column. This is done by adding a `columnFilter` to the `filter` property. -A `columnFilter` has a reference to the column and the value you want to filter by. +A `columnFilter` has a reference to the column and the value you want to filter by. Some filters do not require a +specific column, like the `system.tag` filter. This filters will be applied to the general search query. Available filters are: -| Type | filterValue | Options | -|:-----------------:|:-------------------:|:---------------------------:| -| metadata.select | string | | -| metadata.date | object of timestamp | `from`, `to`, or `on` | -| metadata.input | string | | -| metadata.checkbox | boolean | | -| metadata.textarea | string | | -| metadata.object | integer | ID of the object | -| metadata.document | integer | ID fo the document | -| metadata.asset | integer | ID fo the asset | -| system.string | string | Wildcard search can be used | -| system.datetime | integer | `from`, `to`, or `on` | -| system.tag | object | `considerChildTags`, `tags` | +| Type | filterValue | Options | `key` required | +|:-----------------:|:-------------------:|:---------------------------:|:--------------:| +| metadata.select | string | | true | +| metadata.date | object of timestamp | `from`, `to`, or `on` | true | +| metadata.input | string | | true | +| metadata.checkbox | boolean | | true | +| metadata.textarea | string | | true | +| metadata.object | integer | ID of the object | true | +| metadata.document | integer | ID fo the document | true | +| metadata.asset | integer | ID fo the asset | true | +| system.string | string | Wildcard search can be used | true | +| system.datetime | integer | `from`, `to`, or `on` | true | +| system.tag | object | `considerChildTags`, `tags` | false | +| system.pql | string | PQL Query | false | diff --git a/src/DataIndex/Adapter/AssetSearchAdapter.php b/src/DataIndex/Adapter/AssetSearchAdapter.php index 0c4f0500f..f1bbb00e0 100644 --- a/src/DataIndex/Adapter/AssetSearchAdapter.php +++ b/src/DataIndex/Adapter/AssetSearchAdapter.php @@ -16,6 +16,7 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataIndex\Adapter; +use Exception; use Pimcore\Bundle\GenericDataIndexBundle\Exception\AssetSearchException; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Asset\AssetSearch; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Sort\Tree\OrderByFullPath; @@ -26,6 +27,7 @@ use Pimcore\Bundle\StudioBackendBundle\DataIndex\AssetSearchResult; use Pimcore\Bundle\StudioBackendBundle\DataIndex\Hydrator\HydratorServiceInterface; use Pimcore\Bundle\StudioBackendBundle\DataIndex\Query\QueryInterface; +use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\SearchException; use function sprintf; @@ -41,7 +43,7 @@ public function __construct( } /** - * @throws SearchException + * @throws SearchException|InvalidArgumentException */ public function searchAssets(QueryInterface $assetQuery): AssetSearchResult { @@ -49,6 +51,8 @@ public function searchAssets(QueryInterface $assetQuery): AssetSearchResult $searchResult = $this->searchService->search($assetQuery->getSearch()); } catch (AssetSearchException) { throw new SearchException('assets'); + } catch (Exception $e) { + throw new InvalidArgumentException($e->getMessage()); } $result = []; diff --git a/src/DataIndex/Adapter/AssetSearchAdapterInterface.php b/src/DataIndex/Adapter/AssetSearchAdapterInterface.php index bfb6557d1..2c42cfe17 100644 --- a/src/DataIndex/Adapter/AssetSearchAdapterInterface.php +++ b/src/DataIndex/Adapter/AssetSearchAdapterInterface.php @@ -20,13 +20,14 @@ use Pimcore\Bundle\StudioBackendBundle\Asset\Schema\Asset; use Pimcore\Bundle\StudioBackendBundle\DataIndex\AssetSearchResult; use Pimcore\Bundle\StudioBackendBundle\DataIndex\Query\QueryInterface; +use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\SearchException; interface AssetSearchAdapterInterface { /** - * @throws SearchException + * @throws SearchException|InvalidArgumentException */ public function searchAssets(QueryInterface $assetQuery): AssetSearchResult; diff --git a/src/DataIndex/AssetSearchService.php b/src/DataIndex/AssetSearchService.php index 1e46d9ac7..7f19d1d30 100644 --- a/src/DataIndex/AssetSearchService.php +++ b/src/DataIndex/AssetSearchService.php @@ -29,6 +29,7 @@ use Pimcore\Bundle\StudioBackendBundle\DataIndex\Adapter\AssetSearchAdapterInterface; use Pimcore\Bundle\StudioBackendBundle\DataIndex\Provider\AssetQueryProviderInterface; use Pimcore\Bundle\StudioBackendBundle\DataIndex\Query\QueryInterface; +use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\SearchException; use function count; @@ -42,7 +43,7 @@ public function __construct( } /** - * @throws SearchException + * @throws SearchException|InvalidArgumentException */ public function searchAssets(QueryInterface $assetQuery): AssetSearchResult { diff --git a/src/DataIndex/AssetSearchServiceInterface.php b/src/DataIndex/AssetSearchServiceInterface.php index 8d516e2bc..e26244cb5 100644 --- a/src/DataIndex/AssetSearchServiceInterface.php +++ b/src/DataIndex/AssetSearchServiceInterface.php @@ -27,13 +27,14 @@ use Pimcore\Bundle\StudioBackendBundle\Asset\Schema\Type\Unknown; use Pimcore\Bundle\StudioBackendBundle\Asset\Schema\Type\Video; use Pimcore\Bundle\StudioBackendBundle\DataIndex\Query\QueryInterface; +use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\SearchException; interface AssetSearchServiceInterface { /** - * @throws SearchException + * @throws SearchException|InvalidArgumentException */ public function searchAssets(QueryInterface $assetQuery): AssetSearchResult; diff --git a/src/DataIndex/Filter/PqlFilter.php b/src/DataIndex/Filter/PqlFilter.php new file mode 100644 index 000000000..0a8700ffc --- /dev/null +++ b/src/DataIndex/Filter/PqlFilter.php @@ -0,0 +1,49 @@ +getSimpleColumnFilterByType(ColumnType::SYSTEM_PQL_QUERY->value); + + if (!$filter) { + return $query; + } + + if (!is_string($filter->getFilterValue())) { + throw new InvalidArgumentException('Invalid PQL filter. Filter value must be a string.'); + } + + $filterValue = $filter->getFilterValue(); + + return $query->filterByPql($filterValue); + } +} diff --git a/src/DataIndex/Filter/TagFilter.php b/src/DataIndex/Filter/TagFilter.php index b514798bb..d125e37fc 100644 --- a/src/DataIndex/Filter/TagFilter.php +++ b/src/DataIndex/Filter/TagFilter.php @@ -17,6 +17,9 @@ namespace Pimcore\Bundle\StudioBackendBundle\DataIndex\Filter; use Pimcore\Bundle\StudioBackendBundle\DataIndex\Query\QueryInterface; +use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; +use Pimcore\Bundle\StudioBackendBundle\Grid\Column\ColumnType; +use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\SimpleColumnFiltersParameterInterface; use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\TagFilterParameterInterface; /** @@ -26,16 +29,22 @@ final class TagFilter implements FilterInterface { public function apply(mixed $parameters, QueryInterface $query): QueryInterface { - if (!$parameters instanceof TagFilterParameterInterface) { + if (!$parameters instanceof SimpleColumnFiltersParameterInterface) { return $query; } - $filter = $parameters->getTagFilter(); + $filter = $parameters->getSimpleColumnFilterByType(ColumnType::SYSTEM_TAG->value); if (!$filter) { return $query; } - return $query->filterTags($filter->getTags(), $filter->considerChildTags()); + $filterValue = $filter->getFilterValue(); + + if (!isset($filterValue['tags'], $filterValue['considerChildTags'])) { + throw new InvalidArgumentException('Invalid tag filter'); + } + + return $query->filterTags($filterValue['tags'], $filterValue['considerChildTags']); } } diff --git a/src/DataIndex/Grid/GridSearch.php b/src/DataIndex/Grid/GridSearch.php index 42420043d..e04967c8d 100644 --- a/src/DataIndex/Grid/GridSearch.php +++ b/src/DataIndex/Grid/GridSearch.php @@ -20,6 +20,7 @@ use Pimcore\Bundle\StudioBackendBundle\DataIndex\AssetSearchResult; use Pimcore\Bundle\StudioBackendBundle\DataIndex\AssetSearchServiceInterface; use Pimcore\Bundle\StudioBackendBundle\DataIndex\OpenSearchFilterInterface; +use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\NotFoundException; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\SearchException; use Pimcore\Bundle\StudioBackendBundle\Filter\Service\FilterServiceProviderInterface; @@ -39,7 +40,7 @@ public function __construct( } /** - * @throws NotFoundException|SearchException + * @throws NotFoundException|SearchException|InvalidArgumentException */ public function searchAssets(GridParameter $gridParameter): AssetSearchResult { diff --git a/src/DataIndex/Query/AssetQuery.php b/src/DataIndex/Query/AssetQuery.php index e2964166e..df97b3d65 100644 --- a/src/DataIndex/Query/AssetQuery.php +++ b/src/DataIndex/Query/AssetQuery.php @@ -27,6 +27,7 @@ use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Tree\TagFilter; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\FullTextSearch\ElementKeySearch; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\FullTextSearch\WildcardSearch; +use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\QueryLanguage\PqlFilter; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Sort\OrderByField; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Sort\Tree\OrderByFullPath; @@ -150,10 +151,17 @@ public function filterDatetime( /** * @param array $tags */ - public function filterTags(array $tags, bool $considerChildTags): QueryInterface + public function filterTags(array $tags, bool $considerChildTags): self { $this->search->addModifier(new TagFilter($tags, $considerChildTags)); return $this; } + + public function filterByPql(string $pqlQuery): self + { + $this->search->addModifier(new PqlFilter($pqlQuery)); + + return $this; + } } diff --git a/src/DataIndex/Query/DataObjectQuery.php b/src/DataIndex/Query/DataObjectQuery.php index 877c8e3cc..db3b11d9e 100644 --- a/src/DataIndex/Query/DataObjectQuery.php +++ b/src/DataIndex/Query/DataObjectQuery.php @@ -25,6 +25,7 @@ use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Tree\PathFilter; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Tree\TagFilter; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\FullTextSearch\ElementKeySearch; +use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\QueryLanguage\PqlFilter; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Sort\Tree\OrderByFullPath; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Sort\Tree\OrderByIndexField; use Pimcore\Bundle\StaticResolverBundle\Models\DataObject\ClassDefinitionResolverInterface; @@ -129,10 +130,17 @@ public function orderByIndex(): self /** * @param array $tags */ - public function filterTags(array $tags, bool $considerChildTags): QueryInterface + public function filterTags(array $tags, bool $considerChildTags): self { $this->search->addModifier(new TagFilter($tags, $considerChildTags)); return $this; } + + public function filterByPql(string $pqlQuery): self + { + $this->search->addModifier(new PqlFilter($pqlQuery)); + + return $this; + } } diff --git a/src/DataIndex/Query/QueryInterface.php b/src/DataIndex/Query/QueryInterface.php index 6f9d5ad6b..17e791058 100644 --- a/src/DataIndex/Query/QueryInterface.php +++ b/src/DataIndex/Query/QueryInterface.php @@ -42,4 +42,6 @@ public function searchByIds(array $ids): self; * @param array $tags */ public function filterTags(array $tags, bool $considerChildTags): self; + + public function filterByPql(string $pqlQuery): self; } diff --git a/src/Filter/MappedParameter/FilterParameter.php b/src/Filter/MappedParameter/FilterParameter.php index f6ee69171..c7f934823 100644 --- a/src/Filter/MappedParameter/FilterParameter.php +++ b/src/Filter/MappedParameter/FilterParameter.php @@ -17,16 +17,15 @@ namespace Pimcore\Bundle\StudioBackendBundle\Filter\MappedParameter; use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; -use Pimcore\Bundle\StudioBackendBundle\Grid\Column\ColumnType; use Pimcore\Bundle\StudioBackendBundle\MappedParameter\CollectionParametersInterface; use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\ColumnFilter; use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\ColumnFiltersParameterInterface; use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\ExcludeFolderParameterInterface; use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\PathParameterInterface; +use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\SimpleColumnFilter; +use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\SimpleColumnFiltersParameterInterface; use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\SortFilter; use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\SortFilterParameterInterface; -use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\TagFilterParameter; -use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\TagFilterParameterInterface; use function count; /** @@ -37,8 +36,8 @@ final class FilterParameter implements ExcludeFolderParameterInterface, PathParameterInterface, ColumnFiltersParameterInterface, - SortFilterParameterInterface, - TagFilterParameterInterface + SimpleColumnFiltersParameterInterface, + SortFilterParameterInterface { private ?string $path = null; @@ -106,24 +105,21 @@ public function getColumnFilterByType(string $type): iterable } } - public function getTagFilter(): ?TagFilterParameter + public function getSimpleColumnFilterByType(string $type): ?SimpleColumnFilter { $columns = array_filter( $this->columnFilters, - static fn ($columnFilter) => $columnFilter['type'] === ColumnType::SYSTEM_TAG->value + static fn ($columnFilter) => $columnFilter['type'] === $type ); if (count($columns) > 1) { - throw new InvalidArgumentException('More than one tag filter is not allowed'); + throw new InvalidArgumentException('More than one filter of same type is not allowed'); } - if (isset($columns[0]['filterValue'])) { - $filterValue = $columns[0]['filterValue']; - if (!isset($filterValue['tags'], $filterValue['considerChildTags'])) { - throw new InvalidArgumentException('Invalid tag filter'); - } + $column = reset($columns); - return new TagFilterParameter($filterValue['tags'], $filterValue['considerChildTags']); + if (isset($column['filterValue'])) { + return new SimpleColumnFilter($type, $column['filterValue']); } return null; diff --git a/src/Grid/Column/ColumnType.php b/src/Grid/Column/ColumnType.php index c38d59be0..78bbd53ec 100644 --- a/src/Grid/Column/ColumnType.php +++ b/src/Grid/Column/ColumnType.php @@ -26,6 +26,7 @@ enum ColumnType: string case SYSTEM_INTEGER = 'system.integer'; case SYSTEM_DATETIME = 'system.datetime'; case SYSTEM_TAG = 'system.tag'; + case SYSTEM_PQL_QUERY = 'system.pql'; case METADATA_SELECT = 'metadata.select'; case METADATA_INPUT = 'metadata.input'; case METADATA_DATE = 'metadata.date'; diff --git a/src/MappedParameter/Filter/ColumnFilter.php b/src/MappedParameter/Filter/ColumnFilter.php index ecd9ef2f9..c7f37f913 100644 --- a/src/MappedParameter/Filter/ColumnFilter.php +++ b/src/MappedParameter/Filter/ColumnFilter.php @@ -19,27 +19,18 @@ /** * @internal */ -final readonly class ColumnFilter +final readonly class ColumnFilter extends SimpleColumnFilter { public function __construct( private string $key, private string $type, private mixed $filterValue, ) { + parent::__construct($this->type, $this->filterValue); } public function getKey(): string { return $this->key; } - - public function getType(): string - { - return $this->type; - } - - public function getFilterValue(): mixed - { - return $this->filterValue; - } } diff --git a/src/MappedParameter/Filter/TagFilterParameter.php b/src/MappedParameter/Filter/SimpleColumnFilter.php similarity index 67% rename from src/MappedParameter/Filter/TagFilterParameter.php rename to src/MappedParameter/Filter/SimpleColumnFilter.php index bd3686f85..05ceea10c 100644 --- a/src/MappedParameter/Filter/TagFilterParameter.php +++ b/src/MappedParameter/Filter/SimpleColumnFilter.php @@ -19,24 +19,21 @@ /** * @internal */ -final readonly class TagFilterParameter +readonly class SimpleColumnFilter { public function __construct( - private array $tags, - private bool $considerChildTags + private string $type, + private mixed $filterValue, ) { } - /** - * @return array - */ - public function getTags(): array + public function getType(): string { - return $this->tags; + return $this->type; } - public function considerChildTags(): bool + public function getFilterValue(): mixed { - return $this->considerChildTags; + return $this->filterValue; } } diff --git a/src/MappedParameter/Filter/TagFilterParameterInterface.php b/src/MappedParameter/Filter/SimpleColumnFiltersParameterInterface.php similarity index 73% rename from src/MappedParameter/Filter/TagFilterParameterInterface.php rename to src/MappedParameter/Filter/SimpleColumnFiltersParameterInterface.php index d65be8577..16500fb3d 100644 --- a/src/MappedParameter/Filter/TagFilterParameterInterface.php +++ b/src/MappedParameter/Filter/SimpleColumnFiltersParameterInterface.php @@ -19,7 +19,10 @@ /** * @internal */ -interface TagFilterParameterInterface +interface SimpleColumnFiltersParameterInterface { - public function getTagFilter(): ?TagFilterParameter; + /** + * A column filter that does not require a key + */ + public function getSimpleColumnFilterByType(string $type): ?SimpleColumnFilter; } From d5f6d15525d8f78a3f5d9de9fbf5b7641e2bf351 Mon Sep 17 00:00:00 2001 From: martineiber Date: Thu, 19 Sep 2024 07:08:54 +0000 Subject: [PATCH 2/2] Apply php-cs-fixer changes --- src/DataIndex/Filter/PqlFilter.php | 1 + src/DataIndex/Filter/TagFilter.php | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataIndex/Filter/PqlFilter.php b/src/DataIndex/Filter/PqlFilter.php index 0a8700ffc..3432d204e 100644 --- a/src/DataIndex/Filter/PqlFilter.php +++ b/src/DataIndex/Filter/PqlFilter.php @@ -20,6 +20,7 @@ use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; use Pimcore\Bundle\StudioBackendBundle\Grid\Column\ColumnType; use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\SimpleColumnFiltersParameterInterface; +use function is_string; /** * @internal diff --git a/src/DataIndex/Filter/TagFilter.php b/src/DataIndex/Filter/TagFilter.php index d125e37fc..3e13c9d9c 100644 --- a/src/DataIndex/Filter/TagFilter.php +++ b/src/DataIndex/Filter/TagFilter.php @@ -20,7 +20,6 @@ use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidArgumentException; use Pimcore\Bundle\StudioBackendBundle\Grid\Column\ColumnType; use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\SimpleColumnFiltersParameterInterface; -use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\TagFilterParameterInterface; /** * @internal