repository = $entityManager->getRepository(Result::class); } public function countByGoal(Goal $goal): int { $qb = $this->buildQueryByGoal($goal); $qb->select('COUNT(r)'); return $qb ->getQuery() ->getSingleScalarResult(); } public function countBySocialActionWithDescendants(SocialAction $action): int { $qb = $this->buildQueryBySocialActionWithDescendants($action); $qb->select('COUNT(r)'); return $qb ->getQuery() ->getSingleScalarResult(); } public function find($id): ?Result { return $this->repository->find($id); } /** * @return array */ public function findAll(): array { return $this->repository->findAll(); } /** * @param mixed|null $limit * @param mixed|null $offset * * @return array */ public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array { return $this->repository->findBy($criteria, $orderBy, $limit, $offset); } /** * @return array */ public function findByGoal(Goal $goal, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array { $qb = $this->buildQueryByGoal($goal); if (null !== $orderBy) { foreach ($orderBy as $sort => $order) { $qb->addOrderBy('r.'.$sort, $order); } } return $qb ->select('r') ->setMaxResults($limit) ->setFirstResult($offset) ->getQuery() ->getResult(); } /** * @return Result[] */ public function findBySocialActionWithDescendants(SocialAction $action, array $orderBy = [], ?int $limit = null, ?int $offset = null): array { $qb = $this->buildQueryBySocialActionWithDescendants($action); $qb->select('r'); foreach ($orderBy as $sort => $order) { $qb->addOrderBy('r.'.$sort, $order); } return $qb ->setMaxResults($limit) ->setFirstResult($offset) ->getQuery() ->getResult(); } public function findOneBy(array $criteria, ?array $orderBy = null): ?Result { return $this->repository->findOneBy($criteria, $orderBy); } /** * @return class-string */ public function getClassName(): string { return Result::class; } private function getLang(): string { return $this->requestStack->getCurrentRequest()?->getLocale() ?? 'fr'; } public function getResult( QueryBuilder $qb, ?int $start = 0, ?int $limit = 50, ?array $orderBy = [], ): array { $qb->select('r'); $qb ->setFirstResult($start) ->setMaxResults($limit); foreach ($orderBy as $field => $direction) { $qb->addOrderBy('r.'.$field, $direction); } return $qb->getQuery()->getResult(); } private function queryByTitle(string $pattern): QueryBuilder { $qb = $this->entityManager->createQueryBuilder()->from(Result::class, 'r'); $qb ->where($qb->expr()->like('LOWER(UNACCENT(JSON_EXTRACT(r.title, :lang)))', "CONCAT('%', LOWER(UNACCENT(:pattern)), '%')")) ->setParameter('pattern', $pattern) ->setParameter('lang', $this->getLang()); return $qb; } public function buildFilterBaseQuery(?string $queryString, array $isActive): QueryBuilder { if (null !== $queryString) { $qb = $this->queryByTitle($queryString); } else { $qb = $this->entityManager->createQueryBuilder()->from(Result::class, 'r'); } $now = new \DateTime('now'); if (in_array('Active', $isActive, true) && !in_array('Inactive', $isActive, true)) { $qb->andWhere( $qb->expr()->orX( $qb->expr()->isNull('r.desactivationDate'), $qb->expr()->gt('r.desactivationDate', ':now') ) )->setParameter('now', $now); } elseif (in_array('Inactive', $isActive, true) && !in_array('Active', $isActive, true)) { $qb->andWhere( $qb->expr()->andX( $qb->expr()->isNotNull('r.desactivationDate'), $qb->expr()->lte('r.desactivationDate', ':now') ) )->setParameter('now', $now); } return $qb; } /** * @return array */ public function findFilteredResults( ?string $queryString = null, array $isActive = ['active'], ?int $start = 0, ?int $limit = 50, ?array $orderBy = ['id' => 'ASC'], ): array { $qb = $this->buildFilterBaseQuery($queryString, $isActive); return $this->getResult($qb, $start, $limit, $orderBy); } public function countFilteredResults( ?string $queryString = null, array $isActive = ['active'], ): int { $qb = $this->buildFilterBaseQuery($queryString, $isActive); try { return $qb ->select('COUNT(r)') ->getQuery()->getSingleScalarResult(); } catch (NoResultException|NonUniqueResultException $e) { throw new \LogicException('a count query should return one result', previous: $e); } } private function buildQueryByGoal(Goal $goal): QueryBuilder { $qb = $this->repository->createQueryBuilder('r'); $qb->where(':goal MEMBER OF r.goals') ->setParameter('goal', $goal); return $qb; } private function buildQueryBySocialActionWithDescendants(SocialAction $action): QueryBuilder { $actions = $action->getDescendantsWithThis(); $qb = $this->repository->createQueryBuilder('r'); $orx = $qb->expr()->orX(); $i = 0; foreach ($actions as $act) { $orx->add(":action_{$i} MEMBER OF r.socialActions"); $qb->setParameter("action_{$i}", $act); } $qb->where($orx); return $qb; } }