diff --git a/src/lib/Search/Common/EventSubscriber/UserEventSubscriber.php b/src/lib/Search/Common/EventSubscriber/UserEventSubscriber.php index aea867b956..979e0313ae 100644 --- a/src/lib/Search/Common/EventSubscriber/UserEventSubscriber.php +++ b/src/lib/Search/Common/EventSubscriber/UserEventSubscriber.php @@ -6,11 +6,15 @@ */ namespace Ibexa\Core\Search\Common\EventSubscriber; +use Ibexa\Contracts\Core\Repository\Event\AfterEvent; +use Ibexa\Contracts\Core\Repository\Events\User\AssignUserToUserGroupEvent; +use Ibexa\Contracts\Core\Repository\Events\User\BeforeUnAssignUserFromUserGroupEvent; use Ibexa\Contracts\Core\Repository\Events\User\CreateUserEvent; use Ibexa\Contracts\Core\Repository\Events\User\CreateUserGroupEvent; use Ibexa\Contracts\Core\Repository\Events\User\DeleteUserEvent; use Ibexa\Contracts\Core\Repository\Events\User\DeleteUserGroupEvent; use Ibexa\Contracts\Core\Repository\Events\User\MoveUserGroupEvent; +use Ibexa\Contracts\Core\Repository\Events\User\UnAssignUserFromUserGroupEvent; use Ibexa\Contracts\Core\Repository\Events\User\UpdateUserEvent; use Ibexa\Contracts\Core\Repository\Events\User\UpdateUserGroupEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -27,6 +31,9 @@ public static function getSubscribedEvents(): array MoveUserGroupEvent::class => 'onMoveUserGroup', UpdateUserEvent::class => 'onUpdateUser', UpdateUserGroupEvent::class => 'onUpdateUserGroup', + AssignUserToUserGroupEvent::class => 'onAssignUserToUserGroup', + UnAssignUserFromUserGroupEvent::class => 'onUnAssignUserFromUserGroup', + BeforeUnAssignUserFromUserGroupEvent::class => 'onBeforeUnAssignUserFromUserGroup', ]; } @@ -144,6 +151,53 @@ public function onUpdateUserGroup(UpdateUserGroupEvent $event) $this->searchHandler->indexLocation($location); } } + + public function onAssignUserToUserGroup(AssignUserToUserGroupEvent $event): void + { + $this->indexUserContentWithLocation($event); + } + + public function onUnAssignUserFromUserGroup(UnAssignUserFromUserGroupEvent $event): void + { + $this->indexUserContentWithLocation($event); + } + + public function onBeforeUnAssignUserFromUserGroup(BeforeUnAssignUserFromUserGroupEvent $event): void + { + $userContentInfo = $this->persistenceHandler->contentHandler()->loadContentInfo( + $event->getUser()->id + ); + + $locations = $this->persistenceHandler->locationHandler()->loadLocationsByContent( + $userContentInfo->id + ); + + foreach ($locations as $location) { + $this->searchHandler->deleteLocation($location->id, $userContentInfo->id); + } + } + + private function indexUserContentWithLocation(AfterEvent $event): void + { + $userContentInfo = $this->persistenceHandler->contentHandler()->loadContentInfo( + $event->getUser()->id + ); + + $locations = $this->persistenceHandler->locationHandler()->loadLocationsByContent( + $userContentInfo->id + ); + + $this->searchHandler->indexContent( + $this->persistenceHandler->contentHandler()->load( + $userContentInfo->id, + $userContentInfo->currentVersionNo + ) + ); + + foreach ($locations as $location) { + $this->searchHandler->indexLocation($location); + } + } } class_alias(UserEventSubscriber::class, 'eZ\Publish\Core\Search\Common\EventSubscriber\UserEventSubscriber'); diff --git a/tests/integration/Core/Repository/UserServiceTest.php b/tests/integration/Core/Repository/UserServiceTest.php index 7408ed6ffb..633125669b 100644 --- a/tests/integration/Core/Repository/UserServiceTest.php +++ b/tests/integration/Core/Repository/UserServiceTest.php @@ -2260,6 +2260,39 @@ public function testAssignUserToUserGroupThrowsInvalidArgumentException() /* END: Use Case */ } + /** + * @covers \Ibexa\Contracts\Core\Repository\UserService::assignUserToUserGroup + */ + public function testAssignUserToGroupWithLocationsValidation(): void + { + $repository = $this->getRepository(); + $userService = $repository->getUserService(); + $locationService = $repository->getLocationService(); + + $administratorGroupId = $this->generateId('group', 12); + + $user = $this->createUserVersion1(); + + $group = $userService->loadUserGroup($administratorGroupId); + $groupLocation = $locationService->loadLocation($group->contentInfo->mainLocationId); + + // Count number of child locations before assigning user to group + $count = $locationService->getLocationChildCount($groupLocation); + $expectedCount = $count + 1; + + $userService->assignUserToUserGroup( + $user, + $group + ); + + $this->refreshSearch($repository); + + // Count number of child locations after assigning the user to a group + $actualCount = $locationService->getLocationChildCount($groupLocation); + + self::assertEquals($expectedCount, $actualCount); + } + /** * Test for the unAssignUssrFromUserGroup() method. * @@ -2357,6 +2390,48 @@ public function testUnAssignUserFromUserGroupThrowsBadStateArgumentException() /* END: Use Case */ } + /** + * @covers \Ibexa\Contracts\Core\Repository\UserService::unAssignUserFromUserGroup + */ + public function testUnAssignUserToGroupWithLocationValidation(): void + { + $repository = $this->getRepository(); + $userService = $repository->getUserService(); + $locationService = $repository->getLocationService(); + + $editorsGroupId = $this->generateId('group', 13); + $anonymousGroupId = $this->generateId('group', 42); + + $user = $this->createUserVersion1(); + + $this->refreshSearch($repository); + + $group = $userService->loadUserGroup($editorsGroupId); + $groupLocation = $locationService->loadLocation($group->contentInfo->mainLocationId); + + // Count number of child locations before unassigning the user from a group + $count = $locationService->getLocationChildCount($groupLocation); + $expectedCount = $count - 1; + + // Assigning user to a different group to avoid removing all groups from the user + $userService->assignUserToUserGroup( + $user, + $userService->loadUserGroup($anonymousGroupId) + ); + + $userService->unAssignUserFromUserGroup( + $user, + $userService->loadUserGroup($editorsGroupId) + ); + + $this->refreshSearch($repository); + + // Count number of child locations after unassigning the user from a group + $actualCount = $locationService->getLocationChildCount($groupLocation); + + self::assertEquals($expectedCount, $actualCount); + } + /** * Test that multi-language logic for the loadUserGroup method respects prioritized language list. *