diff --git a/src/Application/Regulation/Command/DeleteRegulationCommand.php b/src/Application/Regulation/Command/DeleteRegulationCommand.php index 3be85e1c5..26dd1c64f 100644 --- a/src/Application/Regulation/Command/DeleteRegulationCommand.php +++ b/src/Application/Regulation/Command/DeleteRegulationCommand.php @@ -10,7 +10,7 @@ final class DeleteRegulationCommand implements CommandInterface { public function __construct( - public readonly array $organizationUserUuids, + public readonly array $userOrganizationUuids, public readonly RegulationOrderRecord $regulationOrderRecord, ) { } diff --git a/src/Application/Regulation/Command/DeleteRegulationCommandHandler.php b/src/Application/Regulation/Command/DeleteRegulationCommandHandler.php index 585e95e58..950a04adb 100644 --- a/src/Application/Regulation/Command/DeleteRegulationCommandHandler.php +++ b/src/Application/Regulation/Command/DeleteRegulationCommandHandler.php @@ -20,7 +20,7 @@ public function __invoke(DeleteRegulationCommand $command): void { $regulationOrderRecord = $command->regulationOrderRecord; - if (false === $this->canOrganizationAccessToRegulation->isSatisfiedBy($regulationOrderRecord, $command->organizationUserUuids)) { + if (false === $this->canOrganizationAccessToRegulation->isSatisfiedBy($regulationOrderRecord, $command->userOrganizationUuids)) { throw new RegulationOrderRecordCannotBeDeletedException(); } diff --git a/src/Application/User/Command/DeleteOrganizationUserCommandHandler.php b/src/Application/User/Command/DeleteOrganizationUserCommandHandler.php index c8b3144eb..5fa719401 100644 --- a/src/Application/User/Command/DeleteOrganizationUserCommandHandler.php +++ b/src/Application/User/Command/DeleteOrganizationUserCommandHandler.php @@ -18,13 +18,13 @@ public function __construct( public function __invoke(DeleteOrganizationUserCommand $command): void { $user = $command->organizationUser->getUser(); - $organizationUsers = $this->organizationUserRepository->findOrganizationsByUser($user); + $userOrganizations = $this->organizationUserRepository->findByUserUuid($user->getUuid()); - if (\count($organizationUsers) === 1) { - // User belongs to only one organization, he is totaly removed + if (\count($userOrganizations) === 1) { + // User belongs to only one organization, remove them and the organization user will be deleted too by CASCADE $this->userRepository->remove($user); } else { - // User belongs to several organizations, he is removed from the organization + // User belongs to several organizations, remove only their presence in this organization $this->organizationUserRepository->remove($command->organizationUser); } } diff --git a/src/Application/User/Query/GetOrganizationUsersQueryHandler.php b/src/Application/User/Query/GetOrganizationUsersQueryHandler.php index 12ae6a923..65b2f83aa 100644 --- a/src/Application/User/Query/GetOrganizationUsersQueryHandler.php +++ b/src/Application/User/Query/GetOrganizationUsersQueryHandler.php @@ -15,6 +15,6 @@ public function __construct( public function __invoke(GetOrganizationUsersQuery $query): array { - return $this->organizationUserRepository->findUsersByOrganizationUuid($query->organizationUuid); + return $this->organizationUserRepository->findByOrganizationUuid($query->organizationUuid); } } diff --git a/src/Application/User/View/UserView.php b/src/Application/User/View/OrganizationUserView.php similarity index 85% rename from src/Application/User/View/UserView.php rename to src/Application/User/View/OrganizationUserView.php index e33ef0403..53be87f37 100644 --- a/src/Application/User/View/UserView.php +++ b/src/Application/User/View/OrganizationUserView.php @@ -4,7 +4,7 @@ namespace App\Application\User\View; -final readonly class UserView +final readonly class OrganizationUserView { public function __construct( public string $uuid, diff --git a/src/Application/User/View/OrganizationView.php b/src/Application/User/View/UserOrganizationView.php similarity index 83% rename from src/Application/User/View/OrganizationView.php rename to src/Application/User/View/UserOrganizationView.php index 575ee29b9..d78a79755 100644 --- a/src/Application/User/View/OrganizationView.php +++ b/src/Application/User/View/UserOrganizationView.php @@ -4,7 +4,7 @@ namespace App\Application\User\View; -final readonly class OrganizationView +final readonly class UserOrganizationView { public function __construct( public string $uuid, diff --git a/src/Domain/Regulation/Specification/CanOrganizationAccessToRegulation.php b/src/Domain/Regulation/Specification/CanOrganizationAccessToRegulation.php index 097e5cc7a..79ab16b0c 100644 --- a/src/Domain/Regulation/Specification/CanOrganizationAccessToRegulation.php +++ b/src/Domain/Regulation/Specification/CanOrganizationAccessToRegulation.php @@ -10,12 +10,12 @@ class CanOrganizationAccessToRegulation { public function isSatisfiedBy( OrganizationRegulationAccessInterface|string $organizationUuid, - array $organizationUserUuids, + array $organizationUuids, ): bool { if (!\is_string($organizationUuid)) { $organizationUuid = $organizationUuid->getOrganizationUuid(); } - return \in_array($organizationUuid, $organizationUserUuids); + return \in_array($organizationUuid, $organizationUuids); } } diff --git a/src/Domain/User/Repository/OrganizationUserRepositoryInterface.php b/src/Domain/User/Repository/OrganizationUserRepositoryInterface.php index 8813e4e91..c17f0f6da 100644 --- a/src/Domain/User/Repository/OrganizationUserRepositoryInterface.php +++ b/src/Domain/User/Repository/OrganizationUserRepositoryInterface.php @@ -4,8 +4,9 @@ namespace App\Domain\User\Repository; +use App\Application\User\View\OrganizationUserView; +use App\Application\User\View\UserOrganizationView; use App\Domain\User\OrganizationUser; -use App\Domain\User\User; interface OrganizationUserRepositoryInterface { @@ -13,9 +14,11 @@ public function add(OrganizationUser $organizationUser): void; public function remove(OrganizationUser $organizationUser): void; - public function findOrganizationsByUser(User $user): array; + /** @return UserOrganizationView[] */ + public function findByUserUuid(string $userUuid): array; - public function findUsersByOrganizationUuid(string $uuid): array; + /** @return OrganizationUserView[] */ + public function findByOrganizationUuid(string $uuid): array; public function findOrganizationUser(string $organizationUuid, string $userUuid): ?OrganizationUser; diff --git a/src/Domain/User/Specification/CanUserEditOrganization.php b/src/Domain/User/Specification/CanUserEditOrganization.php index bbf6d80de..fca1b52db 100644 --- a/src/Domain/User/Specification/CanUserEditOrganization.php +++ b/src/Domain/User/Specification/CanUserEditOrganization.php @@ -12,12 +12,12 @@ class CanUserEditOrganization { public function isSatisfiedBy(Organization $organization, SymfonyUser $user): bool { - foreach ($user->getOrganizationUsers() as $organizationUser) { - if ($organizationUser->uuid !== $organization->getUuid()) { + foreach ($user->getUserOrganizations() as $userOrganization) { + if ($userOrganization->uuid !== $organization->getUuid()) { continue; } - return \in_array(OrganizationRolesEnum::ROLE_ORGA_ADMIN->value, $organizationUser->roles); + return \in_array(OrganizationRolesEnum::ROLE_ORGA_ADMIN->value, $userOrganization->roles); } return false; diff --git a/src/Domain/User/Specification/CanUserPublishRegulation.php b/src/Domain/User/Specification/CanUserPublishRegulation.php index d2d6c04fd..7776f2c53 100644 --- a/src/Domain/User/Specification/CanUserPublishRegulation.php +++ b/src/Domain/User/Specification/CanUserPublishRegulation.php @@ -14,7 +14,7 @@ public function isSatisfiedBy(RegulationOrderRecord $regulationOrderRecord, Symf { $organization = $regulationOrderRecord->getOrganization(); - foreach ($user->getOrganizationUsers() as $userOrganization) { + foreach ($user->getUserOrganizations() as $userOrganization) { if ($userOrganization->uuid !== $organization->getUuid()) { continue; } diff --git a/src/Domain/User/Specification/CanUserViewOrganization.php b/src/Domain/User/Specification/CanUserViewOrganization.php index 63823a93f..7d1bdc68a 100644 --- a/src/Domain/User/Specification/CanUserViewOrganization.php +++ b/src/Domain/User/Specification/CanUserViewOrganization.php @@ -11,6 +11,6 @@ class CanUserViewOrganization { public function isSatisfiedBy(Organization $organization, SymfonyUser $user): bool { - return \in_array($organization->getUuid(), $user->getOrganizationUuids()); + return \in_array($organization->getUuid(), $user->getUserOrganizationUuids()); } } diff --git a/src/Infrastructure/Controller/Organization/ListOrganizationsController.php b/src/Infrastructure/Controller/Organization/ListOrganizationsController.php index 140308651..d6dfadcc5 100644 --- a/src/Infrastructure/Controller/Organization/ListOrganizationsController.php +++ b/src/Infrastructure/Controller/Organization/ListOrganizationsController.php @@ -30,7 +30,7 @@ public function __invoke(): Response return new Response($this->twig->render( name: 'organization/index.html.twig', context: [ - 'organizations' => $user->getOrganizationUsers(), + 'organizations' => $user->getUserOrganizations(), ], )); } diff --git a/src/Infrastructure/Controller/Regulation/AbstractRegulationController.php b/src/Infrastructure/Controller/Regulation/AbstractRegulationController.php index 55add1287..5f8b28642 100644 --- a/src/Infrastructure/Controller/Regulation/AbstractRegulationController.php +++ b/src/Infrastructure/Controller/Regulation/AbstractRegulationController.php @@ -41,7 +41,7 @@ protected function getRegulationOrderRecordUsing(callable $func, bool $requireUs /** @var SymfonyUser|null */ $user = $this->security->getUser(); - if (!$user || !$this->canOrganizationAccessToRegulation->isSatisfiedBy($regulationOrderRecord, $user->getOrganizationUuids())) { + if (!$user || !$this->canOrganizationAccessToRegulation->isSatisfiedBy($regulationOrderRecord, $user->getUserOrganizationUuids())) { throw new AccessDeniedHttpException(); } } diff --git a/src/Infrastructure/Controller/Regulation/AddRegulationController.php b/src/Infrastructure/Controller/Regulation/AddRegulationController.php index 3125f9257..c17004735 100644 --- a/src/Infrastructure/Controller/Regulation/AddRegulationController.php +++ b/src/Infrastructure/Controller/Regulation/AddRegulationController.php @@ -44,7 +44,7 @@ public function __invoke(Request $request): Response type: GeneralInfoFormType::class, data: $command, options: [ - 'organizations' => $user->getOrganizationUsers(), + 'organizations' => $user->getUserOrganizations(), 'action' => $this->router->generate('app_regulation_add'), 'save_options' => [ 'label' => 'common.form.continue', diff --git a/src/Infrastructure/Controller/Regulation/DeleteRegulationController.php b/src/Infrastructure/Controller/Regulation/DeleteRegulationController.php index 737cb0eba..df51b712f 100644 --- a/src/Infrastructure/Controller/Regulation/DeleteRegulationController.php +++ b/src/Infrastructure/Controller/Regulation/DeleteRegulationController.php @@ -64,7 +64,7 @@ public function __invoke(Request $request, string $uuid): Response } try { - $this->commandBus->handle(new DeleteRegulationCommand($user->getOrganizationUuids(), $regulationOrderRecord)); + $this->commandBus->handle(new DeleteRegulationCommand($user->getUserOrganizationUuids(), $regulationOrderRecord)); } catch (RegulationOrderRecordCannotBeDeletedException) { throw new AccessDeniedHttpException(); } diff --git a/src/Infrastructure/Controller/Regulation/Fragments/GetMeasureController.php b/src/Infrastructure/Controller/Regulation/Fragments/GetMeasureController.php index e330cb23d..aa0629c70 100644 --- a/src/Infrastructure/Controller/Regulation/Fragments/GetMeasureController.php +++ b/src/Infrastructure/Controller/Regulation/Fragments/GetMeasureController.php @@ -68,7 +68,7 @@ public function __invoke(string $regulationOrderRecordUuid, string $uuid): Respo context: [ 'measure' => MeasureView::fromEntity($measure), 'generalInfo' => $generalInfo, - 'isReadOnly' => !$this->canOrganizationAccessToRegulation->isSatisfiedBy($regulationOrderRecord, $currentUser->getOrganizationUuids()), + 'isReadOnly' => !$this->canOrganizationAccessToRegulation->isSatisfiedBy($regulationOrderRecord, $currentUser->getUserOrganizationUuids()), 'canDelete' => $this->canDeleteMeasures->isSatisfiedBy($regulationOrderRecord), ], ), diff --git a/src/Infrastructure/Controller/Regulation/Fragments/SaveGeneralInfoController.php b/src/Infrastructure/Controller/Regulation/Fragments/SaveGeneralInfoController.php index 7e6c52958..7549d96cf 100644 --- a/src/Infrastructure/Controller/Regulation/Fragments/SaveGeneralInfoController.php +++ b/src/Infrastructure/Controller/Regulation/Fragments/SaveGeneralInfoController.php @@ -50,7 +50,7 @@ public function __invoke(Request $request, string $uuid): Response type: GeneralInfoFormType::class, data: $command, options: [ - 'organizations' => $user->getOrganizationUsers(), + 'organizations' => $user->getUserOrganizations(), 'action' => $this->router->generate('fragment_regulations_general_info_form', ['uuid' => $uuid]), 'save_options' => [ 'label' => 'common.form.validate', diff --git a/src/Infrastructure/Controller/Regulation/ListRegulationsController.php b/src/Infrastructure/Controller/Regulation/ListRegulationsController.php index 8fdcfac5a..99c32fd4c 100644 --- a/src/Infrastructure/Controller/Regulation/ListRegulationsController.php +++ b/src/Infrastructure/Controller/Regulation/ListRegulationsController.php @@ -43,13 +43,13 @@ public function __invoke(Request $request): Response ); } - $organizationUserUuids = $user?->getOrganizationUuids(); + $userOrganizationUuids = $user?->getUserOrganizationUuids(); $regulations = $this->queryBus->handle( new GetRegulationsQuery( pageSize: $pageSize, page: $page, - organizationUuids: $organizationUserUuids, + organizationUuids: $userOrganizationUuids, ), ); diff --git a/src/Infrastructure/Controller/Regulation/RegulationDetailController.php b/src/Infrastructure/Controller/Regulation/RegulationDetailController.php index b04c6fbec..56ff72e63 100644 --- a/src/Infrastructure/Controller/Regulation/RegulationDetailController.php +++ b/src/Infrastructure/Controller/Regulation/RegulationDetailController.php @@ -57,7 +57,7 @@ public function __invoke(string $uuid): Response $regulationOrderRecord = $this->getRegulationOrderRecord($uuid, requireUserSameOrg: false); $organizationUuid = $regulationOrderRecord->getOrganizationUuid(); $measures = $this->queryBus->handle(new GetMeasuresQuery($uuid)); - $isReadOnly = !($currentUser && $this->canOrganizationAccessToRegulation->isSatisfiedBy($organizationUuid, $currentUser->getOrganizationUuids())); + $isReadOnly = !($currentUser && $this->canOrganizationAccessToRegulation->isSatisfiedBy($organizationUuid, $currentUser->getUserOrganizationUuids())); $context = [ 'uuid' => $uuid, diff --git a/src/Infrastructure/Form/Regulation/GeneralInfoFormType.php b/src/Infrastructure/Form/Regulation/GeneralInfoFormType.php index f5747f586..51979490b 100644 --- a/src/Infrastructure/Form/Regulation/GeneralInfoFormType.php +++ b/src/Infrastructure/Form/Regulation/GeneralInfoFormType.php @@ -4,7 +4,7 @@ namespace App\Infrastructure\Form\Regulation; -use App\Application\User\View\OrganizationView; +use App\Application\User\View\UserOrganizationView; use App\Domain\Regulation\Enum\RegulationOrderCategoryEnum; use App\Domain\User\Organization; use Doctrine\ORM\EntityManagerInterface; @@ -102,13 +102,13 @@ public function buildForm(FormBuilderInterface $builder, array $options): void $builder->get('organization') ->addModelTransformer(new CallbackTransformer( - function (?Organization $organization = null): ?OrganizationView { + function (?Organization $organization = null): ?UserOrganizationView { return $organization - ? new OrganizationView($organization->getUuid(), $organization->getName()) + ? new UserOrganizationView($organization->getUuid(), $organization->getName()) : null; }, - function (OrganizationView $organizationView): Organization { - return $this->entityManager->getReference(Organization::class, $organizationView->uuid); + function (UserOrganizationView $view): Organization { + return $this->entityManager->getReference(Organization::class, $view->uuid); }, )) ; diff --git a/src/Infrastructure/Persistence/Doctrine/Repository/User/OrganizationUserRepository.php b/src/Infrastructure/Persistence/Doctrine/Repository/User/OrganizationUserRepository.php index 7f901e6f7..733d24b5c 100644 --- a/src/Infrastructure/Persistence/Doctrine/Repository/User/OrganizationUserRepository.php +++ b/src/Infrastructure/Persistence/Doctrine/Repository/User/OrganizationUserRepository.php @@ -4,11 +4,10 @@ namespace App\Infrastructure\Persistence\Doctrine\Repository\User; -use App\Application\User\View\OrganizationView; -use App\Application\User\View\UserView; +use App\Application\User\View\OrganizationUserView; +use App\Application\User\View\UserOrganizationView; use App\Domain\User\OrganizationUser; use App\Domain\User\Repository\OrganizationUserRepositoryInterface; -use App\Domain\User\User; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -30,28 +29,39 @@ public function remove(OrganizationUser $organizationUser): void $this->getEntityManager()->remove($organizationUser); } - public function findOrganizationsByUser(User $user): array + public function findByUserUuid(string $uuid): array { return $this->createQueryBuilder('ou') - ->select( - \sprintf('NEW %s(o.uuid, o.name, ou.roles)', OrganizationView::class), - ) - ->where('ou.user = :user') + ->select(\sprintf( + 'NEW %s( + o.uuid, + o.name, + ou.roles + )', + UserOrganizationView::class, + )) + ->where('ou.user = :userUuid') ->innerJoin('ou.organization', 'o') - ->setParameter('user', $user) + ->setParameter('userUuid', $uuid) ->getQuery() ->getResult(); } - public function findUsersByOrganizationUuid(string $uuid): array + public function findByOrganizationUuid(string $uuid): array { return $this->createQueryBuilder('ou') - ->select( - \sprintf('NEW %s(u.uuid, u.fullName, u.email, ou.roles)', UserView::class), - ) - ->where('ou.organization = :organization') + ->select(\sprintf( + 'NEW %s( + u.uuid, + u.fullName, + u.email, + ou.roles + )', + OrganizationUserView::class, + )) + ->where('ou.organization = :organizationUuid') ->innerJoin('ou.user', 'u') - ->setParameter('organization', $uuid) + ->setParameter('organizationUuid', $uuid) ->orderBy('u.fullName', 'ASC') ->getQuery() ->getResult(); diff --git a/src/Infrastructure/Security/Provider/UserProvider.php b/src/Infrastructure/Security/Provider/UserProvider.php index bb185419a..6e865e9a7 100644 --- a/src/Infrastructure/Security/Provider/UserProvider.php +++ b/src/Infrastructure/Security/Provider/UserProvider.php @@ -28,14 +28,14 @@ public function loadUserByIdentifier(string $identifier): UserInterface throw new UserNotFoundException(\sprintf('Unable to find the user %s', $identifier)); } - $organizationUsers = $this->organizationUserRepositoryInterface->findOrganizationsByUser($user); + $userOrganizations = $this->organizationUserRepositoryInterface->findByUserUuid($user->getUuid()); return new SymfonyUser( $user->getUuid(), $user->getEmail(), $user->getFullName(), $user->getPassword(), - $organizationUsers, + $userOrganizations, $user->getRoles(), ); } diff --git a/src/Infrastructure/Security/SymfonyUser.php b/src/Infrastructure/Security/SymfonyUser.php index f569051c6..d29a2577f 100644 --- a/src/Infrastructure/Security/SymfonyUser.php +++ b/src/Infrastructure/Security/SymfonyUser.php @@ -4,7 +4,7 @@ namespace App\Infrastructure\Security; -use App\Application\User\View\OrganizationView; +use App\Application\User\View\UserOrganizationView; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\UserInterface; @@ -15,7 +15,8 @@ public function __construct( private string $email, private string $fullName, private string $password, - private array $organizationUsers, + /** @var UserOrganizationView[] */ + private array $userOrganizations, private array $roles, ) { } @@ -55,17 +56,21 @@ public function getPassword(): string return $this->password; } - public function getOrganizationUsers(): array + /** @return UserOrganizationView[] */ + public function getUserOrganizations(): array { - return $this->organizationUsers; + return $this->userOrganizations; } - public function getOrganizationUuids(): array + public function getUserOrganizationUuids(): array { - return array_map( - function (OrganizationView $organizationUser) { return $organizationUser->uuid; }, - $this->organizationUsers, - ); + $uuids = []; + + foreach ($this->userOrganizations as $org) { + $uuids[] = $org->uuid; + } + + return $uuids; } public function eraseCredentials(): void diff --git a/templates/regulation/_items.html.twig b/templates/regulation/_items.html.twig index 5959a1ffd..237b2a2db 100644 --- a/templates/regulation/_items.html.twig +++ b/templates/regulation/_items.html.twig @@ -2,9 +2,9 @@ {% if isAuthenticated %} {% set duplicateCsrfToken = csrf_token('duplicate-regulation') %} {% set deleteCsrfToken = csrf_token('delete-regulation') %} - {% set organizationUsersUuids = app.user.getOrganizationUuids %} + {% set userOrganizationUuids = app.user.getUserOrganizationUuids %} {% else %} - {% set organizationUsersUuids = [] %} + {% set userOrganizationUuids = [] %} {% endif %}