From ae6553ae0dae49163b5c376e08f382c6fdf05636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 26 Feb 2015 12:15:36 +0100 Subject: [PATCH] Add timeline to report MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refs #357 and refs #224 Squashed commit of the following: commit 1393a2b283566f428e13160da18487c2a0bbea78 Author: Julien Fastré Date: Thu Feb 26 12:13:56 2015 +0100 add summary_fields in timeline The tests and fixtures are adapted accordingly commit d0374961c2b03a334ff724fbe2995d082d7d7e01 Author: Julien Fastré Date: Thu Feb 26 10:36:56 2015 +0100 fix namespace commit c2d71a17301d923cb20ae295f7d1efef8727a643 Author: Julien Fastré Date: Mon Feb 23 21:59:26 2015 +0100 Improve rendering in person context commit 827d3116a36f8b86bc2dcd79926e42a3d472bb70 Author: Julien Fastré Date: Mon Feb 23 16:34:43 2015 +0100 add test for timeline page commit d93aa527190a6038b4c58dff3af81568c377cd0f Author: Julien Fastré Date: Mon Feb 23 16:34:07 2015 +0100 add message for timeline commit 63de4ddc2c7eca8530b3cc6e122d44840340329d Author: Julien Fastré Date: Mon Feb 23 13:48:32 2015 +0100 create timeline provider --- DataFixtures/ORM/LoadCustomField.php | 2 +- DataFixtures/ORM/LoadCustomFieldsGroup.php | 19 ++- DataFixtures/ORM/LoadReports.php | 2 +- DependencyInjection/ChillReportExtension.php | 14 +- Resources/config/services.yml | 9 +- Resources/translations/messages.fr.yml | 5 +- .../Timeline/report_person_context.html.twig | 23 +++ Tests/Timeline/TimelineProviderTest.php | 157 ++++++++++++++++++ Timeline/TimelineReportProvider.php | 141 ++++++++++++++++ 9 files changed, 362 insertions(+), 10 deletions(-) create mode 100644 Resources/views/Timeline/report_person_context.html.twig create mode 100644 Tests/Timeline/TimelineProviderTest.php create mode 100644 Timeline/TimelineReportProvider.php diff --git a/DataFixtures/ORM/LoadCustomField.php b/DataFixtures/ORM/LoadCustomField.php index 7d45004de..116e2a8e7 100644 --- a/DataFixtures/ORM/LoadCustomField.php +++ b/DataFixtures/ORM/LoadCustomField.php @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -namespace Chill\PersonBundle\DataFixtures\ORM; +namespace Chill\ReportBundle\DataFixtures\ORM; use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\OrderedFixtureInterface; diff --git a/DataFixtures/ORM/LoadCustomFieldsGroup.php b/DataFixtures/ORM/LoadCustomFieldsGroup.php index f926c9df4..fe033069e 100644 --- a/DataFixtures/ORM/LoadCustomFieldsGroup.php +++ b/DataFixtures/ORM/LoadCustomFieldsGroup.php @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -namespace Chill\PersonBundle\DataFixtures\ORM; +namespace Chill\ReportBundle\DataFixtures\ORM; use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\OrderedFixtureInterface; @@ -40,8 +40,13 @@ class LoadCustomFieldsGroup extends AbstractFixture implements OrderedFixtureInt { echo "loading customFieldsGroup...\n"; - $report = $this->createReport($manager, array('fr' => 'Situation de logement')); - $this->addReference('cf_group_report_logement', $report); + $report = $this->createReport($manager, + array('fr' => 'Situation de logement'), + ['summary_fields' => ['has_logement', 'house-desc']]); + $this->addReference( + 'cf_group_report_logement', + $report + ); $report = $this->createReport($manager, array('fr' => 'Alphabétisme')); $this->addReference('cf_group_report_education', $report); @@ -65,13 +70,17 @@ class LoadCustomFieldsGroup extends AbstractFixture implements OrderedFixtureInt * @param array $name * @return CustomFieldsGroup */ - private function createReport(ObjectManager $manager, array $name) + private function createReport( + ObjectManager $manager, + array $name, + array $options = array()) { echo $name['fr']." \n"; $cFGroup = (new CustomFieldsGroup()) ->setName($name) - ->setEntity('Chill\ReportBundle\Entity\Report'); + ->setEntity('Chill\ReportBundle\Entity\Report') + ->setOptions($options); $manager->persist($cFGroup); diff --git a/DataFixtures/ORM/LoadReports.php b/DataFixtures/ORM/LoadReports.php index 8531e0a61..2aba6c286 100644 --- a/DataFixtures/ORM/LoadReports.php +++ b/DataFixtures/ORM/LoadReports.php @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -namespace Chill\PersonBundle\DataFixtures\ORM; +namespace Chill\ReportBundle\DataFixtures\ORM; use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\OrderedFixtureInterface; diff --git a/DependencyInjection/ChillReportExtension.php b/DependencyInjection/ChillReportExtension.php index 1f5d408cf..fb5a285da 100644 --- a/DependencyInjection/ChillReportExtension.php +++ b/DependencyInjection/ChillReportExtension.php @@ -43,7 +43,19 @@ class ChillReportExtension extends Extension implements PrependExtensionInterfac $container->prependExtensionConfig('chill_custom_fields', array('customizables_entities' => array( - array('class' => 'Chill\ReportBundle\Entity\Report', 'name' => 'ReportEntity') + array( + 'class' => 'Chill\ReportBundle\Entity\Report', + 'name' => 'ReportEntity', + 'options' => array( + 'summary_fields' => array( + 'form_type' => 'custom_fields_group_linked_custom_fields', + 'form_options' => + [ + 'multiple' => true, + 'expanded' => false + ] + ) + )) ) ) ); diff --git a/Resources/config/services.yml b/Resources/config/services.yml index 4c06c3b79..f5305da04 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -11,4 +11,11 @@ services: calls: - [setContainer, ["@service_container"]] tags: - - { name: chill.search, alias: 'report' } \ No newline at end of file + - { name: chill.search, alias: 'report' } + + chill.report.timeline: + class: Chill\ReportBundle\Timeline\TimelineReportProvider + arguments: + - '@doctrine.orm.entity_manager' + tags: + - { name: chill.timeline, context: 'person' } \ No newline at end of file diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml index 3b1940502..4b5e591c1 100644 --- a/Resources/translations/messages.fr.yml +++ b/Resources/translations/messages.fr.yml @@ -32,4 +32,7 @@ User: Utilisateur 'You may not set a date argument and a date in default': Vous avez introduit deux dates, l'une avec l'argument date et l'autre en zone de recherche par défaut. Merci d'indiquer l'un ou l'autre 'You must provide either a date:YYYY-mm-dd argument or a YYYY-mm-dd default search': Merci d'indiquer soit un argument date:YYYY-mm-dd, soit une date dans la recherche par défaut. 'Reports search results': Recherche dans les rapports -'%total% reports matching the search "%pattern%"': '{0} Aucun rapport ne correspond à la recherche "%pattern%" | {1} Un rapport correspond à la recherche "%pattern%" | ]1,Inf]%total% rapports correspondent à la recherche "%pattern%"' \ No newline at end of file +'%total% reports matching the search "%pattern%"': '{0} Aucun rapport ne correspond à la recherche "%pattern%" | {1} Un rapport correspond à la recherche "%pattern%" | ]1,Inf]%total% rapports correspondent à la recherche "%pattern%"' + +#timeline +'%user% has filled a %report_label% report on %date%': %user% a ajouté un rapport '%report_label%' le %date% \ No newline at end of file diff --git a/Resources/views/Timeline/report_person_context.html.twig b/Resources/views/Timeline/report_person_context.html.twig new file mode 100644 index 000000000..d19559632 --- /dev/null +++ b/Resources/views/Timeline/report_person_context.html.twig @@ -0,0 +1,23 @@ +
+
+ {{ '%user% has filled a %report_label% report on %date%'|trans( + { + '%user%' : user, + '%report_label%': report.CFGroup.name|localize_translatable_string, + '%date%' : report.date|localizeddate('long', 'none') } + ) }} {{ 'View the report'|trans }} +
+ {% if custom_fields_in_summary|length > 0 %} +
+ {% for field in custom_fields_in_summary %} + {% if field.type == 'title' %} + {{ chill_custom_field_widget(report.cFData, field) }} + {% else %} +
{{ chill_custom_field_label(field) }}
+
{{ chill_custom_field_widget(report.cFData, field) }}
+ {% endif %} + {% endfor %} +
+ {% endif %} +
\ No newline at end of file diff --git a/Tests/Timeline/TimelineProviderTest.php b/Tests/Timeline/TimelineProviderTest.php new file mode 100644 index 000000000..bf18a3eab --- /dev/null +++ b/Tests/Timeline/TimelineProviderTest.php @@ -0,0 +1,157 @@ + + * + * 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\ReportBundle\Tests\Timeline; + +use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; +use Chill\PersonBundle\Entity\Person; +use Chill\ReportBundle\Entity\Report; +use Chill\MainBundle\Tests\TestHelper as MainTestHelper; + +/** + * Test a report is shown into timeline + * + * @author Julien Fastré + * @author Champs Libres + */ +class TimelineProviderTest extends WebTestCase +{ + + /** + * + * @var \Doctrine\ORM\EntityManager + */ + private static $em; + + /** + * + * @var Person + */ + private $person; + + /** + * + * @var Report + */ + private $report; + + /** + * Create a person with a report associated with the person + */ + public function setUp() + { + static::bootKernel(); + + static::$em = static::$kernel->getContainer() + ->get('doctrine.orm.entity_manager'); + + $this->person = (new Person(new \DateTime('2015-05-01'))) + ->setGenre(Person::GENRE_WOMAN) + ->setFirstName('Nelson') + ->setLastName('Mandela'); + static::$em->persist($this->person); + + $this->report = (new Report) + ->setUser(static::$em->getRepository('ChillMainBundle:User') + ->findOneByUsername('chill b_social')) + ->setDate(new \DateTime('2015-05-02')) + ->setPerson($this->person) + ->setCFGroup($this->getHousingCustomFieldsGroup()) + ->setCFData(['has_logement' => 'own_house', + 'house-desc' => 'blah blah']); + + static::$em->persist($this->report); + + + + static::$em->flush(); + + } + + /** + * Test that a report is shown in timeline + */ + public function testTimelineReport() + { + $client = static::createClient(array(), + MainTestHelper::getAuthenticatedClientOptions() + ); + + $crawler = $client->request('GET', '/fr/person/'.$this->person->getId() + .'/timeline'); + + $this->assertTrue($client->getResponse()->isSuccessful(), + 'The page timeline is loaded successfully'); + $this->assertContains('a ajouté un rapport', $crawler->text(), + 'the page contains the text "a publié un rapport"'); + } + + public function testTimelineReportWithSummaryField() + { + //load the page + $client = static::createClient(array(), + MainTestHelper::getAuthenticatedClientOptions() + ); + + $crawler = $client->request('GET', '/fr/person/'.$this->person->getId() + .'/timeline'); + + //performs tests + $this->assertTrue($client->getResponse()->isSuccessful(), + 'The page timeline is loaded successfully'); + $this->assertGreaterThan(0, $crawler->filter('.report .summary') + ->count(), + 'the page contains a .report .summary element'); + $this->assertContains('blah blah', $crawler->filter('.report .summary') + ->text(), + 'the page contains the text "blah blah"'); + $this->assertContains('Propriétaire', $crawler->filter('.report .summary') + ->text(), + 'the page contains the mention "Propriétaire"'); + } + + /** + * get a random custom fields group + * + * @return \Chill\CustomFieldsBundle\Entity\CustomFieldsGroup + */ + private function getHousingCustomFieldsGroup() + { + $groups = static::$em + ->getRepository('ChillCustomFieldsBundle:CustomFieldsGroup') + ->findAll(); + + foreach ($groups as $group) { + if ($group->getName()['fr'] === 'Situation de logement') { + return $group; + } + } + + return $groups[rand(0, count($groups) -1)]; + } + + + + public function tearDown() + { + //static::$em->remove($this->person); + //static::$em->remove($this->report); + } +} diff --git a/Timeline/TimelineReportProvider.php b/Timeline/TimelineReportProvider.php new file mode 100644 index 000000000..c9138c9d4 --- /dev/null +++ b/Timeline/TimelineReportProvider.php @@ -0,0 +1,141 @@ + + * + * 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\ReportBundle\Timeline; + +use Chill\MainBundle\Timeline\TimelineProviderInterface; +use Doctrine\ORM\EntityManager; + +/** + * Provide report for inclusion in timeline + * + * @author Julien Fastré + * @author Champs Libres + */ +class TimelineReportProvider implements TimelineProviderInterface +{ + + /** + * + * @var EntityManager + */ + protected $em; + + public function __construct(EntityManager $em) + { + $this->em = $em; + } + + /** + * + * {@inheritDoc} + */ + public function fetchQuery($context, array $args) + { + $this->checkContext($context); + + $metadata = $this->em->getClassMetadata('ChillReportBundle:Report'); + + return array( + 'id' => $metadata->getColumnName('id'), + 'type' => 'report', + 'date' => $metadata->getColumnName('date'), + 'FROM' => $metadata->getTableName(), + 'WHERE' => sprintf('%s = %d', + $metadata + ->getAssociationMapping('person')['joinColumns'][0]['name'], + $args['person']->getId()) + ); + } + + /** + * + * {@inheritDoc} + */ + public function getEntities(array $ids) + { + $reports = $this->em->getRepository('ChillReportBundle:Report') + ->findBy(array('id' => $ids)); + + $result = array(); + foreach($reports as $report) { + $result[$report->getId()] = $report; + } + + return $result; + } + + /** + * + * {@inheritDoc} + */ + public function getEntityTemplate($entity, $context, array $args) + { + $this->checkContext($context); + + //gather all custom fields which should appears in summary + $customFieldsInSummary = array(); + if (array_key_exists('summary_fields', $entity->getCFGroup()->getOptions())) { + + foreach ($entity->getCFGroup()->getCustomFields() as $customField) { + if (in_array($customField->getSlug(), + $entity->getCFGroup()->getOptions()['summary_fields'])) { + $customFieldsInSummary[] = $customField; + } + } + } + + + + return array( + 'template' => 'ChillReportBundle:Timeline:report_person_context.html.twig', + 'template_data' => array( + 'report' => $entity, + 'custom_fields_in_summary' => $customFieldsInSummary, + 'person' => $args['person'], + 'user' => $entity->getUser() + ) + ); + } + + /** + * + * {@inheritDoc} + */ + public function supportsType($type) + { + return $type === 'report'; + } + + /** + * check if the context is supported + * + * @param string $context + * @throws \LogicException if the context is not supported + */ + private function checkContext($context) + { + if ($context !== 'person') { + throw new \LogicException("The context '$context' is not " + . "supported. Currently only 'person' is supported"); + } + } + +}