authorizationHelper = $authorizationHelper; } /** * Count the tasks for given parameters. * * The parameters are describe in @see SingleTaskRepository::filterByParameters. * * @see SingleTaskRepository::filterByParameters * @param array $params * @param User $currentUser * @return int */ public function countByParameters($params, User $currentUser = null) { $qb = $this->createQueryBuilder('st') ->select('COUNT(st)'); $this->buildQuery($qb, $params, $currentUser); return (int) $qb ->getQuery() ->getSingleScalarResult() ; } /** * Find task for given parameters. * * Available parameters: * * - `person` : filter by person associated with the task ; * - `user` : filter by user that created the task ; * - `scope` : filter by scope associated with the task ; * - `date_status`: type of task. To choose between : * `ended`, `warning`, `current`, `not_started` ; * - `is_closed`: boolean. Indicate if the tasks must be closed (true) or * opened * - `types`: string[] an array of task types * * @param type $params * @param User $currentUser * @param int $firstResult * @param int $maxResults * @return type */ public function findByParameters($params, User $currentUser, int $firstResult = 0, int $maxResults = 50) { $qb = $this->createQueryBuilder('st'); $this->buildQuery($qb, $params, $currentUser); $qb ->setMaxResults($maxResults) ->setFirstResult($firstResult) ; return $qb ->getQuery() ->getResult() ; } protected function buildQuery(QueryBuilder $qb, $params, User $currentUser = null) { if (NULL !== $currentUser) { $this->buildACLQuery($qb, $currentUser); } if (\array_key_exists('person', $params) and !empty($params['person'])) { $qb->andWhere($qb->expr()->eq('st.person', ':person')); $qb->setParameter('person', $params['person']); } elseif (\array_key_exists('center', $params)) { if ($params['center'] instanceof Center) { $qb->join('st.person', 'person'); $qb->andWhere($qb->expr()->eq('person.center', ':center')); $qb->setParameter('center', $params['center']); } else { throw new \UnexpectedValueException("params 'center' should be an instance of ".Center::class); } } if (\array_key_exists('unassigned', $params) and $params['unassigned'] === true) { if (\array_key_exists('user', $params) and !empty($params['user'])) { throw new \UnexpectedValueException("You should not require for " . "unassigned tasks and tasks assigned to some user."); } $qb->andWhere($qb->expr()->isNull('st.assignee')); } if (\array_key_exists('user', $params) and !empty($params['user'])) { $qb->andWhere($qb->expr()->eq('st.assignee', ':user')); $qb->setParameter('user', $params['user']); } if (\array_key_exists('scope', $params) and !empty($params['scope'])) { $qb->andWhere($qb->expr()->eq('st.circle', ':scope')); $qb->setParameter('scope', $params['scope']); } if (\array_key_exists('types', $params) && $params['types'] !== NULL) { if (count($params['types']) > 0) { $qb->andWhere($qb->expr()->in('st.type', ':types')); $qb->setParameter('types', $params['types']); } } if (\array_key_exists('date_status', $params) and !empty($params['date_status'])) { $this->addTypeFilter($qb, $params); } if (\array_key_exists('is_closed', $params)) { $qb->andWhere($this->buildIsClosed($qb, !$params['is_closed'])); } } protected function addTypeFilter(QueryBuilder $qb, $params) { $andWhere = $qb->expr()->andX(); switch ($params['date_status']) { case self::DATE_STATUS_ENDED: $andWhere ->add($this->buildNowIsAfterEndDate($qb)) ; break; case self::DATE_STATUS_WARNING: $andWhere ->add($this->buildNowIsAfterEndDate($qb, true)) ->add($this->buildNowIsAfterWarningDate($qb)) ; break; case self::DATE_STATUS_CURRENT: // st.endDate is NULL or (st.endDate is not null and st.endDate < now)) $andWhere ->add($this->buildNowIsAfterEndDate($qb, true)) ->add($this->buildNowIsAfterWarningDate($qb, true)) ->add($this->buildNowIsAfterStartDate($qb, false)) ; break; case self::DATE_STATUS_NOT_STARTED: $andWhere ->add($this->buildNowIsAfterEndDate($qb, true)) ->add($this->buildNowIsAfterWarningDate($qb, true)) ->add($this->buildNowIsAfterStartDate($qb, true)) ; } $qb->setParameter('now', new \DateTime('today'), Type::DATE); $qb->andWhere($andWhere); } private function buildNowIsAfterEndDate(QueryBuilder $qb, $negative = false) { if ($negative === false) { return $qb->expr()->andX() ->add($qb->expr()->isNotNull('st.endDate')) ->add($qb->expr()->lte('st.endDate', ':now')) ; } else { return $qb->expr()->orX() ->add( $qb->expr()->andX() ->add($qb->expr()->isNotNull('st.endDate')) ->add($qb->expr()->gt('st.endDate', ':now')) ) ->add($qb->expr()->isNull('st.endDate')) ; } } private function buildNowIsAfterWarningDate(QueryBuilder $qb, bool $negative = false) { if ($negative === false) { return $qb->expr()->andX() ->add($qb->expr()->lte( $qb->expr()->diff('st.endDate', 'st.warningInterval'), ':now' ) ); } else { return $qb->expr()->orX() ->add( $qb->expr()->andX() ->add($qb->expr()->isNotNull('st.endDate')) ->add($qb->expr()->isNotNull('st.warningInterval')) ->add($qb->expr()->gt( $qb->expr()->diff('st.endDate', 'st.warningInterval'), ':now' ) ) ) ->add($qb->expr()->isNull('st.endDate')) ->add($qb->expr()->isNull('st.warningInterval')) ; } } private function buildNowIsAfterStartDate(QueryBuilder $qb, bool $negative = false) { if ($negative === false) { return $qb->expr()->orX() ->add($qb->expr()->lte('st.startDate', ':now')) ->add($qb->expr()->isNull('st.startDate')) ; } else { return $qb->expr()->andX() ->add($qb->expr()->gt('st.startDate', ':now')) ->add($qb->expr()->isNotNull('st.startDate')) ; } } private function buildIsClosed(QueryBuilder $qb, bool $negative = false) { if ($negative === false) { return $qb->expr()->eq('st.closed', "'TRUE'"); } else { return $qb->expr()->eq('st.closed', "'FALSE'"); } } protected function buildACLQuery(QueryBuilder $qb, User $currentUser) { if (NULL === $this->authorizationHelper) { throw new \LogicException("Injecting the authorization helper is " . "required to run this query. Please use dependency injection " . "to initialize this repository or use the method " . "`setAuthorizationHelper`"); } $role = new Role(TaskVoter::SHOW); $qb->join('st.person', 'p'); $centers = $this->authorizationHelper ->getReachableCenters($currentUser, $role) ; $i = 0; $where = $qb->expr()->orX(); foreach($centers as $center) { $circles = $this->authorizationHelper ->getReachableCircles($currentUser, $role, $center); $centerWhere = $qb->expr()->andX(); $centerWhere->add($qb->expr()->eq('p.center', ':center_'.$i)); $qb->setParameter('center_'.$i, $center); $centerWhere->add($qb->expr()->in('st.circle', ':circles_'.$i)); $qb->setParameter('circles_'.$i, $circles); $where->add($centerWhere); $i ++; } $qb->where($where); } }