repository = $entityManager->getRepository(User::class); } public function countBy(array $criteria): int { return $this->repository->count($criteria); } public function countByActive(): int { return $this->countBy(['enabled' => true]); } public function countByNotHavingAttribute(string $key): int { $rsm = new ResultSetMapping(); $rsm->addScalarResult('count', 'count'); $sql = 'SELECT count(*) FROM users u WHERE NOT attributes ?? :key OR attributes IS NULL AND enabled IS TRUE'; return $this->entityManager->createNativeQuery($sql, $rsm)->setParameter(':key', $key)->getSingleScalarResult(); } public function countByUsernameOrEmail(string $pattern): int { $qb = $this->queryByUsernameOrEmail($pattern); $qb->select('COUNT(u)'); return (int) $qb->getQuery()->getSingleScalarResult(); } public function find($id, $lockMode = null, $lockVersion = null): ?User { return $this->repository->find($id, $lockMode, $lockVersion); } /** * @return User[] */ public function findAll(): array { return $this->repository->findAll(); } /** * @param string $lang */ public function findAllAsArray(string $lang): iterable { $dql = sprintf(<<<'DQL' SELECT u.id AS id, u.username AS username, u.email, u.enabled, IDENTITY(u.civility) AS civility_id, JSON_EXTRACT(civility.abbreviation, :lang) AS civility_abbreviation, JSON_EXTRACT(civility.name, :lang) AS civility_name, u.label, mainCenter.id AS mainCenter_id, mainCenter.name AS mainCenter_name, IDENTITY(u.mainScope) AS mainScope_id, JSON_EXTRACT(mainScope.name, :lang) AS mainScope_name, IDENTITY(u.userJob) AS userJob_id, JSON_EXTRACT(userJob.label, :lang) AS userJob_name, currentLocation.id AS currentLocation_id, currentLocation.name AS currentLocation_name, mainLocation.id AS mainLocation_id, mainLocation.name AS mainLocation_name, u.absenceStart FROM Chill\MainBundle\Entity\User u LEFT JOIN u.civility civility LEFT JOIN u.currentLocation currentLocation LEFT JOIN u.mainLocation mainLocation LEFT JOIN u.mainCenter mainCenter LEFT JOIN u.mainScope mainScope LEFT JOIN u.userJob userJob ORDER BY u.label DQL); $query = $this->entityManager->createQuery($dql) ->setHydrationMode(AbstractQuery::HYDRATE_ARRAY) ->setParameter('lang', $lang) ; foreach ($query->toIterable() as $u) { yield $u; } } public function findAllUserACLAsArray(): iterable { $sql = <<<'SQL' SELECT u.id, u.username, u.email, u.label, u.enabled, c.id AS center_id, c.name AS center_name, pg.id AS permissionsGroup_id, pg.name AS permissionsGroup_name FROM users u LEFT JOIN user_groupcenter ON u.id = user_groupcenter.user_id LEFT JOIN group_centers ON user_groupcenter.groupcenter_id = group_centers.id LEFT JOIN centers c on group_centers.center_id = c.id LEFT JOIN permission_groups pg on group_centers.permissionsgroup_id = pg.id ORDER BY u.username, c.name, pg.name SQL; $query = $this->entityManager->getConnection()->executeQuery($sql); foreach ($query->iterateAssociative() as $u) { yield $u; } } /** * @param mixed|null $limit * @param mixed|null $offset * * @return User[] */ public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array { return $this->repository->findBy($criteria, $orderBy, $limit, $offset); } /** * @return array|User[] */ public function findByActive(?array $orderBy = null, ?int $limit = null, ?int $offset = null): array { return $this->findBy(['enabled' => true], $orderBy, $limit, $offset); } /** * Find users which does not have a key on attribute column. * * @return array|User[] */ public function findByNotHavingAttribute(string $key, ?int $limit = null, ?int $offset = null): array { $rsm = new ResultSetMappingBuilder($this->entityManager); $rsm->addRootEntityFromClassMetadata(User::class, 'u'); $sql = 'SELECT ' . $rsm->generateSelectClause() . ' FROM users u WHERE NOT attributes ?? :key OR attributes IS NULL AND enabled IS TRUE'; if (null !== $limit) { $sql .= " LIMIT {$limit}"; } if (null !== $offset) { $sql .= " OFFSET {$offset}"; } return $this->entityManager->createNativeQuery($sql, $rsm)->setParameter(':key', $key)->getResult(); } public function findByUsernameOrEmail(string $pattern, ?array $orderBy = [], ?int $limit = null, ?int $offset = null): array { $qb = $this->queryByUsernameOrEmail($pattern); $qb->select('u'); if (null !== $limit) { $qb->setMaxResults($limit); } if (null !== $offset) { $qb->setFirstResult($offset); } foreach ($orderBy as $field => $order) { $qb->addOrderBy('u.' . $field, $order); } return $qb->getQuery()->getResult(); } public function findOneBy(array $criteria, ?array $orderBy = null): ?User { return $this->repository->findOneBy($criteria, $orderBy); } public function findOneByUsernameOrEmail(string $pattern): ?User { $qb = $this->queryByUsernameOrEmail($pattern)->select('u'); try { return $qb->getQuery()->getSingleResult(); } catch (NoResultException) { return null; } } /** * Get the users having a specific flags. * * If provided, only the users amongst "filtered users" are searched. This * allows to make a first search amongst users based on role and center * and, then filter those users having some flags. * * @param \Chill\MainBundle\Entity\User[] $amongstUsers * @param mixed $flag */ public function findUsersHavingFlags($flag, array $amongstUsers = []): array { $gcs = $this ->entityManager ->createQuery( 'SELECT DISTINCT gc ' . 'FROM ' . GroupCenter::class . ' gc ' . 'JOIN gc.permissionsGroup pg ' . 'WHERE ' . 'JSONB_EXISTS_IN_ARRAY(pg.flags, :flag) = :true ' ) ->setParameters([ 'true' => true, 'flag' => $flag, ]) ->getResult(); if (count($gcs) === 0) { return []; } $qb = $this->entityManager->createQueryBuilder(); $qb ->select('DISTINCT u') ->from(User::class, 'u') ->where("u.enabled = 'TRUE'"); $orx = $qb->expr()->orX(); foreach ($gcs as $i => $gc) { $orx->add(':gc_' . $i . ' MEMBER OF u.groupCenters'); $qb->setParameter('gc_' . $i, $gc); } $qb->andWhere($orx); if ([] !== $amongstUsers) { $qb ->andWhere($qb->expr()->in('u', ':amongstUsers')) ->setParameter('amongstUsers', $amongstUsers); } return $qb->getQuery()->getResult(); } public function getClassName(): string { return User::class; } private function queryByUsernameOrEmail(string $pattern): QueryBuilder { $qb = $this->entityManager->createQueryBuilder()->from(User::class, 'u'); $searchByPattern = $qb->expr()->orX(); $searchByPattern ->add($qb->expr()->like('u.usernameCanonical', 'CONCAT(\'%\', LOWER(UNACCENT(:pattern)), \'%\')')) ->add($qb->expr()->like('u.emailCanonical', 'CONCAT(\'%\', LOWER(UNACCENT(:pattern)), \'%\')')); $qb ->where($searchByPattern) ->setParameter('pattern', $pattern); return $qb; } }