AccessRepository.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Repository\Access;
  4. use App\DQL\DateConditions;
  5. use App\Entity\Access\Access;
  6. use App\Entity\Organization\Organization;
  7. use App\Enum\Access\FunctionEnum;
  8. use App\Service\Doctrine\FiltersConfigurationService;
  9. use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
  10. use Doctrine\Persistence\ManagerRegistry;
  11. use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
  12. use Symfony\Component\HttpFoundation\RequestStack;
  13. use Symfony\Component\Security\Core\User\UserInterface;
  14. /**
  15. * @method Access|null find($id, $lockMode = null, $lockVersion = null)
  16. * @method Access|null findOneBy(mixed[] $criteria, mixed[] $orderBy = null)
  17. * @method Access[] findAll()
  18. * @method Access[] findBy(mixed[] $criteria, mixed[] $orderBy = null, $limit = null, $offset = null)
  19. */
  20. class AccessRepository extends ServiceEntityRepository implements UserLoaderInterface
  21. {
  22. public const ACCESS_NAME_HEADER = 'X-AccessId';
  23. public const HTTP_X_SWITCH_USER = 'X-Switch-User';
  24. public function __construct(
  25. ManagerRegistry $registry,
  26. private readonly RequestStack $requestStack,
  27. private readonly FiltersConfigurationService $filtersConfigurationService,
  28. ) {
  29. parent::__construct($registry, Access::class);
  30. }
  31. /**
  32. * Méthode permettant de fournir un userProvider custom (voir config provider : access_provider).
  33. *
  34. * @param string $identifier
  35. *
  36. * @throws \Doctrine\ORM\NonUniqueResultException
  37. */
  38. public function loadUserByIdentifier($identifier): ?UserInterface
  39. {
  40. if ($this->requestStack->getMainRequest()->headers->get(self::HTTP_X_SWITCH_USER) === $identifier) {
  41. return $this->getEntityManager()->find(Access::class, $identifier);
  42. }
  43. return $this->findAccessByUsernameAndAccessId($identifier, (int) $this->requestStack->getMainRequest()->headers->get(self::ACCESS_NAME_HEADER));
  44. }
  45. /**
  46. * Récupère un access grâce à son username et son ID.
  47. *
  48. * @throws \Doctrine\ORM\NonUniqueResultException
  49. */
  50. private function findAccessByUsernameAndAccessId(string $username, int $id): mixed
  51. {
  52. $entityManager = $this->getEntityManager();
  53. return $entityManager->createQuery(
  54. 'SELECT a
  55. FROM App\Entity\Access\Access a
  56. INNER JOIN a.person p
  57. WHERE p.username = :query AND a.id = :id'
  58. )
  59. ->setParameter('query', $username)
  60. ->setParameter('id', $id)
  61. ->getOneOrNullResult();
  62. }
  63. /**
  64. * Retourne l'access administrateur de cette organisation.
  65. */
  66. public function findAdminAccess(Organization $organization): Access
  67. {
  68. return $this->findOneBy([
  69. 'adminAccess' => 1,
  70. 'organization' => $organization,
  71. ]);
  72. }
  73. /**
  74. * Retourne tous les access qui appartiennent à une organisation qui est active dans un réseau.
  75. */
  76. public function findAllValidAccesses(
  77. Access $access,
  78. ): mixed {
  79. $datetime = new \DateTime();
  80. $today = $datetime->format('Y-m-d');
  81. $this->filtersConfigurationService->suspendTimeConstraintFilters();
  82. try {
  83. $q = $this->createQueryBuilder('access')
  84. ->innerJoin('access.organization', 'organization')
  85. ->innerJoin('organization.networkOrganizations', 'networkOrganizations')
  86. ->where('access.person = :person')
  87. ->andWhere('networkOrganizations.startDate <= :today')
  88. ->andWhere(
  89. "networkOrganizations.endDate >= :today
  90. OR networkOrganizations.endDate = '0000-00-00'
  91. OR networkOrganizations.endDate IS NULL")
  92. ->setParameter('person', $access->getPerson())
  93. ->setParameter('today', $today);
  94. return $q->getQuery()->getResult();
  95. } finally {
  96. $this->filtersConfigurationService->restoreTimeConstraintFilters();
  97. }
  98. }
  99. /**
  100. * Retourne si oui ou non un access possède une fonction F active à une date précise.
  101. */
  102. public function hasGotFunctionAtThisDate(Access $access, FunctionEnum $function, \DateTime $date): bool
  103. {
  104. $this->filtersConfigurationService->suspendTimeConstraintFilters();
  105. try {
  106. $qb = $this->createQueryBuilder('access');
  107. $qb
  108. ->innerJoin('access.organizationFunction', 'organization_function')
  109. ->innerJoin('organization_function.functionType', 'function_type')
  110. ->where('function_type.mission = :mission')
  111. ->andWhere('access.id = :id')
  112. ->setParameter('id', $access->getId())
  113. ->setParameter('mission', $function);
  114. DateConditions::addDateInPeriodCondition($qb, 'organization_function', $date->format('Y-m-d'));
  115. return count($qb->getQuery()->getResult()) > 0;
  116. } finally {
  117. $this->filtersConfigurationService->restoreTimeConstraintFilters();
  118. }
  119. }
  120. /**
  121. * Retourne tous les accesses de l'organization ayant la fonction donnée à la date donnée.
  122. *
  123. * @return list<Access>
  124. */
  125. public function findByOrganizationAndMission(Organization $organization, FunctionEnum $function, ?\DateTime $date = null): array
  126. {
  127. if ($date === null) {
  128. $date = new \DateTime();
  129. }
  130. $this->filtersConfigurationService->suspendTimeConstraintFilters();
  131. try {
  132. $qb = $this->createQueryBuilder('access');
  133. $qb
  134. ->innerJoin('access.organizationFunction', 'organization_function')
  135. ->innerJoin('organization_function.functionType', 'function_type')
  136. ->where('function_type.mission = :mission')
  137. ->andWhere('access.organization = :id')
  138. ->setParameter('id', $organization->getId())
  139. ->setParameter('mission', $function);
  140. DateConditions::addDateInPeriodCondition($qb, 'organization_function', $date->format('Y-m-d'));
  141. return $qb->getQuery()->getResult();
  142. } finally {
  143. $this->filtersConfigurationService->restoreTimeConstraintFilters();
  144. }
  145. }
  146. /**
  147. * Get all the currently active accesses and return an array
  148. * of the form ['id' => $accessId, 'organization_id' => $organizationId, 'mission' => $mission].
  149. *
  150. * Used by App\Service\Dolibarr\DolibarrSync\DolibarrSyncService
  151. *
  152. * @return list<Access>
  153. */
  154. public function getAllActiveMembersAndMissions(): array
  155. {
  156. $qb = $this->createQueryBuilder('access');
  157. $qb
  158. ->select('access.id', 'organization.id as organization_id', 'function_type.mission')
  159. ->innerJoin('access.organization', 'organization')
  160. ->innerJoin('access.organizationFunction', 'organization_function')
  161. ->innerJoin('organization_function.functionType', 'function_type')
  162. ;
  163. DateConditions::addDateInPeriodCondition($qb, 'organization_function', date('Y-m-d'));
  164. return $qb->getQuery()->getArrayResult();
  165. }
  166. }