diff --git a/src/Bundle/ChillMainBundle/Timeline/TimelineBuilder.php b/src/Bundle/ChillMainBundle/Timeline/TimelineBuilder.php index 6d061d0a2..454c2fb7d 100644 --- a/src/Bundle/ChillMainBundle/Timeline/TimelineBuilder.php +++ b/src/Bundle/ChillMainBundle/Timeline/TimelineBuilder.php @@ -29,40 +29,40 @@ use Symfony\Component\DependencyInjection\ContainerAwareInterface; * * @author Julien Fastré */ -class TimelineBuilder implements ContainerAwareInterface +class TimelineBuilder implements ContainerAwareInterface, TimelineBuilderInterface { - + use \Symfony\Component\DependencyInjection\ContainerAwareTrait; - + /** * * @var \Doctrine\ORM\EntityManagerInterface */ private $em; - + /** * Record provider - * + * * This array has the structure `[ 'service id' => $service ]` * * @var TimelineProviderInterface[] */ private $providers = []; - + /** * Record provider and their context - * + * * This array has the structure `[ 'context' => [ 'service id' ] ]` * * @var array */ private $providersByContext = []; - + public function __construct(EntityManagerInterface $em) { $this->em = $em; } - + /** * return an HTML string with timeline * @@ -79,18 +79,18 @@ class TimelineBuilder implements ContainerAwareInterface public function getTimelineHTML($context, array $args, $firstItem = 0, $number = 20) { $union = $this->buildUnionQuery($context, $args); - + //add ORDER BY clause and LIMIT $query = $union . sprintf(' ORDER BY date DESC LIMIT %d OFFSET %d', $number, $firstItem); - + // run query and handle results $fetched = $this->runUnionQuery($query); $entitiesByKey = $this->getEntities($fetched, $context); - + return $this->render($fetched, $entitiesByKey, $context, $args); } - + /** * Return the number of items for the given context and args * @@ -101,17 +101,17 @@ class TimelineBuilder implements ContainerAwareInterface public function countItems($context, array $args) { $union = $this->buildUnionQuery($context, $args); - + // embed the union query inside a count query $count = sprintf('SELECT COUNT(sq.id) AS total FROM (%s) as sq', $union); - + $rsm = (new ResultSetMapping()) ->addScalarResult('total', 'total', Type::INTEGER); - + return $this->em->createNativeQuery($count, $rsm) ->getSingleScalarResult(); } - + /** * add a provider id * @@ -125,7 +125,7 @@ class TimelineBuilder implements ContainerAwareInterface $this->providersByContext[$context][] = $id; $this->providers[$id] = $provider; } - + /** * Get providers by context * @@ -139,16 +139,16 @@ class TimelineBuilder implements ContainerAwareInterface throw new \LogicException(sprintf('No builders have been defined for "%s"' . ' context', $context)); } - + $providers = []; - + foreach($this->providersByContext[$context] as $providerId) { $providers[] = $this->providers[$providerId]; } - + return $providers; } - + /** * build the UNION query with all providers * @@ -170,10 +170,10 @@ class TimelineBuilder implements ContainerAwareInterface $append = ($union === '') ? $select : ' UNION '.$select; $union .= $append; } - + return $union; } - + /** * return the SQL SELECT query as a string, * @@ -186,7 +186,7 @@ class TimelineBuilder implements ContainerAwareInterface private function buildSelectQuery(TimelineProviderInterface $provider, $context, array $args) { $data = $provider->fetchQuery($context, $args); - + return sprintf( 'SELECT %s AS id, ' . '%s AS "date", ' @@ -199,7 +199,7 @@ class TimelineBuilder implements ContainerAwareInterface $data['FROM'], $data['WHERE']); } - + /** * run the UNION query and return result as an array * @@ -212,11 +212,11 @@ class TimelineBuilder implements ContainerAwareInterface ->addScalarResult('id', 'id') ->addScalarResult('type', 'type') ->addScalarResult('date', 'date'); - + return $this->em->createNativeQuery($query, $resultSetMapping) ->getArrayResult(); } - + /** * * @param array $queriedIds @@ -227,11 +227,11 @@ class TimelineBuilder implements ContainerAwareInterface { //gather entities by type to pass all id with same type to the TimelineProvider. $idsByType = array(); - + foreach($queriedIds as $result) { $idsByType[$result['type']][] = $result['id']; } - + //fetch entities from providers $entitiesByType = array(); foreach ($idsByType as $type => $ids) { @@ -243,10 +243,10 @@ class TimelineBuilder implements ContainerAwareInterface } } } - + return $entitiesByType; } - + /** * render the timeline as HTML * @@ -269,17 +269,17 @@ class TimelineBuilder implements ContainerAwareInterface $timelineEntry['date'] = new \DateTime($result['date']); $timelineEntry['template'] = $data['template']; $timelineEntry['template_data'] = $data['template_data']; - + $timelineEntries[] = $timelineEntry; } - + return $this->container->get('templating') ->render('@ChillMain/Timeline/index.html.twig', array( 'results' => $timelineEntries )); - + } - + /** * get the template data from the provider for the given entity, by type. * diff --git a/src/Bundle/ChillMainBundle/Timeline/TimelineBuilderInterface.php b/src/Bundle/ChillMainBundle/Timeline/TimelineBuilderInterface.php new file mode 100644 index 000000000..b80a4771c --- /dev/null +++ b/src/Bundle/ChillMainBundle/Timeline/TimelineBuilderInterface.php @@ -0,0 +1,24 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +namespace Chill\MainBundle\Timeline; + +interface TimelineBuilderInterface +{ +} diff --git a/src/Bundle/ChillMainBundle/config/services/timeline.yaml b/src/Bundle/ChillMainBundle/config/services/timeline.yaml index 241f6a6f1..094a742d8 100644 --- a/src/Bundle/ChillMainBundle/config/services/timeline.yaml +++ b/src/Bundle/ChillMainBundle/config/services/timeline.yaml @@ -4,4 +4,6 @@ services: arguments: - "@doctrine.orm.entity_manager" calls: - - [ setContainer, ["@service_container"]] \ No newline at end of file + - [ setContainer, ["@service_container"]] + + Chill\MainBundle\Timeline\TimelineBuilderInterface: "@chill_main.timeline_builder" diff --git a/src/Bundle/ChillPersonBundle/src/Controller/TimelinePersonController.php b/src/Bundle/ChillPersonBundle/src/Controller/TimelinePersonController.php index 43d6c1103..c1976f7f3 100644 --- a/src/Bundle/ChillPersonBundle/src/Controller/TimelinePersonController.php +++ b/src/Bundle/ChillPersonBundle/src/Controller/TimelinePersonController.php @@ -26,6 +26,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; use Chill\MainBundle\Timeline\TimelineBuilder; use Chill\MainBundle\Pagination\PaginatorFactory; +use Chill\MainBundle\Timeline\TimelineBuilderInterface; use Chill\PersonBundle\Security\Authorization\PersonVoter; use Symfony\Component\Routing\Annotation\Route; @@ -37,24 +38,24 @@ use Symfony\Component\Routing\Annotation\Route; */ class TimelinePersonController extends AbstractController { - + /** * @var EventDispatcherInterface */ protected $eventDispatcher; - + /** * - * @var TimelineBuilder + * @var TimelineBuilderInterface */ protected $timelineBuilder; - + /** * * @var PaginatorFactory */ protected $paginatorFactory; - + /** * TimelinePersonController constructor. * @@ -62,7 +63,7 @@ class TimelinePersonController extends AbstractController */ public function __construct( EventDispatcherInterface $eventDispatcher, - TimelineBuilder $timelineBuilder, + TimelineBuilderInterface $timelineBuilder, PaginatorFactory $paginatorFactory ) { $this->eventDispatcher = $eventDispatcher; @@ -93,22 +94,22 @@ class TimelinePersonController extends AbstractController if ($person === NULL) { throw $this->createNotFoundException(); } - + $this->denyAccessUnlessGranted(PersonVoter::SEE, $person); - - $nbItems = $this->timelineBuilder->countItems('person', + + $nbItems = $this->timelineBuilder->countItems('person', [ 'person' => $person ] ); - + $paginator = $this->paginatorFactory->create($nbItems); - + $event = new PrivacyEvent($person, array('action' => 'timeline')); $this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event); - + return $this->render('ChillPersonBundle:Timeline:index.html.twig', array ( 'timeline' => $this->timelineBuilder->getTimelineHTML( - 'person', + 'person', array('person' => $person), $paginator->getCurrentPage()->getFirstItemNumber(), $paginator->getItemsPerPage()