diff --git a/VERSIONS_WIP/25728 b/VERSIONS_WIP/25728 new file mode 100644 index 0000000000000000000000000000000000000000..76c10edf0cc64954f3251c567f70a337735fc124 --- /dev/null +++ b/VERSIONS_WIP/25728 @@ -0,0 +1 @@ + - ticket #25728 : Ajouter la possibilité de flux rss à la boite sitothèque \ No newline at end of file diff --git a/application/modules/admin/views/scripts/accueil/sitotheque.phtml b/application/modules/admin/views/scripts/accueil/sitotheque.phtml index 3d3d72d1c5ca7f9c0836f2290d73751b39cced2f..184e770125d3e7b67a6f2a93faaa80f0f6188914 100644 --- a/application/modules/admin/views/scripts/accueil/sitotheque.phtml +++ b/application/modules/admin/views/scripts/accueil/sitotheque.phtml @@ -39,6 +39,15 @@ formSelectToggleVisibilityForElement("input[name=display_order]", "#option_nb_af <td class="droite">Titre </td> <td class="gauche"><input type="text" name="titre" size="50" value="<?php print($this->preferences['titre']); ?>"></td> </tr> + <tr> + <td class="droite">Proposer un fil Rss </td> + <td class="gauche"> + <?php echo $this->formCheckbox('rss', + $this->preferences['rss'], + null, + ['1', '0']) ?> + </td> + </tr> </table> </fieldset> <br> diff --git a/application/modules/opac/controllers/CmsController.php b/application/modules/opac/controllers/CmsController.php index a682560e6a7ebd4a97394f7fb0e71cdc3d29efc0..cb1dcf37597122b38a2add249cae0ffcbb14af57 100644 --- a/application/modules/opac/controllers/CmsController.php +++ b/application/modules/opac/controllers/CmsController.php @@ -84,21 +84,7 @@ class CmsController extends ZendAfi_Controller_Action { public function calendarrssAction() { $id_profil = (int)$this->_getParam('id_profil'); $id_module = (int)$this->_getParam('id_module'); - $profil = Class_Profil::find($id_profil); - - $preferences = $profil->getModuleAccueilPreferences($id_module, 'NEWS'); - $articles=Class_Calendar::getAllNextEvents($id_module,$profil); - - $data_rss = [ - 'title' => trim($preferences['titre']) ? trim($preferences['titre']) : $profil->getLibelle(), - 'link' => $profil->urlForModule('cms', 'articleviewbydate', $id_module), - 'charset' => 'utf-8', - 'description' => 'Agenda: ' . $preferences['titre'], - 'lastUpdate' => time() - ]; - - $this->_renderRSS($articles, $data_rss); - + $this->_helper->renderRss($id_profil, $id_module, $this->view, 'NEWS'); } @@ -161,44 +147,18 @@ class CmsController extends ZendAfi_Controller_Action { } + public function reseauAction() { $this->view->article = Class_Article::getLoader() ->find((int)$this->_getParam('id_article')); $this->_helper->getHelper('viewRenderer')->setLayoutScript('empty.phtml'); } + public function rssAction(){ $id_profil = (int)$this->_getParam('id_profil'); $id_module = (int)$this->_getParam('id_module'); - - $articles = []; - - $data_rss = [ - 'title' => 'Flux indisponible', - 'link' => $this->_request->getScheme() . '://' - . $this->_request->getServer('HTTP_HOST'), - 'charset' => 'utf-8', - 'description' => '', - 'lastUpdate' => time() - ]; - - if (null != ($profil = Class_Profil::find($id_profil))) { - $preferences = $profil->getModuleAccueilPreferences($id_module, 'NEWS'); - - $data_rss = array_merge( - $data_rss, - [ - 'title' => $preferences['titre'], - 'link' => $profil->urlForModule('cms', 'viewselection', $id_module), - 'description' => 'Articles: '.$preferences['titre'] - ] - ); - - $articles = Class_Article::getArticlesByPreferences($preferences); - $articles = Class_Article::filterByLocaleAndWorkflow($articles); - } - - $this->_renderRSS($articles, $data_rss); + $this->_helper->renderRss($id_profil, $id_module, $this->view, 'ARTICLE'); } @@ -307,46 +267,6 @@ class CmsController extends ZendAfi_Controller_Action { $this->view->param = $param; } - - /** - * @param array $article - */ - protected function _getPubDate($article) { - if ($article->hasEventsDebut()) - return $article->getEventsDebut(); - - if ($article->hasDebut()) - return $article->getDebut(); - - return $article->getDateMaj(); - } - - /** - * @param array $articles - * @param array $rss_array - */ - private function _renderRSS($articles, $rss_array) { - $entries = []; - foreach ($articles as $article) { - $entries[] = - [ - 'title' => html_entity_decode($article->getTitre()), - 'link' => $this->_request->getScheme() . '://' - . $this->_request->getServer('HTTP_HOST') - . $this->view->url($article->getUrl()), - 'lastUpdate' => strtotime($this->_getPubDate($article)), - 'description' => html_entity_decode(Class_CmsUrlTransformer::imgUrlRelativeToAbsolute($this->view->tagArticleEvent($article).$article->getFullContent()))]; - } - - $rss_array['entries'] = $entries; - - $feed = Zend_Feed::importArray($rss_array, 'rss'); - - $this->getHelper('ViewRenderer')->setNoRender(); - $this->_response->setHeader('Content-Type', 'application/rss+xml;charset=utf-8') ; - $this->_response->setBody($feed->saveXML()); - } - /** * @param int $id_module * @param int $id_profil diff --git a/application/modules/opac/controllers/SitoController.php b/application/modules/opac/controllers/SitoController.php index e10c79e9ddcd91a5c6cff4890a135b19f6e2a0e4..f556c8b28882780835d3a7368fe51a5e5a0dab3b 100644 --- a/application/modules/opac/controllers/SitoController.php +++ b/application/modules/opac/controllers/SitoController.php @@ -86,4 +86,12 @@ class SitoController extends Zend_Controller_Action { $webThumbnail = new Class_WebService_WebSiteThumbnail(); $this->_redirect($webThumbnail->fetchFullUrl($url)); } + + + public function sitoRssAction() { + $id_profil = (int)$this->_getParam('id_profil'); + $id_module = (int)$this->_getParam('id_module'); + + $this->_helper->renderRss($id_profil, $id_module, $this->view, 'SITO'); + } } \ No newline at end of file diff --git a/library/Class/Article.php b/library/Class/Article.php index 34ac7a8b6a80eaf147959a8d055709ab5d5ce08e..9ff6d9fb6cdf5d477d857950e0b6d60bd9c91052 100644 --- a/library/Class/Article.php +++ b/library/Class/Article.php @@ -783,6 +783,17 @@ class Class_Article extends Storm_Model_Abstract { } + public function getPubDate() { + if ($this->hasEventsDebut()) + return $this->getEventsDebut(); + + if ($this->hasDebut()) + return $this->getDebut(); + + return $this->getDateMaj(); + } + + public function beforeSave() { if ($this->isNew() && !$this->getDateCreation()) $this->setDateCreation($this->getDateMaj()); diff --git a/library/Class/Systeme/ModulesAccueil/Sitotheque.php b/library/Class/Systeme/ModulesAccueil/Sitotheque.php index c0592951f2bc1adad2cf5a9f96bc083766202d96..26fb68344d5451c4f72f8d286e5fc34f277f65c8 100644 --- a/library/Class/Systeme/ModulesAccueil/Sitotheque.php +++ b/library/Class/Systeme/ModulesAccueil/Sitotheque.php @@ -38,14 +38,15 @@ class Class_Systeme_ModulesAccueil_Sitotheque extends Class_Systeme_ModulesAccue protected $_isPhone = false; /** @var array */ - protected $_defaultValues = array( - 'titre' => 'Sitothèque', // Titre de la boite - 'type_aff' => 1, // Type a afficher : 1=sélection libre, 2=les + récents - 'id_categorie' => '', // Liste d'id_categorie séparés par des tirets - 'id_items' => '', // Liste d'id_site séparés par des tirets - 'nb_aff' => '2', // Nombre à afficher - 'group_by_categorie' => false, //grouper les sites par categorie sous forme de menu, - 'display_order' => 'Random' //ordre d'affichage: Random ou Selection - ); + protected $_defaultValues = [ + 'titre' => 'Sitothèque', // Titre de la boite + 'type_aff' => 1, // Type a afficher : 1=sélection libre, 2=les + récents + 'id_categorie' => '', // Liste d'id_categorie séparés par des tirets + 'id_items' => '', // Liste d'id_site séparés par des tirets + 'nb_aff' => '2', // Nombre à afficher + 'rss' => '0', + 'group_by_categorie' => false, //grouper les sites par categorie sous forme de menu, + 'display_order' => 'Random' //ordre d'affichage: Random ou Selection + ]; } ?> \ No newline at end of file diff --git a/library/ZendAfi/Controller/Action/Helper/RenderRss.php b/library/ZendAfi/Controller/Action/Helper/RenderRss.php new file mode 100644 index 0000000000000000000000000000000000000000..2411ac338054bd92e83220942236168cffb454ef --- /dev/null +++ b/library/ZendAfi/Controller/Action/Helper/RenderRss.php @@ -0,0 +1,197 @@ +<?php +/** + * Copyright (c) 2012-2014, 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_Controller_Action_Helper_RenderRss extends Zend_Controller_Action_Helper_Abstract { + + protected function _newStrategy($named) { + $class_name = 'ZendAfi_Controller_Action_Helper_RenderRss' . ucfirst($named); + return new $class_name(); + } + + + public function direct($id_profil, $id_module, $view, $type) { + $this->_newStrategy($type)->render($id_profil,$id_module,$view,$this->getActionController()); + } +} + + + +abstract class ZendAfi_Controller_Action_Helper_RenderRssAbstract { + protected $action, $_view; + + public function render($id_profil, $id_module, $view,$action) { + $this->_view = $view; + $this->action=$action; + $datas = []; + $data_rss = + [ + 'title' => 'Flux indisponible', + 'link' => ($this->action->getRequest()->getScheme() . '://' + . $this->action->getRequest()->getServer('HTTP_HOST')), + 'charset' => 'utf-8', + 'description' => '', + 'lastUpdate' => time() + ]; + + $profil = Class_Profil::find($id_profil); + if ($profil != null) { + $preferences = $profil->getModuleAccueilPreferences($id_module, $this->getType()); + $datas = $this->_getObjectDatas($id_module, $profil, $preferences); + $data_rss = array_merge( + $data_rss, + [ + 'title' => (trim($preferences['titre']) ? trim($preferences['titre']) : $profil->getLibelle()), + 'link' => $this->_getLink($profil, $id_module), + 'description' => $this->_getDescription() . $preferences['titre'] + ] + ); + } + $this->_renderRssFeed($datas, $data_rss); + } + + + protected function getDescriptionForElement($data) { + return html_entity_decode(Class_CmsUrlTransformer::imgUrlRelativeToAbsolute($this->_view->tagArticleEvent($data) + . $data->getFullContent())); + } + + + protected function getUrlLink($data) { + return $this->action->getRequest()->getScheme() . '://' + . $this->action->getRequest()->getServer('HTTP_HOST') + . $this->_view->url($data->getUrl()); + } + + + protected function lastUpdate($data) { + return strtotime($data->getPubDate()); + } + + + protected function _renderRssFeed($datas, $rss_array) { + $entries = []; + foreach ($datas as $data) { + $entries[] = + [ + 'title' => html_entity_decode($data->getTitre()), + 'link' => $this->getUrlLink($data), + 'lastUpdate' => $this->lastUpdate($data), + + 'description' => $this->getDescriptionForElement($data) + ]; + } + $rss_array['entries'] = $entries; + $feed = Zend_Feed::importArray($rss_array, 'rss'); + + $this->action->getHelper('ViewRenderer')->setNoRender(); + $this->action->getResponse()->setHeader('Content-Type', 'application/rss+xml;charset=utf-8') ; + $this->action->getResponse()->setBody($feed->saveXML()); + } + + + abstract protected function _getObjectDatas($id_module, $profil, $preferences); + + + protected function _getDescription() { + return ''; + } + + + protected function _getLink($profil, $id_module) { + return ''; + } + + + protected function getType() { + return 'NEWS'; + } +} + + + +class ZendAfi_Controller_Action_Helper_RenderRssSito extends ZendAfi_Controller_Action_Helper_RenderRssAbstract { + + protected function getType() { + return 'SITO'; + } + + + protected function getDescriptionForElement($data) { + return html_entity_decode($data->getDescription()); + } + + + protected function lastUpdate($data) { + return strtotime($data->getDateMaj()); + } + + + protected function getUrlLink($data) { + return $data->getUrl(); + } + + + protected function _getObjectDatas($id_module, $profil, $preferences) { + return Class_Sitotheque::getSitesFromIdsAndCategories( + explode('-', $preferences['id_items']), + explode('-', $preferences['id_categorie'])); + } +} + + + +class ZendAfi_Controller_Action_Helper_RenderRssNews extends ZendAfi_Controller_Action_Helper_RenderRssAbstract { + + protected function _getObjectDatas($id_module, $profil, $preferences) { + return Class_Calendar::getAllnextEvents($id_module, $profil); + } + + + protected function _getDescription() { + return 'Agenda: '; + } + + + protected function _getLink($profil, $id_module) { + return $profil->urlForModule('cms', 'articleviewbydate', $id_module); + } +} + + + +class ZendAfi_Controller_Action_Helper_RenderRssArticle extends ZendAfi_Controller_Action_Helper_RenderRssAbstract { + + protected function _getObjectDatas($id_module, $profil, $preferences) { + $articles = Class_Article::getArticlesByPreferences($preferences); + return Class_Article::filterByLocaleAndWorkflow($articles); + } + + + protected function _getDescription() { + return 'Articles: '; + } + + + protected function _getLink($profil, $id_module) { + return $profil->urlForModule('cms', 'viewselection', $id_module); + } +} \ No newline at end of file diff --git a/library/ZendAfi/View/Helper/Accueil/Sito.php b/library/ZendAfi/View/Helper/Accueil/Sito.php index f440aab07c94404fe7c9c2805071eba6abe44563..e541de0328efc121bb3f8d8b51aadac4a26bcafd 100644 --- a/library/ZendAfi/View/Helper/Accueil/Sito.php +++ b/library/ZendAfi/View/Helper/Accueil/Sito.php @@ -47,6 +47,9 @@ class ZendAfi_View_Helper_Accueil_Sito extends ZendAfi_View_Helper_Accueil_Base $contenu = ''; $nb_aff = $this->getPreference('nb_aff'); + if ($this->preferences['rss']) + $this->rss_interne = $this->_getRSSurl('sito', 'sito-rss'); + $box_title = $this->getPreference('titre') ? $this->getPreference('titre') : $this->_('Derniers sites ajoutés'); diff --git a/tests/application/modules/admin/controllers/AccueilControllerTest.php b/tests/application/modules/admin/controllers/AccueilControllerTest.php index 4e8692448cdb0d56297ff27b51ceafc4d3f44b2d..1478e833a80312147f614646c9e73aaa58b00d03 100644 --- a/tests/application/modules/admin/controllers/AccueilControllerTest.php +++ b/tests/application/modules/admin/controllers/AccueilControllerTest.php @@ -311,10 +311,17 @@ class AccueilControllerConfigSitothequeDefaultsTest extends Admin_AbstractContro $this->assertXPath('//input[@type="radio"][@name="display_order"][@value="Random"]'); } + /** @test */ public function displayOrderSelectionShouldBePresent() { $this->assertXPath('//input[@type="radio"][@name="display_order"][@value="Selection"]'); } + + +/** @test */ + public function rssFlowPreferenceShouldBePresent() { + $this->assertXPath('//input[@type="checkbox"][@name="rss"]', $this->_response->getBody()); + } } diff --git a/tests/application/modules/opac/controllers/ProfilOptionsControllerTest.php b/tests/application/modules/opac/controllers/ProfilOptionsControllerTest.php index 779e101872d096abfdab79c0835153f85d30d91c..02420da50b23171a1d1496490daea7dbccd211ed 100644 --- a/tests/application/modules/opac/controllers/ProfilOptionsControllerTest.php +++ b/tests/application/modules/opac/controllers/ProfilOptionsControllerTest.php @@ -1180,7 +1180,10 @@ class ProfilOptionsControllerProfilBreadcrumbTest extends ProfilOptionsControlle } - + /** @test */ + public function sitothequesShouldNotContainsLinkToRss() { + $this->assertNotXpath('//div[@class="rss"]/a[contains(@href, "/sito/sito-rss")]'); + } } @@ -1301,8 +1304,6 @@ class ProfilOptionsControllerProfilJeunesseViewPageJeuxTest extends ProfilOption class ProfilOptionsControllerPagesJeuxWithSitotheque extends ProfilOptionsControllerProfilJeunesseWithPagesJeuxMusiqueTestCase { - - public function setUp() { parent::setUp(); @@ -1310,7 +1311,8 @@ class ProfilOptionsControllerPagesJeuxWithSitotheque extends ProfilOptionsContro '10' => ['division' => '2', 'type_module' => 'SITO', - 'preferences' => ['id_categorie' => '2', + 'preferences' => ['rss' => 1, + 'id_categorie' => '2', 'group_by_categorie' => true]]], 'options' => []]); @@ -1349,6 +1351,12 @@ class ProfilOptionsControllerPagesJeuxWithSitotheque extends ProfilOptionsContro } + /** @test */ + public function sitothequesShouldContainsLinkToRss() { + $this->assertXpath('//div[@class="rss"]/a[contains(@href, "/sito/sito-rss")]'); + } + + /** @test */ public function categoryMySitesShouldBeInUlSitotheque() { $this->assertXPathContentContains('//ul[@class="sitotheque"]/li/h2/a', diff --git a/tests/application/modules/opac/controllers/SitoControllerTest.php b/tests/application/modules/opac/controllers/SitoControllerTest.php index e6be26938dca4ff18c57ebfcad735760827e4001..fbc10f5a6953767fa1de424936e7e212abecd4ea 100644 --- a/tests/application/modules/opac/controllers/SitoControllerTest.php +++ b/tests/application/modules/opac/controllers/SitoControllerTest.php @@ -49,7 +49,8 @@ abstract class SitoControllerTestCase extends AbstractControllerTestCase { 'division' => '2', 'type_module' => 'SITO', 'preferences' => ['id_categorie' => '3', - 'id_items' => '25-28'] + 'id_items' => '25-28', + 'rss_status' => 1] ] ], 'options' => []]); @@ -60,7 +61,7 @@ abstract class SitoControllerTestCase extends AbstractControllerTestCase { -abstract class SitoControllerViewCategoyTestCase extends SitoControllerTestCase { +abstract class SitoControllerViewCategoryTestCase extends SitoControllerTestCase { public function setUp() { parent::setUp(); $collectif = $this->fixture('Class_SitothequeCategorie', @@ -104,7 +105,8 @@ abstract class SitoControllerViewCategoyTestCase extends SitoControllerTestCase 'type_module' => 'SITO', 'preferences' => ['id_categorie' => '12', 'type_aff' => '3', - 'id_items' => '280-281']]], + 'id_items' => '280-281', + 'rss' => 1]]], 'options' => []]); } } @@ -112,7 +114,7 @@ abstract class SitoControllerViewCategoyTestCase extends SitoControllerTestCase -class SitoControllerViewCategoyTest extends SitoControllerViewCategoyTestCase { +class SitoControllerViewCategoryTest extends SitoControllerViewCategoryTestCase { public function setUp() { parent::setUp(); $this->dispatch('/sito/viewcategory/id_cat/12/start_cat/12', true); @@ -168,7 +170,7 @@ class SitoControllerViewRecentTest extends SitoControllerTestCase { -class SitoControllerViewCategorySearchTest extends SitoControllerViewCategoyTestCase { +class SitoControllerViewCategorySearchTest extends SitoControllerViewCategoryTestCase { public function setUp() { parent::setUp(); @@ -321,4 +323,67 @@ class SitoControllerSitoWebThumbnailUrl extends SitoControllerTestCase { $this->getResponseLocation()); } } + + + +class SitoControllerRssWithProfileTest extends SitoControllerViewCategoryTestCase { + public function setUp() { + parent::setUp(); + + Class_Profil::getCurrentProfil() + ->setCfgAccueil(['modules' => ['1' => ['division' => '2', + 'type_module' => 'SITO', + 'preferences' => ['id_categorie' => '19', + 'type_aff' => '3', + 'id_items' => '281', + 'rss' => 1]]], + 'options' => []]); + + $this->dispatch('sito/sito-rss?id_module=1&id_profil=2'); + } + + +/** @test */ + public function rssShouldOnlyContainsTwoSitos() { + $this->assertXPathCount('//item', 2,$this->_response->getBody()); + } + + + /** @test */ + public function linuxFrShouldNotBeShown() { + $this->assertNotXPathContentContains('link', 'http://april.org'); + } + + + /** @test */ + public function framasoftShouldBeShown() { + $this->assertXPathContentContains('//link', 'http://framasoft.org'); + } + + + /** @test */ + public function laquadratureShouldBeShown() { + $this->assertXPathContentContains('//link', 'http://laquadrature.net'); + } +} + + + +class SitoControllerRssWithoutProfileTest extends AbstractControllerTestCase { + public function setUp() { + parent::setUp(); + + Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Profil') + ->whenCalled('find') + ->answers(null); + + $this->dispatch('sito/sito-rss'); + } + + + /** @test */ + public function titleShouldBeFluxIndisponible() { + $this->assertXPathContentContains('//channel/title', 'Flux indisponible', $this->_response->getBody()); + } +} ?>