entityManager = $entityManager; $this->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 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) { $qb = $this->queryByUsernameOrEmail($pattern); return $qb->getQuery()->getSingleResult(); } /** * 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; } }