src/Repository/UserRepository.php line 31

Open in your IDE?
  1. <?php
  2. namespace App\Repository;
  3. use App\Entity\BlogPost;
  4. use App\Entity\User;
  5. use DateTimeImmutable;
  6. use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
  7. use Doctrine\ORM\EntityManagerInterface;
  8. use Doctrine\Persistence\ManagerRegistry;
  9. use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
  10. use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
  11. use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
  12. use Scienta\DoctrineJsonFunctions\Query\AST\Functions\Mysql as DqlFunctions;
  13. use App\Repository\SiteConfigRepository;
  14. /**
  15.  * @method User|null find($id, $lockMode = null, $lockVersion = null)
  16.  * @method User|null findOneBy(array $criteria, array $orderBy = null)
  17.  * @method User[]    findAll()
  18.  * @method User[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
  19.  */
  20. class UserRepository extends ServiceEntityRepository implements PasswordUpgraderInterface
  21. {
  22.     public function __construct(
  23.         ManagerRegistry $registry,
  24.         private EntityManagerInterface $em,
  25.         private PreferenceRepository $preferenceRepository,
  26.         SiteConfigRepository $siteConfigRepository
  27.     ) {
  28.         parent::__construct($registryUser::class);
  29.         $this->siteConfigRepository $siteConfigRepository;
  30.     }
  31.     public function deleteOldFirebaseToken(): int
  32.     {
  33.         $lastMounth = (new DateTimeImmutable())->modify("-30 day");
  34.         return $this->createQueryBuilder("u")
  35.             ->update()
  36.             ->set('u.tokenFirebase'":null")
  37.             ->where('u.firebaseTokenGeneratedAt < :val')
  38.             ->orWhere('u.firebaseTokenGeneratedAt is null')
  39.             ->setParameter('val'$lastMounth)
  40.             ->setParameter('null'null)
  41.             ->getQuery()
  42.             ->execute();
  43.     }
  44.     /**
  45.      * Used to upgrade (rehash) the user's password automatically over time.
  46.      */
  47.     public function upgradePassword(PasswordAuthenticatedUserInterface $userstring $newHashedPassword): void
  48.     {
  49.         if (!$user instanceof User) {
  50.             throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.'\get_class($user)));
  51.         }
  52.         $user->setPassword($newHashedPassword);
  53.         $this->_em->persist($user);
  54.         $this->_em->flush();
  55.     }
  56.     public function search(string $query)
  57.     {
  58.         return $this->createQueryBuilder('u')
  59.             ->andWhere('u.email LIKE :query')
  60.             ->setParameter('query''%' $query '%')
  61.             ->getQuery()
  62.             ->getArrayResult();
  63.     }
  64.     public function allCategories($id)
  65.     {
  66.         return $this->createQueryBuilder('u')
  67.             ->select('u, b')
  68.             ->andWhere('u.id = :id')
  69.             ->leftJoin('u.categories''b')
  70.             ->setParameter('id'$id)
  71.             ->addSelect('b as BlogPostCategory')
  72.             ->getQuery()
  73.             ->execute();
  74.     }
  75.     public function getId($email)
  76.     {
  77.         $query $this
  78.             ->createQueryBuilder('u')
  79.             ->select('u.id')
  80.             ->andWhere('u.email IN (:email)')
  81.             ->setParameter(':email'$email);
  82.         return $query->getQuery()->getResult();
  83.     }
  84.     public function getTotalUsers(User $currentUser null)
  85.     {
  86.         $qb $this->createQueryBuilder('u')
  87.             ->select('count(DISTINCT u.id)');
  88.         $this->addInstanceFilter($qb$currentUser);
  89.         
  90.         return $qb->getQuery()->getSingleScalarResult();
  91.     }
  92.     public function getTotalUsersByMonth(User $currentUser null)
  93.     {
  94.         $qb $this->createQueryBuilder('u')
  95.             ->select('count(DISTINCT u.id)')
  96.             ->where('MONTH(u.createdAt) = MONTH(CURRENT_DATE())')
  97.             ->andWhere('YEAR(u.createdAt) = YEAR(CURRENT_DATE())');
  98.         $this->addInstanceFilter($qb$currentUser);
  99.         
  100.         return $qb->getQuery()->getSingleScalarResult();
  101.     }
  102.     public function getTotalUsersByWeek(User $currentUser null)
  103.     {
  104.         $qb $this->createQueryBuilder('u')
  105.             ->select('count(DISTINCT u.id)')
  106.             ->where('WEEK(u.createdAt) = WEEK(CURRENT_DATE())')
  107.             ->andWhere('YEAR(u.createdAt) = YEAR(CURRENT_DATE())');
  108.         $this->addInstanceFilter($qb$currentUser);
  109.         
  110.         return $qb->getQuery()->getSingleScalarResult();
  111.     }
  112.     public function getTotalUsersByDay(User $currentUser null)
  113.     {
  114.         $qb $this->createQueryBuilder('u')
  115.             ->select('count(DISTINCT u.id)')
  116.             ->where('DAY(u.createdAt) = DAY(CURRENT_DATE())')
  117.             ->andWhere('MONTH(u.createdAt) = MONTH(CURRENT_DATE())')
  118.             ->andWhere('YEAR(u.createdAt) = YEAR(CURRENT_DATE())');
  119.         $this->addInstanceFilter($qb$currentUser);
  120.         
  121.         return $qb->getQuery()->getSingleScalarResult();
  122.     }
  123.     private function addInstanceFilter($qb, ?User $currentUser): void
  124.     {
  125.         $generalSiteConfig $this->siteConfigRepository->findOneBy([]);
  126.         $isInstanceActive $generalSiteConfig $generalSiteConfig->isInstanceActive() : true;
  127.         if ($isInstanceActive && $currentUser) {
  128.             $userInstances $currentUser->getInstances();
  129.             if ($userInstances->count() > 0) {
  130.                 $instanceIds $userInstances->map(function($instance) {
  131.                     return $instance->getId();
  132.                 })->toArray();
  133.                 
  134.                 $qb->leftJoin('u.instances''i')
  135.                 ->andWhere('i.id IN (:userInstanceIds)')
  136.                 ->setParameter('userInstanceIds'$instanceIds);
  137.             } else {
  138.                 $qb->andWhere('1 = 0');
  139.             }
  140.         }
  141.     }
  142.     public function getUsersByRolesAndCriterias(BlogPost $post): mixed
  143.     {
  144.         $postRoles $post->getRoles();
  145.         $postCriteria1Items $post->getCriteria1Items()->map(fn($c) => $c->getId())->toArray() + [-1];   // adding -1 value for sql query "in" that requires at least one value
  146.         $postCriteria2Items $post->getCriteria2Items()->map(fn($c) => $c->getId())->toArray() + [-1];
  147.         $postCriteria3Items $post->getCriteria3Items()->map(fn($c) => $c->getId())->toArray() + [-1];
  148.         $postIsPublic $post->getIsPublic();
  149.         $postHasAllCriterias1 $post->isHasAllCriteria1();
  150.         $postHasAllCriterias2 $post->isHasAllCriteria2();
  151.         $postHasAllCriterias3 $post->isHasAllCriteria3();
  152.         // create the custom query to filter by user role
  153.         $roleSqlArray = [];
  154.         foreach ($postRoles as $role) {
  155.             $roleSqlArray[] = 'JSON_CONTAINS(u.roles, \'["' $role->getCode() . '"]\', \'$\') = true';
  156.         }
  157.         if (count($roleSqlArray))
  158.             $roleSqlQuery implode(" OR "$roleSqlArray) . " OR ";
  159.         else
  160.             $roleSqlQuery "";
  161.         $query $this->createQueryBuilder('u')
  162.             ->leftJoin('u.criteria1Items''c1items')
  163.             ->leftJoin('u.criteria2Items''c2items')
  164.             ->leftJoin('u.criteria3Items''c3items')
  165.             ->where($roleSqlQuery ":postIsPublic = true")
  166.             ->andWhere("c1items IN (:postCriteria1Items) OR :postHasAllCriterias1 = true")
  167.             ->andWhere("c2items IN (:postCriteria2Items) OR :postHasAllCriterias2 = true")
  168.             ->andWhere("c3items IN (:postCriteria3Items) OR :postHasAllCriterias3 = true")
  169.             ->setParameter('postCriteria1Items'$postCriteria1Items)
  170.             ->setParameter('postCriteria2Items'$postCriteria2Items)
  171.             ->setParameter('postCriteria3Items'$postCriteria3Items)
  172.             ->setParameter('postIsPublic'$postIsPublic)
  173.             ->setParameter('postHasAllCriterias1'$postHasAllCriterias1)
  174.             ->setParameter('postHasAllCriterias2'$postHasAllCriterias2)
  175.             ->setParameter('postHasAllCriterias3'$postHasAllCriterias3)
  176.             ->distinct();
  177.         return $query->getQuery()->getResult();
  178.     }
  179.     /**
  180.      * Add all the existing preferences of the application to the user
  181.      */
  182.     public function addAllPreferences(User $user): void
  183.     {
  184.         $preferences $this->preferenceRepository->findAll();
  185.         foreach ($preferences as $preference) {
  186.             $user->addPreference($preference);
  187.         }
  188.     }
  189.      public function getUsersByRolesAndCriteriasAndInstances(BlogPost $post): array
  190.     {
  191.         // 1) récupération de ce qu’on avait déjà
  192.         $postRoles $post->getRoles();
  193.         $postCriteria1Items $post->getCriteria1Items()->map(fn($c) => $c->getId())->toArray() + [-1];
  194.         $postCriteria2Items $post->getCriteria2Items()->map(fn($c) => $c->getId())->toArray() + [-1];
  195.         $postCriteria3Items $post->getCriteria3Items()->map(fn($c) => $c->getId())->toArray() + [-1];
  196.         $postIsPublic        $post->getIsPublic();
  197.         $postHasAllCriterias1 $post->isHasAllCriteria1();
  198.         $postHasAllCriterias2 $post->isHasAllCriteria2();
  199.         $postHasAllCriterias3 $post->isHasAllCriteria3();
  200.         // 2) on récupère les instances du post
  201.         // (dans ton back tu as un champ "Instances *", donc on part du principe que c’est un ManyToMany)
  202.         $postInstanceIds = [];
  203.         if (method_exists($post'getInstances')) {
  204.             $postInstanceIds $post->getInstances()
  205.                 ->map(fn($i) => $i->getId())
  206.                 ->toArray();
  207.         }
  208.         // create the custom query to filter by user role
  209.         $roleSqlArray = [];
  210.         foreach ($postRoles as $role) {
  211.             $roleSqlArray[] = 'JSON_CONTAINS(u.roles, \'["' $role->getCode() . '"]\', \'$\') = true';
  212.         }
  213.         $roleSqlQuery count($roleSqlArray)
  214.             ? implode(" OR "$roleSqlArray) . " OR "
  215.             "";
  216.         $qb $this->createQueryBuilder('u')
  217.             ->leftJoin('u.criteria1Items''c1items')
  218.             ->leftJoin('u.criteria2Items''c2items')
  219.             ->leftJoin('u.criteria3Items''c3items')
  220.             ->where($roleSqlQuery ":postIsPublic = true")
  221.             ->andWhere("c1items IN (:postCriteria1Items) OR :postHasAllCriterias1 = true")
  222.             ->andWhere("c2items IN (:postCriteria2Items) OR :postHasAllCriterias2 = true")
  223.             ->andWhere("c3items IN (:postCriteria3Items) OR :postHasAllCriterias3 = true")
  224.             ->setParameter('postCriteria1Items'$postCriteria1Items)
  225.             ->setParameter('postCriteria2Items'$postCriteria2Items)
  226.             ->setParameter('postCriteria3Items'$postCriteria3Items)
  227.             ->setParameter('postIsPublic'$postIsPublic)
  228.             ->setParameter('postHasAllCriterias1'$postHasAllCriterias1)
  229.             ->setParameter('postHasAllCriterias2'$postHasAllCriterias2)
  230.             ->setParameter('postHasAllCriterias3'$postHasAllCriterias3)
  231.             ->distinct();
  232.         /**
  233.          * Ici on ajoute le filtre “instance”
  234.          * On ne le fait que si le site a la gestion d’instances activée
  235.          * ET que le contenu a bien au moins 1 instance.
  236.          */
  237.         $generalSiteConfig $this->siteConfigRepository->findOneBy([]);
  238.         $isInstanceActive $generalSiteConfig $generalSiteConfig->isInstanceActive() : true;
  239.         if ($isInstanceActive && !empty($postInstanceIds)) {
  240.             // user.instances est un ManyToMany → on join
  241.             $qb
  242.                 ->leftJoin('u.instances''ui')
  243.                 ->andWhere('ui.id IN (:postInstanceIds)')
  244.                 ->setParameter('postInstanceIds'$postInstanceIds);
  245.         }
  246.         return $qb->getQuery()->getResult();
  247.     }
  248. }