diff --git a/eZ/Publish/API/Repository/Tests/Filtering/ContentFilteringTest.php b/eZ/Publish/API/Repository/Tests/Filtering/ContentFilteringTest.php index 2bcfe4b361..36d4b3a015 100644 --- a/eZ/Publish/API/Repository/Tests/Filtering/ContentFilteringTest.php +++ b/eZ/Publish/API/Repository/Tests/Filtering/ContentFilteringTest.php @@ -12,11 +12,14 @@ use function count; use eZ\Publish\API\Repository\Values\Content\Content; use eZ\Publish\API\Repository\Values\Content\ContentList; +use eZ\Publish\API\Repository\Values\Content\Location; use eZ\Publish\API\Repository\Values\Content\Query; use eZ\Publish\API\Repository\Values\Content\Query\Criterion; use eZ\Publish\API\Repository\Values\Content\Query\SortClause; use eZ\Publish\API\Repository\Values\Content\Search\SearchHit; use eZ\Publish\API\Repository\Values\Filter\Filter; +use eZ\Publish\API\Repository\Values\ObjectState\ObjectStateCreateStruct; +use eZ\Publish\API\Repository\Values\ObjectState\ObjectStateGroupCreateStruct; use eZ\Publish\Core\FieldType\Keyword; use eZ\Publish\SPI\Repository\Values\Filter\FilteringSortClause; use IteratorAggregate; @@ -332,6 +335,75 @@ private function performAndAssertSimpleSortClauseQuery(FilteringSortClause $sort self::assertSame(57, $contentList->getIterator()[0]->id); } + /** + * @throws \eZ\Publish\API\Repository\Exceptions\Exception + */ + public function testObjectStateIdCriterionOnMultipleObjectStates(): void + { + $contentService = $this->getRepository()->getContentService(); + $contentTypeService = $this->getRepository()->getContentTypeService(); + $locationService = $this->getRepository()->getLocationService(); + $objectStateService = $this->getRepository()->getObjectStateService(); + + // Create additional Object States + $objectStateGroupStruct = new ObjectStateGroupCreateStruct(); + $objectStateGroupStruct->identifier = 'domain'; + $objectStateGroupStruct->names = ['eng-GB' => 'Domain']; + $objectStateGroupStruct->defaultLanguageCode = 'eng-GB'; + $objectStateGroup = $objectStateService->createObjectStateGroup($objectStateGroupStruct); + + $objectStateCreateStruct = new ObjectStateCreateStruct(); + $objectStateCreateStruct->identifier = 'public'; + $objectStateCreateStruct->names = ['eng-GB' => 'Public']; + $objectStateCreateStruct->defaultLanguageCode = 'eng-GB'; + $objectStateService->createObjectState($objectStateGroup, $objectStateCreateStruct); + + $objectStateCreateStruct->identifier = 'private'; + $objectStateCreateStruct->names = ['eng-GB' => 'Private']; + $objectStatePrivate = $objectStateService->createObjectState($objectStateGroup, $objectStateCreateStruct); + + // Create a new content object and assign object state "Private" to it: + $contentCreate = $contentService->newContentCreateStruct( + $contentTypeService->loadContentTypeByIdentifier('folder'), + 'eng-GB' + ); + $contentCreate->setField('name', 'Private Folder'); + $content = $contentService->createContent( + $contentCreate, + [$locationService->newLocationCreateStruct(2)] + ); + $contentService->publishVersion( + $content->getVersionInfo() + ); + $objectStateService->setContentState( + $content->getVersionInfo()->getContentInfo(), + $objectStateGroup, + $objectStatePrivate + ); + + $filter = new Filter(); + $filter + ->withCriterion(new Criterion\LogicalAnd([ + new Criterion\ParentLocationId(2), + new Criterion\LogicalAnd([ + new Criterion\ObjectStateId(1), + new Criterion\ObjectStateId($objectStatePrivate->id), + ]), + ])); + + $results = $this->find($filter); + + self::assertEquals( + 1, + $results->getTotalCount(), + 'Expected to find only one object which has state "not_locked" and "private"' + ); + + foreach ($results as $result) { + self::assertEquals($result->id, $content->id, 'Expected to find "Private Folder"'); + } + } + public function getListOfSupportedSortClauses(): iterable { yield 'Content\\Id' => [SortClause\ContentId::class]; diff --git a/eZ/Publish/Core/Persistence/Legacy/Filter/CriterionQueryBuilder/Content/ObjectStateIdQueryBuilder.php b/eZ/Publish/Core/Persistence/Legacy/Filter/CriterionQueryBuilder/Content/ObjectStateIdQueryBuilder.php index fcb0f5821d..a189f42847 100644 --- a/eZ/Publish/Core/Persistence/Legacy/Filter/CriterionQueryBuilder/Content/ObjectStateIdQueryBuilder.php +++ b/eZ/Publish/Core/Persistence/Legacy/Filter/CriterionQueryBuilder/Content/ObjectStateIdQueryBuilder.php @@ -29,19 +29,21 @@ public function buildQueryConstraint( FilteringQueryBuilder $queryBuilder, FilteringCriterion $criterion ): ?string { + $tableAlias = uniqid('osl_'); + /** @var \eZ\Publish\API\Repository\Values\Content\Query\Criterion\ObjectStateId $criterion */ $queryBuilder - ->joinOnce( + ->join( 'content', Gateway::OBJECT_STATE_LINK_TABLE, - 'object_state_link', - 'content.id = object_state_link.contentobject_id', + $tableAlias, + 'content.id = ' . $tableAlias . '.contentobject_id', ); $value = (array)$criterion->value; return $queryBuilder->expr()->in( - 'object_state_link.contentobject_state_id', + $tableAlias . '.contentobject_state_id', $queryBuilder->createNamedParameter($value, Connection::PARAM_INT_ARRAY) ); }