* @author Champs Libres */ class EventSearch extends AbstractSearch { /** * * @var EntityRepository */ private $er; /** * * @var \Chill\MainBundle\Entity\User */ private $user; /** * * @var AuthorizationHelper */ private $helper; /** * * @var TemplatingEngine */ private $templating; /** * * @var PaginatorFactory */ private $paginationFactory; const NAME = 'event_regular'; public function __construct( TokenStorageInterface $tokenStorage, EntityRepository $eventRepository, AuthorizationHelper $authorizationHelper, TemplatingEngine $templating, PaginatorFactory $paginatorFactory ) { $this->user = $tokenStorage->getToken()->getUser(); $this->er = $eventRepository; $this->helper = $authorizationHelper; $this->templating = $templating; $this->paginationFactory = $paginatorFactory; } public function supports($domain, $format) { return 'event' === $domain or 'events' === $domain; } public function isActiveByDefault() { return true; } public function getOrder() { return 3000; } public function renderResult(array $terms, $start = 0, $limit = 50, array $options = array(), $format = 'html') { $total = $this->count($terms); $paginator = $this->paginationFactory->create($total); if ($format === 'html') { return $this->templating->render('ChillEventBundle:Event:list.html.twig', array( 'events' => $this->search($terms, $start, $limit, $options), 'pattern' => $this->recomposePattern($terms, $this->getAvailableTerms(), $terms['_domain']), 'total' => $total, 'start' => $start, 'preview' => $options[SearchInterface::SEARCH_PREVIEW_OPTION], 'paginator' => $paginator, 'search_name' => self::NAME )); } else if ($format === 'json') { $results = []; $search = $this->search($terms, $start, $limit, $options); foreach ($search as $item) { $results[] = [ 'id' => $item->getId(), 'text' => $item->getDate()->format('d/m/Y, H:i') . ' → ' . // $item->getType()->getName()['fr'] . ': ' . // display the type of event $item->getName() ]; } return [ 'results' => $results, 'pagination' => [ 'more' => $paginator->hasNextPage() ] ]; } } protected function getAvailableTerms() { return array('date-from', 'date-to', 'name', 'date'); } protected function search(array $terms, $start, $limit, $options) { $qb = $this->er->createQueryBuilder('e'); $qb->select('e'); $this->composeQuery($qb, $terms) ->setMaxResults($limit) ->setFirstResult($start) ->orderBy('e.date', 'DESC') ; return $qb->getQuery()->getResult(); } protected function count(array $terms) { $qb = $this->er->createQueryBuilder('e'); $qb->select('COUNT(e)'); $this->composeQuery($qb, $terms) ; return $qb->getQuery()->getSingleScalarResult(); } protected function composeQuery(QueryBuilder &$qb, $terms) { // add security clauses $reachableCenters = $this->helper ->getReachableCenters($this->user, new Role('CHILL_EVENT_SEE')); if (count($reachableCenters) === 0) { // add a clause to block all events $where = $qb->expr()->isNull('e.center'); $qb->andWhere($where); } else { $n = 0; $orWhere = $qb->expr()->orX(); foreach ($reachableCenters as $center) { $circles = $this->helper->getReachableScopes($this->user, new Role('CHILL_EVENT_SEE'), $center); $where = $qb->expr()->andX( $qb->expr()->eq('e.center', ':center_'.$n), $qb->expr()->in('e.circle', ':circle_'.$n) ); $qb->setParameter('center_'.$n, $center); $qb->setParameter('circle_'.$n, $circles); $orWhere->add($where); } $qb->andWhere($orWhere); } if ( (isset($terms['name']) OR isset($terms['_default'])) AND (!empty($terms['name']) OR !empty($terms['_default']))) { // the form with name:"xyz" has precedence $name = isset($terms['name']) ? $terms['name'] : $terms['_default']; $where = $qb->expr()->like('UNACCENT(LOWER(e.name))', ':name'); $qb->setParameter('name', '%'.$name.'%'); $qb->andWhere($where); } if (isset($terms['date'])) { $date = $this->parseDate($terms['date']); $where = $qb->expr()->eq('e.date', ':date'); $qb->setParameter('date', $date); $qb->andWhere($where); } if (isset($terms['date-from'])) { $date = $this->parseDate($terms['date-from']); $where = $qb->expr()->gte('e.date', ':datefrom'); $qb->setParameter('datefrom', $date); $qb->andWhere($where); } if (isset($terms['date-to'])) { $date = $this->parseDate($terms['date-to']); $where = $qb->expr()->lte('e.date', ':dateto'); $qb->setParameter('dateto', $date); $qb->andWhere($where); } return $qb; } }