centerResolverDispatcher = $centerResolverDispatcher; $this->em = $em; $this->security = $security; $this->authorizationHelper = $authorizationHelper; } public function findByCurrentUsersTasks( ?string $pattern = null, ?array $flags = [], ?int $start = 0, ?int $limit = 50, ?array $orderBy = [] ): array { $qb = $this->buildQueryMyTasks($pattern, $flags); return $this->getResult($qb, $start, $limit, $orderBy); } public function countByCurrentUsersTasks( ?string $pattern = null, ?array $flags = [] ): int { return $this->buildQueryMyTasks($pattern, $flags) ->select('COUNT(t)') ->getQuery()->getSingleScalarResult(); } public function findByCourse( AccompanyingPeriod $course, ?string $pattern = null, ?array $flags = [], ?int $start = 0, ?int $limit = 50, ?array $orderBy = [] ): array { $qb = $this->buildQueryByCourse($course, $pattern, $flags); $qb = $this->addACL($qb, $course); return $this->getResult($qb, $start, $limit, $orderBy); } public function countByCourse( AccompanyingPeriod $course, ?string $pattern = null, ?array $flags = [] ): int { $qb = $this->buildQueryByCourse($course, $pattern, $flags); return $this ->addACL($qb, $course) ->select('COUNT(t)') ->getQuery()->getSingleScalarResult(); } public function buildQueryByCourse( AccompanyingPeriod $course, ?string $pattern = null, ?array $flags = [] ) : QueryBuilder { $qb = $this->buildBaseQuery($pattern, $flags); return $qb ->andWhere($qb->expr()->eq('t.course', ':course')) ->setParameter('course', $course) ; } public function buildQueryMyTasks( ?string $pattern = null, ?array $flags = [] ): QueryBuilder { $qb = $this->buildBaseQuery($pattern, $flags); return $qb ->andWhere($qb->expr()->eq('t.assignee', ':user')) ->setParameter('user', $this->security->getUser()) ; } public function getResult( QueryBuilder $qb, ?int $start = 0, ?int $limit = 50, ?array $orderBy = [] ): array { $qb->select('t'); $qb ->setFirstResult($start) ->setMaxResults($limit) ; foreach ($orderBy as $field => $direction) { $qb->addOrderBy('t.'.$field, $direction); } return $qb->getQuery()->getResult(); } public function addACL( QueryBuilder $qb, $entity ): QueryBuilder { $scopes = $this->authorizationHelper->getReachableScopes($this->security->getUser(), TaskVoter::SHOW, $this->centerResolverDispatcher->resolveCenter($entity)); return $qb->andWhere($qb->expr()->in('t.circle', ':scopes')) ->setParameter('scopes', $scopes); } public function buildBaseQuery ( ?string $pattern = null, ?array $flags = [] ): QueryBuilder { $qb = $this->em->createQueryBuilder(); $qb ->from(SingleTask::class, 't') ; if (!empty($pattern)) { $qb->andWhere($qb->expr()->like('LOWER(UNACCENT(t.title))', 'LOWER(UNACCENT(:pattern))')) ->setParameter('pattern', '%'.$pattern.'%') ; } if (count($flags) > 0) { $orXDate = $qb->expr()->orX(); $orXState = $qb->expr()->orX(); $now = new \DateTime(); foreach ($flags as $key => $flag) { switch ($flag) { case 'no-alert': $orXDate ->add( $qb->expr()->orX( $qb->expr()->isNull('t.endDate'), $qb->expr()->gte('t.endDate - COALESCE(t.warningInterval, :intervalBlank)', ':now') ) ); $qb ->setParameter('intervalBlank', new \DateInterval('P0D')) ->setParameter('now', $now); break; case 'warning': $orXDate ->add( $qb->expr()->andX( $qb->expr()->not($qb->expr()->isNull('t.endDate')), $qb->expr()->not($qb->expr()->isNull('t.warningInterval')), $qb->expr()->gte('t.endDate - t.warningInterval', ':now'), $qb->expr()->lt('t.endDate', ':now') ) ); $qb ->setParameter('now', $now); break; case 'alert': $orXDate ->add( $qb->expr()->andX( $qb->expr()->not($qb->expr()->isNull('t.endDate')), $qb->expr()->lte('t.endDate', ':now') ) ); $qb ->setParameter('now', $now); break; case 'state_new': $orXState ->add( "JSONB_ARRAY_LENGTH(t.currentStates) = 0" ); break; case \substr($flag, 0, 6) === 'state_': $state = \substr($flag, 6); $orXState ->add( "JSONB_EXISTS_IN_ARRAY(t.currentStates, :state_$key) = 'TRUE'" ); $qb->setParameter("state_$key", $state); break; default: throw new \LogicException("this flag is not supported: $flag"); } } if ($orXDate->count() > 0) { $qb->andWhere($orXDate); } if ($orXState->count() > 0) { $qb->andWhere($orXState); } } return $qb; } }