diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 84e11eddd2..e6d4d33183 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -34730,11 +34730,6 @@ parameters: count: 4 path: tests/integration/Core/Repository/LocationServiceTest.php - - - message: "#^Cannot call method fetchColumn\\(\\) on Doctrine\\\\DBAL\\\\ForwardCompatibility\\\\Result\\|int\\|string\\.$#" - count: 1 - path: tests/integration/Core/Repository/LocationServiceTest.php - - message: "#^Cannot call method getContentInfo\\(\\) on Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\Content\\\\Location\\|null\\.$#" count: 2 @@ -44685,11 +44680,6 @@ parameters: count: 1 path: tests/lib/FieldType/Url/Gateway/DoctrineStorageTest.php - - - message: "#^Cannot call method fetchAllAssociative\\(\\) on Doctrine\\\\DBAL\\\\ForwardCompatibility\\\\Result\\|int\\|string\\.$#" - count: 4 - path: tests/lib/FieldType/Url/Gateway/DoctrineStorageTest.php - - message: "#^Method Ibexa\\\\Tests\\\\Core\\\\FieldType\\\\Url\\\\Gateway\\\\DoctrineStorageTest\\:\\:testGetIdUrlMap\\(\\) has no return type specified\\.$#" count: 1 @@ -51545,11 +51535,6 @@ parameters: count: 1 path: tests/lib/Persistence/Legacy/Content/FieldValueConverterRegistryTest.php - - - message: "#^Cannot call method fetchColumn\\(\\) on Doctrine\\\\DBAL\\\\ForwardCompatibility\\\\Result\\|int\\|string\\.$#" - count: 5 - path: tests/lib/Persistence/Legacy/Content/Gateway/DoctrineDatabaseTest.php - - message: "#^Method Ibexa\\\\Tests\\\\Core\\\\Persistence\\\\Legacy\\\\Content\\\\Gateway\\\\DoctrineDatabaseTest\\:\\:assertContentVersionAttributesLanguages\\(\\) has parameter \\$expectation with no value type specified in iterable type array\\.$#" count: 1 @@ -52155,11 +52140,6 @@ parameters: count: 1 path: tests/lib/Persistence/Legacy/Content/Location/Gateway/DoctrineDatabaseTest.php - - - message: "#^Cannot call method fetchColumn\\(\\) on Doctrine\\\\DBAL\\\\ForwardCompatibility\\\\Result\\|int\\|string\\.$#" - count: 1 - path: tests/lib/Persistence/Legacy/Content/Location/Gateway/DoctrineDatabaseTest.php - - message: "#^Method Ibexa\\\\Tests\\\\Core\\\\Persistence\\\\Legacy\\\\Content\\\\Location\\\\Gateway\\\\DoctrineDatabaseTest\\:\\:assertLoadLocationProperties\\(\\) has parameter \\$locationData with no value type specified in iterable type array\\.$#" count: 1 @@ -54575,11 +54555,6 @@ parameters: count: 4 path: tests/lib/Persistence/Legacy/Content/UrlAlias/UrlAliasHandlerTest.php - - - message: "#^Cannot call method fetchColumn\\(\\) on Doctrine\\\\DBAL\\\\ForwardCompatibility\\\\Result\\|int\\|string\\.$#" - count: 1 - path: tests/lib/Persistence/Legacy/Content/UrlAlias/UrlAliasHandlerTest.php - - message: "#^Method Ibexa\\\\Tests\\\\Core\\\\Persistence\\\\Legacy\\\\Content\\\\UrlAlias\\\\UrlAliasHandlerTest\\:\\:assertVirtualUrlAliasValid\\(\\) has no return type specified\\.$#" count: 1 diff --git a/src/lib/Limitation/UserGroupLimitationType.php b/src/lib/Limitation/UserGroupLimitationType.php index 3f7eb1390f..0232e10ec9 100644 --- a/src/lib/Limitation/UserGroupLimitationType.php +++ b/src/lib/Limitation/UserGroupLimitationType.php @@ -7,6 +7,7 @@ namespace Ibexa\Core\Limitation; use Ibexa\Contracts\Core\Limitation\Type as SPILimitationTypeInterface; +use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException; use Ibexa\Contracts\Core\Repository\Exceptions\NotImplementedException; use Ibexa\Contracts\Core\Repository\Values\Content\Content; use Ibexa\Contracts\Core\Repository\Values\Content\ContentCreateStruct; @@ -190,10 +191,15 @@ public function getCriterion(APILimitationValue $value, APIUserReference $curren } $groupIds = []; - $currentUserLocations = $this->persistence->locationHandler()->loadLocationsByContent($currentUser->getUserId()); - if (!empty($currentUserLocations)) { - foreach ($currentUserLocations as $currentUserLocation) { - $groupIds[] = $currentUserLocation->parentId; + $locationHandler = $this->persistence->locationHandler(); + $currentUserLocations = $locationHandler->loadLocationsByContent($currentUser->getUserId()); + foreach ($currentUserLocations as $currentUserLocation) { + try { + $parentLocation = $locationHandler->load($currentUserLocation->parentId); + $groupIds[] = $parentLocation->contentId; + } catch (NotFoundException $e) { + // there is no need for any action - carrying on with checking other user locations + continue; } } diff --git a/tests/integration/Core/Limitation/UserGroupLimitationTest.php b/tests/integration/Core/Limitation/UserGroupLimitationTest.php new file mode 100644 index 0000000000..77e64f772c --- /dev/null +++ b/tests/integration/Core/Limitation/UserGroupLimitationTest.php @@ -0,0 +1,96 @@ +getRepository(); + + $user = $this->createUserWithPolicies('test_user', $this->getPermissions()); + $userGroups = $repository->getUserService()->loadUserGroupsOfUser($user); + $userGroupIds = []; + foreach ($userGroups as $userGroup) { + $userGroupIds[] = $userGroup->id; + } + + $repository->getPermissionResolver()->setCurrentUserReference($user); + + $parentFolder = $this->createFolder( + ['eng-US' => 'Parent folder'], + 2 + ); + $childFolder = $this->createFolder( + ['eng-US' => 'Child folder'], + $parentFolder->contentInfo->getMainLocationId() + ); + + $this->refreshSearch($repository); + + $query = new LocationQuery(); + $query->filter = new Criterion\LogicalAnd([ + new Criterion\ContentTypeId(self::FOLDER_CONTENT_TYPE_ID), + new Criterion\UserMetadata('group', 'in', $userGroupIds), + ]); + + $results = $repository->getSearchService()->findLocations($query)->searchHits; + $resultLocationIds = array_map(static function (SearchHit $hit): int { + /** @var \Ibexa\Contracts\Core\Repository\Values\Content\Location $location */ + $location = $hit->valueObject; + + return $location->id; + }, $results); + + self::assertContains($parentFolder->contentInfo->getMainLocationId(), $resultLocationIds); + self::assertContains($childFolder->contentInfo->getMainLocationId(), $resultLocationIds); + } + + /** + * @return array> + */ + private function getPermissions(): array + { + return [ + [ + 'module' => 'content', + 'function' => 'create', + ], + [ + 'module' => 'content', + 'function' => 'publish', + ], + [ + 'module' => 'content', + 'function' => 'read', + 'limitations' => [ + new LocationLimitation(['limitationValues' => [2]]), + ], + ], + [ + 'module' => 'content', + 'function' => 'read', + 'limitations' => [ + new ContentTypeLimitation(['limitationValues' => [self::FOLDER_CONTENT_TYPE_ID]]), + new UserGroupLimitation(['limitationValues' => [1]]), + ], + ], + ]; + } +}