AccessRepository.php 6.9 KB

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