em = $em; $this->helper = $helper; if (!$tokenStorage->getToken()->getUser() instanceof \Chill\MainBundle\Entity\User) { throw new RuntimeException('an user must be associated with token'); } $this->user = $tokenStorage->getToken()->getUser(); } public function getOrder() { return 10000; } public function isActiveByDefault() { return false; } public function renderResult(array $terms, $start = 0, $limit = 50, array $options = [], $format = 'html') { return $this->container->get('templating')->render('ChillReportBundle:Search:results.html.twig', [ 'reports' => $this->getReports($terms, $start, $limit), 'total' => $this->count($terms), 'pattern' => $this->recomposePattern($terms, ['date'], 'report'), ]); } public function supports($domain, $format = 'html') { return 'report' === $domain; } private function addACL(QueryBuilder $qb) { //adding join $qb->join('r.person', 'p'); $role = new Role('CHILL_REPORT_SEE'); $reachableCenters = $this->helper->getReachableCenters($this->user, $role); $whereElement = $qb->expr()->orX(); $i = 0; foreach ($reachableCenters as $center) { $reachableScopesId = array_map( static function (Scope $scope) { return $scope->getId(); }, $this->helper->getReachableScopes($this->user, $role, $center) ); $whereElement->add( $qb->expr()->andX( $qb->expr()->eq('p.center', ':center_' . $i), $qb->expr()->in('r.scope', ':reachable_scopes_' . $i) ) ); $qb->setParameter('center_' . $i, $center); $qb->setParameter('reachable_scopes_' . $i, $reachableScopesId); } return $whereElement; } /** * @param array $terms the terms * * @return \Doctrine\ORM\QueryBuilder */ private function buildQuery(array $terms) { $query = $this->em->createQueryBuilder(); $query->from('ChillReportBundle:Report', 'r'); //throw a parsing exception if key 'date' and default is set if (array_key_exists('date', $terms) && '' !== $terms['_default']) { throw new ParsingException('You may not set a date argument and a date in default'); } //throw a parsing exception if no argument except report if (!array_key_exists('date', $terms) && '' === $terms['_default']) { throw new ParsingException('You must provide either a date:YYYY-mm-dd argument or a YYYY-mm-dd default search'); } if (array_key_exists('date', $terms)) { $query->andWhere($query->expr()->eq('r.date', ':date')) ->setParameter('date', $this->parseDate($terms['date'])); } elseif (array_key_exists('_default', $terms)) { $query->andWhere($query->expr()->eq('r.date', ':date')) ->setParameter('date', $this->parseDate($terms['_default'])); } $query->andWhere($this->addACL($query)); return $query; } private function count(array $terms) { $qb = $this->buildQuery($terms); $qb->select('COUNT(r.id)'); return $qb->getQuery()->getSingleScalarResult(); } private function getReports(array $terms, $start, $limit) { $qb = $this->buildQuery($terms); $qb->select('r') ->setMaxResults($limit) ->setFirstResult($start) ->orderBy('r.date', 'desc'); $reportQuery = $qb->getQuery(); $reportQuery->setFetchMode('Chill\\ReportBundle\\Entity\\Report', 'person', \Doctrine\ORM\Mapping\ClassMetadata::FETCH_EAGER); return $reportQuery->getResult(); } }