Skip to content

Commit f9581ac

Browse files
authored
[Tree]: Add class ids modifier (#287)
* add modifier to filter by class ids * add test for new modifier * Apply php-cs-fixer changes --------- Co-authored-by: lukmzig <[email protected]>
1 parent e596e82 commit f9581ac

File tree

4 files changed

+115
-0
lines changed

4 files changed

+115
-0
lines changed

doc/04_Searching_For_Data_In_Index/05_Search_Modifiers/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ $search->addModifier(new ParentIdFilter(1))
2020
| [ExcludeFoldersFilter](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/Filter/Basic/ExcludeFoldersFilter.php) | Basic filters | Exclude folders from search result |
2121
| [ParentIdsFilter](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/Filter/Tree/ParentIdsFilter.php) | Tree related filters | Filter by parent ID |
2222
| [PathFilter](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/Filter/Tree/PathFilter.php) | Tree related filters | Filter by path (depending on use case for all levels or direct children only and with or without the parent item included) |
23+
| [ClassIdsFilter](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/Filter/Tree/ClassIdsFilter.php) | Tree related filters | Filter object items by class IDs (depending on use case the folders can be included in the result) |
2324
| [TagFilter](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/Filter/Tree/TagFilter.php) | Tree related filters | Filter by tag IDs (it is also possible to include child tags) |
2425
| [AssetMetaDataFilter](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/Filter/Asset/AssetMetaDataFilter.php) | Asset filters | Filter by asset meta data attribute. The format of the `$data` which needs to be passed depends on the type of the meta data attribute and is handled by its [field definition adapter](https://github.com/pimcore/generic-data-index-bundle/tree/1.x/src/SearchIndexAdapter/DefaultSearch/Asset/FieldDefinitionAdapter). |
2526
| [WorkspaceQuery](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/Filter/Workspaces/WorkspaceQuery.php) | Workspace related filters | Filter based on the user workspaces and permissions for a defined element type (this query is added to the asset/document/data object search by default) |
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
/**
5+
* Pimcore
6+
*
7+
* This source file is available under two different licenses:
8+
* - GNU General Public License version 3 (GPLv3)
9+
* - Pimcore Commercial License (PCL)
10+
* Full copyright and license information is available in
11+
* LICENSE.md which is distributed with this source code.
12+
*
13+
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
14+
* @license http://www.pimcore.org/license GPLv3 and PCL
15+
*/
16+
17+
namespace Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Tree;
18+
19+
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\SearchModifierInterface;
20+
21+
final readonly class ClassIdsFilter implements SearchModifierInterface
22+
{
23+
public function __construct(
24+
private array $classIds,
25+
private bool $includeFolders = false
26+
) {
27+
}
28+
29+
/**
30+
* @return string[]
31+
*/
32+
public function getClassIds(): array
33+
{
34+
return $this->classIds;
35+
}
36+
37+
public function includeFolders(): bool
38+
{
39+
return $this->includeFolders;
40+
}
41+
}

src/SearchIndexAdapter/DefaultSearch/Search/Modifier/Filter/TreeFilters.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
use Pimcore\Bundle\GenericDataIndexBundle\Model\DefaultSearch\Modifier\SearchModifierContextInterface;
2323
use Pimcore\Bundle\GenericDataIndexBundle\Model\DefaultSearch\Query\BoolQuery;
2424
use Pimcore\Bundle\GenericDataIndexBundle\Model\DefaultSearch\Query\TermFilter;
25+
use Pimcore\Bundle\GenericDataIndexBundle\Model\DefaultSearch\Query\TermsFilter;
26+
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Tree\ClassIdsFilter;
2527
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Tree\ParentIdFilter;
2628
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Tree\PathFilter;
2729
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Tree\TagFilter;
@@ -156,4 +158,35 @@ public function handleTagFilter(TagFilter $tagFilter, SearchModifierContextInter
156158
);
157159

158160
}
161+
162+
#[AsSearchModifierHandler]
163+
public function handleClassesFilter(
164+
ClassIdsFilter $classesFilter,
165+
SearchModifierContextInterface $context
166+
): void {
167+
if (empty($classesFilter->getClassIds())) {
168+
return;
169+
}
170+
171+
$query = new TermsFilter(
172+
field: SystemField::CLASS_NAME->getPath('keyword'),
173+
terms: $classesFilter->getClassIds()
174+
);
175+
176+
if ($classesFilter->includeFolders()) {
177+
$query = new BoolQuery([
178+
ConditionType::SHOULD->value => [
179+
new TermFilter(
180+
field: SystemField::TYPE->getPath(),
181+
term: 'folder'
182+
),
183+
$query,
184+
],
185+
]);
186+
}
187+
188+
$context->getSearch()->addQuery(
189+
new BoolQuery([ConditionType::MUST->value => [$query]])
190+
);
191+
}
159192
}

tests/Functional/Search/Modifier/Filter/TreeFiltersTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@
1616
namespace Pimcore\Bundle\GenericDataIndexBundle\Tests\Functional\Search\Modifier\Filter;
1717

1818
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Basic\ExcludeFoldersFilter;
19+
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Tree\ClassIdsFilter;
1920
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Tree\ParentIdFilter;
2021
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Tree\PathFilter;
2122
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Tree\TagFilter;
2223
use Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\Asset\AssetSearchServiceInterface;
24+
use Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\DataObject\DataObjectSearchServiceInterface;
2325
use Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\SearchProviderInterface;
2426
use Pimcore\Tests\Support\Util\TestHelper;
2527

@@ -194,6 +196,44 @@ public function testTagFilter(): void
194196
$this->assertEquals($asset->getId(), $searchResult->getIds()[0]);
195197
}
196198

199+
public function testClassIdsFilter(): void
200+
{
201+
$objects = TestHelper::createEmptyObjects(count: 2);
202+
$folder = TestHelper::createObjectFolder();
203+
204+
/** @var DataObjectSearchServiceInterface $searchService */
205+
$searchService = $this->tester->grabService('generic-data-index.test.service.data-object-search-service');
206+
/** @var SearchProviderInterface $searchProvider */
207+
$searchProvider = $this->tester->grabService(SearchProviderInterface::class);
208+
209+
$assetSearch = $searchProvider
210+
->createDataObjectSearch()
211+
->addModifier(new ClassIdsFilter([$objects[0]->getClassId()]));
212+
$searchResult = $searchService->search($assetSearch);
213+
214+
$this->assertCount(2, $searchResult->getIds());
215+
216+
$assetSearch = $searchProvider
217+
->createDataObjectSearch()
218+
->addModifier(new ClassIdsFilter([$objects[0]->getClassId()], true));
219+
$searchResult = $searchService->search($assetSearch);
220+
221+
$this->assertCount(3, $searchResult->getIds());
222+
223+
$assetSearch = $searchProvider
224+
->createDataObjectSearch()
225+
->addModifier(new ClassIdsFilter(['someNonExistingClass']));
226+
$searchResult = $searchService->search($assetSearch);
227+
228+
$this->assertEmpty($searchResult->getIds());
229+
$assetSearch = $searchProvider
230+
->createDataObjectSearch()
231+
->addModifier(new ClassIdsFilter(['someNonExistingClass'], true));
232+
$searchResult = $searchService->search($assetSearch);
233+
234+
$this->assertEquals([$folder->getId()], $searchResult->getIds());
235+
}
236+
197237
private function assertIdArrayEquals(array $ids1, array $ids2)
198238
{
199239
sort($ids1);

0 commit comments

Comments
 (0)