repository = $entityManager->getRepository(Goal::class); } public function countBySocialActionWithDescendants(SocialAction $action): int { $qb = $this->buildQueryBySocialActionWithDescendants($action); $qb->select('COUNT(g)'); return $qb ->getQuery() ->getSingleScalarResult(); } public function find($id): ?Goal { 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 Goal[] */ public function findBySocialActionWithDescendants(SocialAction $action, array $orderBy = [], ?int $limit = null, ?int $offset = null): array { $qb = $this->buildQueryBySocialActionWithDescendants($action); $qb->select('g'); $qb->andWhere( $qb->expr()->orX( $qb->expr()->isNull('g.desactivationDate'), $qb->expr()->gt('g.desactivationDate', ':now') ) ) ->setParameter('now', new \DateTime('now')); foreach ($orderBy as $sort => $order) { $qb->addOrderBy('g.'.$sort, $order); } return $qb ->setMaxResults($limit) ->setFirstResult($offset) ->getQuery() ->getResult(); } public function findOneBy(array $criteria, ?array $orderBy = null): ?Goal { return $this->repository->findOneBy($criteria, $orderBy); } /** * @return class-string */ public function getClassName(): string { return Goal::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('g'); $qb ->setFirstResult($start) ->setMaxResults($limit); foreach ($orderBy as $field => $direction) { $qb->addOrderBy('g.'.$field, $direction); } return $qb->getQuery()->getResult(); } private function queryByTitle(string $pattern): QueryBuilder { $qb = $this->entityManager->createQueryBuilder()->from(Goal::class, 'g'); // search across locales by extracting the localized value $qb ->where($qb->expr()->like('LOWER(UNACCENT(JSON_EXTRACT(g.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(Goal::class, 'g'); } // Active when desactivationDate is null or in the future $now = new \DateTime('now'); if (in_array('Active', $isActive, true) && !in_array('Inactive', $isActive, true)) { $qb->andWhere( $qb->expr()->orX( $qb->expr()->isNull('g.desactivationDate'), $qb->expr()->gt('g.desactivationDate', ':now') ) )->setParameter('now', $now); } elseif (in_array('Inactive', $isActive, true) && !in_array('Active', $isActive, true)) { $qb->andWhere( $qb->expr()->andX( $qb->expr()->isNotNull('g.desactivationDate'), $qb->expr()->lte('g.desactivationDate', ':now') ) )->setParameter('now', $now); } return $qb; } /** * @return array */ public function findFilteredGoals( ?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 countFilteredGoals( ?string $queryString = null, array $isActive = ['active'], ): int { $qb = $this->buildFilterBaseQuery($queryString, $isActive); try { return $qb ->select('COUNT(g)') ->getQuery()->getSingleScalarResult(); } catch (NoResultException|NonUniqueResultException $e) { throw new \LogicException('a count query should return one result', previous: $e); } } private function buildQueryBySocialActionWithDescendants(SocialAction $action): QueryBuilder { $actions = $action->getDescendantsWithThis(); $qb = $this->repository->createQueryBuilder('g'); $orx = $qb->expr()->orX(); $i = 0; foreach ($actions as $act) { $orx->add(":action_{$i} MEMBER OF g.socialActions"); $qb->setParameter("action_{$i}", $act); } $qb->where($orx); return $qb; } }