diff --git a/FEATURES/121023 b/FEATURES/121023 new file mode 100644 index 0000000000000000000000000000000000000000..6b47029120b6b294fccc3f7dee27895078c2081e --- /dev/null +++ b/FEATURES/121023 @@ -0,0 +1,10 @@ + '121023' => + ['Label' => $this->_('Ajout du filtre ville dans la boite Agenda'), + 'Desc' => 'Possibilité de filtrer les évenements par ville', + 'Image' => '', + 'Video' => '', + 'Category' => 'Agenda', + 'Right' => function($feature_description, $user) {return true;}, + 'Wiki' => 'http://wiki.bokeh-library-portal.org/index.php?title=Param%C3%A9trer_le_module_Calendrier#Selection_de_filtres', + 'Test' => '', + 'Date' => '2020-11-12'], \ No newline at end of file diff --git a/VERSIONS_WIP/121023 b/VERSIONS_WIP/121023 new file mode 100644 index 0000000000000000000000000000000000000000..6764bdb1ef94f5ccacd2989cedd8b1249162cf29 --- /dev/null +++ b/VERSIONS_WIP/121023 @@ -0,0 +1 @@ + - ticket #121023 : Agenda : possibilité de filtrer les évenements par ville \ No newline at end of file diff --git a/library/Class/Article.php b/library/Class/Article.php index b67073652a8f1b19a3e66629f807e15fea50b2c4..afc750af2698fa7fc184064d6d6073128af2b538 100644 --- a/library/Class/Article.php +++ b/library/Class/Article.php @@ -293,6 +293,19 @@ class ArticleLoader extends Storm_Model_Loader { } + protected function _byPlaceTown($town) { + if (!$town || '' == $town) + return $this; + $this->_select + ->join('lieux', + 'lieux.ID = cms_article.ID_LIEU', + array()) + ->where('trim(lieux.VILLE) like ?', $town); + + return $this; + } + + protected function _byCustomFields($custom_fields) { foreach ($custom_fields as $id => $value) { $this->_select @@ -342,6 +355,7 @@ class ArticleLoader extends Storm_Model_Loader { 'events_only' => false, // filtre que les évènements, 'published' => true, // seulement les articles dont les date de debut / fin incluent le jour en cours, 'id_lieu' => null, // id du lieu Class_Lieu + 'place_town' => null, 'display_mode' => 'Title', 'custom_fields' => []]; } @@ -388,6 +402,7 @@ class ArticleLoader extends Storm_Model_Loader { ->_publishedNow() ->_byIdBib($this->_id_bib) ->_byIdLieu($this->_id_lieu) + ->_byPlaceTown($preferences['place_town']) ->_whereSelectionIn($this->_id_articles, $this->_id_categories) ->_whereEventDateIn($this->_event_date) ->_whereEventStartAfter($this->_event_start_after) diff --git a/library/Class/Calendar.php b/library/Class/Calendar.php index 89401fd4f37b847711aaf8677d5b6309fa14dcc6..a04851a259374d56ac21aaa7f067d2f3c23809ac 100644 --- a/library/Class/Calendar.php +++ b/library/Class/Calendar.php @@ -154,11 +154,17 @@ class Class_Calendar { protected function _loadArticles($extra_prefs) { $id_lieu = $this->getPlaceParam(); - - if ( (0 === strpos($this->id_module, 'library_')) && (!$id_lieu)) + $town = $this->_getParam('place_town', null); + if ( (0 === strpos($this->id_module, 'library_')) + && (!$id_lieu) + && !$town) return []; + $prefs = []; + if ($town) + $prefs['place_town'] = $town; - $prefs = array_merge(['display_order' => (isset($this->preferences['display_order']) + $prefs = array_merge($prefs, + ['display_order' => (isset($this->preferences['display_order']) ? $this->preferences['display_order'] : $this->preferences['order']), 'id_categorie' => $this->_getCategoriesIds(), diff --git a/library/Class/Systeme/ModulesAccueil/Calendrier.php b/library/Class/Systeme/ModulesAccueil/Calendrier.php index 72c58a72981996cdf3e492cfb53c4d8018114c71..a9b9e9436daba78c847bf64564951132ec515674 100644 --- a/library/Class/Systeme/ModulesAccueil/Calendrier.php +++ b/library/Class/Systeme/ModulesAccueil/Calendrier.php @@ -62,7 +62,8 @@ class Class_Systeme_ModulesAccueil_Calendrier extends Class_Systeme_ModulesAccue public function getAvailableFilters() { $available_filters = ['day' => $this->_('Date'), 'date' => $this->_('Mois'), - 'place' => $this->_('Lieu')]; + 'place' => $this->_('Lieu'), + 'place_town' => $this->_('Ville')]; $custom_fields = Class_CustomField_Model::getModel('Article')->getFields(); diff --git a/library/Class/Systeme/ModulesAccueil/Library.php b/library/Class/Systeme/ModulesAccueil/Library.php index 3e21bc8a629ed9b9d22375842dfe37ea6a407638..81bbeeb507fc37b51ef8af78fbee35b3a84fd862 100644 --- a/library/Class/Systeme/ModulesAccueil/Library.php +++ b/library/Class/Systeme/ModulesAccueil/Library.php @@ -37,6 +37,7 @@ class Class_Systeme_ModulesAccueil_Library extends Class_Systeme_ModulesAccueil_ FILTER_OPENING = 'opening', FILTER_TOWN = 'town', + FILTER_PLACE_TOWN = 'place_town', FILTER_TERRITORY = 'territory', FILTER_SEARCH = 'search', diff --git a/library/ZendAfi/View/Helper/Filters/Element.php b/library/ZendAfi/View/Helper/Filters/Element.php index fe9047a62a9e987e7535e5474773cf578c27f326..da0a37f8d3fd55c118bc92a7eae5c3c34b6ea87b 100644 --- a/library/ZendAfi/View/Helper/Filters/Element.php +++ b/library/ZendAfi/View/Helper/Filters/Element.php @@ -33,7 +33,7 @@ abstract class ZendAfi_View_Helper_Filters_Element extends ZendAfi_View_Helper_B if (preg_match('/^custom_field_(\d+)/', $filter, $matches)) return (new ZendAfi_View_Helper_Filters_Element_CustomField($matches[1]))->setFilter($filter); - $class = 'ZendAfi_View_Helper_Filters_Element_' . ucfirst($filter); + $class = 'ZendAfi_View_Helper_Filters_Element_' . Storm_Inflector::camelize($filter); if (!class_exists($class)) $class = 'ZendAfi_View_Helper_Filters_Element_Null'; diff --git a/library/ZendAfi/View/Helper/Filters/Element/PlaceTown.php b/library/ZendAfi/View/Helper/Filters/Element/PlaceTown.php new file mode 100644 index 0000000000000000000000000000000000000000..5df7ff3e399edd25bb43f51277de8ca353dfaceb --- /dev/null +++ b/library/ZendAfi/View/Helper/Filters/Element/PlaceTown.php @@ -0,0 +1,39 @@ +<?php +/** + * Copyright (c) 2012, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH 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. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH 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 BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +class ZendAfi_View_Helper_Filters_Element_PlaceTown extends ZendAfi_View_Helper_Filters_Element { + public function __construct($custom_field_id = null) { + $this->_custom_field_id = Class_Systeme_ModulesAccueil_Library::FILTER_PLACE_TOWN; + } + + + public function elements() { + $towns = array_unique( + (new Storm_Model_Collection(Class_Lieu::findAllBy(['order' => 'ville']))) + ->collect('ville') + ->getArrayCopy()); + + $towns = array_map(function($town) + { return trim($town);}, $towns); + + return array_combine($towns, $towns); + } +} diff --git a/tests/application/modules/admin/controllers/WidgetControllerTest.php b/tests/application/modules/admin/controllers/WidgetControllerTest.php index fe5968f206f3bb0c77d221e60bb367e99666128e..886bdb16bf508b8e77fea4aa295162336c92fa2b 100644 --- a/tests/application/modules/admin/controllers/WidgetControllerTest.php +++ b/tests/application/modules/admin/controllers/WidgetControllerTest.php @@ -382,8 +382,8 @@ class WidgetControllerCalendarTest extends WidgetControllerDispatchWidgetConfigu /** @test */ - public function secondListShouldContainsTwoElements() { - $this->assertXPathCount('//div[@id="input_enabled_filters"]/div[2]/ul/li', 2); + public function secondListShouldContainsThreeElements() { + $this->assertXPathCount('//div[@id="input_enabled_filters"]/div[2]/ul/li', 3); } diff --git a/tests/scenarios/Templates/TemplatesWidgetTest.php b/tests/scenarios/Templates/TemplatesWidgetTest.php index 244f990d4e07549810afe506c4123edf977dfe5a..cc76092f5ff2ccda7749f4c04203755b6b4ef99a 100644 --- a/tests/scenarios/Templates/TemplatesWidgetTest.php +++ b/tests/scenarios/Templates/TemplatesWidgetTest.php @@ -43,6 +43,7 @@ class TemplatesWidgetsNewsletterTest extends TemplatesIntonationTestCase { $this->assertXpath('//input[@name="titre"][@type="text"]'); } + /** @test */ public function buttonDisableNewsletterShouldBePresent() { $this->fixture('Class_Newsletter', @@ -118,11 +119,38 @@ abstract class TemplatesWidgetRenderAllTestCase extends TemplatesIntonationTestC $this->fixture('Class_Bib', ['id' => 1, - 'libelle' => 'Annecy']); + 'libelle' => 'Annecy', + 'id_lieu' => 11, + 'ville' => 'Grand Annecy']); $this->fixture('Class_Bib', ['id' => 45, - 'libelle' => 'Cran']); + 'libelle' => 'Cran', + 'id_lieu' => 145, + 'ville' => 'Grand Annecy']); + + $this->fixture('Class_Lieu', + ['id' => 11, + 'libelle' => 'Centre culturel', + 'ville' => 'Grand Annecy' + ]); + + $this->fixture('Class_Lieu', + ['id' => 145, + 'libelle' => 'Mediatheque', + 'ville' => 'Grand Annecy ' + ]); + + $this->fixture('Class_Lieu', + ['id' => 146, + 'libelle' => 'Ludotheque', + 'ville' => 'Faverges' + ]); + + Class_Bib::newInstanceWithId(46, ['libelle' => 'Seythenex', + 'ville' => 'Faverges', + 'id_lieu' => 146]) + ->save(); } } @@ -164,6 +192,14 @@ class TemplatesWidgetRenderAllContainersTest extends TemplatesWidgetRenderAllTes class TemplatesWidgetRenderAllAgendaTest extends TemplatesWidgetRenderAllTestCase { public function setUp() { parent::setUp(); + + Class_Profil::find(72) + ->setCfgAccueil(['modules' => + ['21' => ['division' => 3, + 'type_module' => 'CALENDAR', + 'preferences' => ['rss' => 1, + 'enabled_filters' => 'place;place_town']]]]); + $this->dispatch('/opac/widget/render-all/profile_id/72/widget_id/21'); } @@ -184,6 +220,109 @@ class TemplatesWidgetRenderAllAgendaTest extends TemplatesWidgetRenderAllTestCas public function renderWidgetAgendaShouldContainsVersionLinkForArticleVacance() { $this->assertXPathContentContains('//a[contains(@href, "/admin/cms/version/id/78")]', 'Historique'); } + + + /** @test */ + public function filterPlaceShouldBeDisplayed() { + $this->assertXPathContentContains('//div[contains(@class, "filters")]//button[contains(@class, "button_Lieu")]', 'Lieu'); + } + + + /** @test */ + public function filterTownShouldBeDisplayed() { + $this->assertXPathContentContains('//div[contains(@class, "filters")]//button[contains(@class, "button_Ville")]', 'Ville'); + } + + + /** @test */ + public function townGrandAnnecyShouldBeSelectable() { + $this->assertXPathContentContains('//div[contains(@class, "filters")]//li//a[contains(@href, "/cms/render-all/id_module/21/place_town/Grand+Annecy")]', 'Grand Annecy'); + } +} + + + + +class TemplatesWidgetFilterTest extends TemplatesWidgetRenderAllTestCase { + + public function setUp() { + parent::setUp(); + Intonation_View_CalendarContent::setTimeSource(new TimeSourceForTest('2020-11-12 23:34:00')); + Class_Profil::find(1) + ->setCfgAccueil(['modules' => + ['51' => ['division' => 3, + 'type_module' => 'CALENDAR', + 'preferences' => ['enabled_filters' => 'place;place_town', + 'layout' => 'wall' + ]]]]); + + Class_Article::newInstanceWithId(78, + ['titre' => 'L\'été', + 'contenu' => 'À la mer', + 'id_lieu' => 145]) + ->save(); + Class_Article::newInstanceWithId(79, + ['titre' => 'L\'hiver', + 'contenu' => 'À la montagne', + 'id_lieu' => 146]) + ->save(); + + Class_Article::getLoader() + ->whenCalled('getArticlesByPreferences') + ->with(['display_order' => 'EventDebut', + 'id_categorie' => '', + 'events_only' => true, + 'event_date' => '2020-11', + 'id_bib' => 0, + 'id_lieu' => '', + 'place_town' => 'Grand Annecy', + 'custom_fields' => [], + 'published' => true, + 'event_end_after' => '2020-11-12']) + ->answers([Class_Article::find(78)]) + ->whenCalled('getArticlesByPreferences') + ->with(['display_order' => 'EventDebut', + 'id_categorie' => '', + 'events_only' => true, + 'event_date' => '2020-11', + 'id_bib' => 0, + 'id_lieu' => '', + 'place_town' => 'Grand Annecy', + 'custom_fields' => [], + 'published' => true + ]) + ->answers([Class_Article::find(78)]) + ->whenCalled('getArticlesByPreferences') + ->with(['display_order' => 'EventDebut', + 'id_categorie' => '', + 'events_only' => true, + 'event_date' => '', + 'id_bib' => 0, + 'id_lieu' => '', + 'place_town' => 'Grand Annecy', + 'custom_fields' => [], + 'published' => true, + 'event_start_after' => '2020-11', + 'event_end_after' => '', + 'limit' => 3 + ]) + ->answers([Class_Article::find(78)]) + ->beStrict(); + + $this->dispatch('/cms/calendar/id_profil/1/id_module/51/place_town/Grand+Annecy'); + } + + + /** @test */ + public function eventLEteShouldBeDisplayedWithTownGrandAnnecySelected() { + $this->assertXPathContentContains('//div', 'L\'été', $this->_response->getBody()); + } + + + /** @test */ + public function eventAlaMontagneShouldNotBeDisplayedWithTownGrandAnnecySelected() { + $this->assertNotXPathContentContains('//div', 'L\'hiver'); + } } @@ -494,6 +633,7 @@ class TemplatesWidgetSearchToggleStyleTest extends TemplatesIntonationTestCase { + class TemplatesImageWidgetTest extends TemplatesIntonationTestCase { /** @test */ @@ -567,6 +707,7 @@ class TemplatesCreditsWidgetTest extends TemplatesIntonationTestCase { + class TemplatesScrollWidgetTest extends TemplatesIntonationTestCase { /** @test */ @@ -758,6 +899,7 @@ class TemplateRenderWidgetTest extends TemplatesIntonationTestCase { + class TemplatesDispatchLibraryWidgetTest extends TemplatesIntonationTestCase { public function setUp() { @@ -979,6 +1121,7 @@ class TemplatesDispatchDomainWidgetTest extends TemplatesIntonationTestCase { + class TemplatesDispatchIntonationWithDomainWidgetTest extends TemplatesIntonationTestCase { /** @test */ @@ -995,6 +1138,7 @@ class TemplatesDispatchIntonationWithDomainWidgetTest extends TemplatesIntonatio + class TemplatesDispatchAdminWidgetEditActionTest extends TemplatesIntonationTestCase { /** @test */ @@ -1025,7 +1169,6 @@ class TemplatesDispatchAdminWidgetEditActionTest extends TemplatesIntonationTest } - /** @test */ public function customCssClassesShouldHaveBeenSaved() { $this->postDispatch('/admin/widget/edit-action/id/recherche_resultat_simple/id_profil/72',