From f9135dee88d222cb5afc434759efd31be8c0116e Mon Sep 17 00:00:00 2001 From: Martin Eiber Date: Fri, 13 Sep 2024 08:29:32 +0200 Subject: [PATCH 1/3] Add Tag Filter --- config/data_index_filters.yaml | 3 ++ doc/03_Grid.md | 16 ++++++++ src/DataIndex/Filter/TagFilter.php | 41 +++++++++++++++++++ src/DataIndex/Query/AssetQuery.php | 13 ++++++ src/DataIndex/Query/DataObjectQuery.php | 11 +++++ src/DataIndex/Query/QueryInterface.php | 5 +++ .../MappedParameter/FilterParameter.php | 30 +++++++++++++- src/Grid/Column/ColumnType.php | 1 + .../Filter/TagFilterParameter.php | 41 +++++++++++++++++++ .../Filter/TagFilterParameterInterface.php | 25 +++++++++++ 10 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 src/DataIndex/Filter/TagFilter.php create mode 100644 src/MappedParameter/Filter/TagFilterParameter.php create mode 100644 src/MappedParameter/Filter/TagFilterParameterInterface.php diff --git a/config/data_index_filters.yaml b/config/data_index_filters.yaml index ba82da464..53fdfc0b7 100644 --- a/config/data_index_filters.yaml +++ b/config/data_index_filters.yaml @@ -32,6 +32,9 @@ services: Pimcore\Bundle\StudioBackendBundle\DataIndex\Filter\PathFilter: tags: [ 'pimcore.studio_backend.open_search.filter' ] + Pimcore\Bundle\StudioBackendBundle\DataIndex\Filter\TagFilter: + 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 fafdf9582..d5621523d 100644 --- a/doc/03_Grid.md +++ b/doc/03_Grid.md @@ -40,6 +40,7 @@ Available filters are: | 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` | @@ -73,3 +74,18 @@ Filter by a date column: ] ... ``` + +Filter by Tags: +```json +... +"columnFilters" [ + { + "type": "system.tag", + "filterValue": { + "considerChildTags": true, + "tags": [1,2,3] + } + } +] +... +``` \ No newline at end of file diff --git a/src/DataIndex/Filter/TagFilter.php b/src/DataIndex/Filter/TagFilter.php new file mode 100644 index 000000000..b514798bb --- /dev/null +++ b/src/DataIndex/Filter/TagFilter.php @@ -0,0 +1,41 @@ +getTagFilter(); + + if (!$filter) { + return $query; + } + + return $query->filterTags($filter->getTags(), $filter->considerChildTags()); + } +} diff --git a/src/DataIndex/Query/AssetQuery.php b/src/DataIndex/Query/AssetQuery.php index c132f13db..94c227a2b 100644 --- a/src/DataIndex/Query/AssetQuery.php +++ b/src/DataIndex/Query/AssetQuery.php @@ -24,6 +24,7 @@ use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\FieldType\DateFilter; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Tree\ParentIdFilter; 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\FullTextSearch\WildcardSearch; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Sort\OrderByField; @@ -145,4 +146,16 @@ public function filterDatetime( return $this; } + + /** + * @param array $tags + */ + public function filterTags(array $tags, bool $considerChildTags): QueryInterface + { + $this->search->addModifier(new TagFilter($tags, $considerChildTags)); + + return $this; + } + + } diff --git a/src/DataIndex/Query/DataObjectQuery.php b/src/DataIndex/Query/DataObjectQuery.php index 778e9e709..877c8e3cc 100644 --- a/src/DataIndex/Query/DataObjectQuery.php +++ b/src/DataIndex/Query/DataObjectQuery.php @@ -23,6 +23,7 @@ use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Basic\IdsFilter; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Tree\ParentIdFilter; 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\Sort\Tree\OrderByFullPath; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Sort\Tree\OrderByIndexField; @@ -124,4 +125,14 @@ public function orderByIndex(): self return $this; } + + /** + * @param array $tags + */ + public function filterTags(array $tags, bool $considerChildTags): QueryInterface + { + $this->search->addModifier(new TagFilter($tags, $considerChildTags)); + + return $this; + } } diff --git a/src/DataIndex/Query/QueryInterface.php b/src/DataIndex/Query/QueryInterface.php index 8dec22655..6f9d5ad6b 100644 --- a/src/DataIndex/Query/QueryInterface.php +++ b/src/DataIndex/Query/QueryInterface.php @@ -37,4 +37,9 @@ public function getSearch(): SearchInterface; public function orderByPath(string $direction): self; public function searchByIds(array $ids): self; + + /** + * @param array $tags + */ + public function filterTags(array $tags, bool $considerChildTags): self; } diff --git a/src/Filter/MappedParameter/FilterParameter.php b/src/Filter/MappedParameter/FilterParameter.php index ae724c377..7b21ef8d1 100644 --- a/src/Filter/MappedParameter/FilterParameter.php +++ b/src/Filter/MappedParameter/FilterParameter.php @@ -17,6 +17,7 @@ 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; @@ -24,6 +25,8 @@ use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\PathParameterInterface; 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; /** * @internal @@ -33,7 +36,8 @@ final class FilterParameter implements ExcludeFolderParameterInterface, PathParameterInterface, ColumnFiltersParameterInterface, - SortFilterParameterInterface + SortFilterParameterInterface, + TagFilterParameterInterface { private ?string $path = null; @@ -101,6 +105,30 @@ public function getColumnFilterByType(string $type): iterable } } + public function getTagFilter(): ?TagFilterParameter + { + $columns = array_filter( + $this->columnFilters, + static fn ($columnFilter) => $columnFilter['type'] === ColumnType::SYSTEM_TAG->value + ); + + if (count($columns) < 1) { + throw new InvalidArgumentException('More than one tag filter is not allowed'); + } + + if (isset($columns[0]['filterValue'])) { + $filterValue = $columns[0]['filterValue']; + if (!isset($filterValue['tags'], $filterValue['considerChildTags'])) { + throw new InvalidArgumentException('Invalid tag filter'); + } + + return new TagFilterParameter($filterValue['tags'], $filterValue['considerChildTags']); + } + + return null; + } + + public function getFirstColumnFilterByType(string $type): ?ColumnFilter { $columns = iterator_to_array($this->getColumnFilterByType($type)); diff --git a/src/Grid/Column/ColumnType.php b/src/Grid/Column/ColumnType.php index 4ea8a8b1c..c38d59be0 100644 --- a/src/Grid/Column/ColumnType.php +++ b/src/Grid/Column/ColumnType.php @@ -25,6 +25,7 @@ enum ColumnType: string case SYSTEM_FILE_SIZE = 'system.fileSize'; case SYSTEM_INTEGER = 'system.integer'; case SYSTEM_DATETIME = 'system.datetime'; + case SYSTEM_TAG = 'system.tag'; case METADATA_SELECT = 'metadata.select'; case METADATA_INPUT = 'metadata.input'; case METADATA_DATE = 'metadata.date'; diff --git a/src/MappedParameter/Filter/TagFilterParameter.php b/src/MappedParameter/Filter/TagFilterParameter.php new file mode 100644 index 000000000..728895737 --- /dev/null +++ b/src/MappedParameter/Filter/TagFilterParameter.php @@ -0,0 +1,41 @@ + + */ + public function getTags(): array + { + return $this->tags; + } + + public function considerChildTags(): bool + { + return $this->considerChildTags; + } +} \ No newline at end of file diff --git a/src/MappedParameter/Filter/TagFilterParameterInterface.php b/src/MappedParameter/Filter/TagFilterParameterInterface.php new file mode 100644 index 000000000..d65be8577 --- /dev/null +++ b/src/MappedParameter/Filter/TagFilterParameterInterface.php @@ -0,0 +1,25 @@ + Date: Fri, 13 Sep 2024 08:39:07 +0200 Subject: [PATCH 2/3] Fix Filter check. --- src/Filter/MappedParameter/FilterParameter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Filter/MappedParameter/FilterParameter.php b/src/Filter/MappedParameter/FilterParameter.php index 7b21ef8d1..5eeb0b0ee 100644 --- a/src/Filter/MappedParameter/FilterParameter.php +++ b/src/Filter/MappedParameter/FilterParameter.php @@ -112,7 +112,7 @@ public function getTagFilter(): ?TagFilterParameter static fn ($columnFilter) => $columnFilter['type'] === ColumnType::SYSTEM_TAG->value ); - if (count($columns) < 1) { + if (count($columns) > 1) { throw new InvalidArgumentException('More than one tag filter is not allowed'); } From 908750a558da800e50d46ff817aaf36389a6a560 Mon Sep 17 00:00:00 2001 From: martineiber Date: Fri, 13 Sep 2024 06:45:54 +0000 Subject: [PATCH 3/3] Apply php-cs-fixer changes --- src/DataIndex/Query/AssetQuery.php | 2 -- src/Filter/MappedParameter/FilterParameter.php | 2 +- src/MappedParameter/Filter/TagFilterParameter.php | 15 ++++++++------- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/DataIndex/Query/AssetQuery.php b/src/DataIndex/Query/AssetQuery.php index 94c227a2b..e2964166e 100644 --- a/src/DataIndex/Query/AssetQuery.php +++ b/src/DataIndex/Query/AssetQuery.php @@ -156,6 +156,4 @@ public function filterTags(array $tags, bool $considerChildTags): QueryInterface return $this; } - - } diff --git a/src/Filter/MappedParameter/FilterParameter.php b/src/Filter/MappedParameter/FilterParameter.php index 5eeb0b0ee..f6ee69171 100644 --- a/src/Filter/MappedParameter/FilterParameter.php +++ b/src/Filter/MappedParameter/FilterParameter.php @@ -27,6 +27,7 @@ use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\SortFilterParameterInterface; use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\TagFilterParameter; use Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter\TagFilterParameterInterface; +use function count; /** * @internal @@ -128,7 +129,6 @@ public function getTagFilter(): ?TagFilterParameter return null; } - public function getFirstColumnFilterByType(string $type): ?ColumnFilter { $columns = iterator_to_array($this->getColumnFilterByType($type)); diff --git a/src/MappedParameter/Filter/TagFilterParameter.php b/src/MappedParameter/Filter/TagFilterParameter.php index 728895737..bd3686f85 100644 --- a/src/MappedParameter/Filter/TagFilterParameter.php +++ b/src/MappedParameter/Filter/TagFilterParameter.php @@ -4,14 +4,16 @@ /** * Pimcore * - * This source file is available under following license: + * This source file is available under two different licenses: + * - GNU General Public License version 3 (GPLv3) * - Pimcore Commercial License (PCL) + * Full copyright and license information is available in + * LICENSE.md which is distributed with this source code. * - * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org) - * @license http://www.pimcore.org/license PCL + * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org) + * @license http://www.pimcore.org/license GPLv3 and PCL */ - namespace Pimcore\Bundle\StudioBackendBundle\MappedParameter\Filter; /** @@ -22,8 +24,7 @@ public function __construct( private array $tags, private bool $considerChildTags - ) - { + ) { } /** @@ -38,4 +39,4 @@ public function considerChildTags(): bool { return $this->considerChildTags; } -} \ No newline at end of file +}