diff --git a/VERSIONS_WIP/63069 b/VERSIONS_WIP/63069 new file mode 100644 index 0000000000000000000000000000000000000000..046a87024a55ed8a091bf568f98229de0e91bca9 --- /dev/null +++ b/VERSIONS_WIP/63069 @@ -0,0 +1 @@ + - ticket #63069 : Ajout d'un batch permettant moissonner un calendrier externe automatiquement \ No newline at end of file diff --git a/application/modules/admin/controllers/ExternalAgendasController.php b/application/modules/admin/controllers/ExternalAgendasController.php index 2398e0110a99fc46a8957a2e43809b1ffb4a21f0..0c78b90ddca93cff18bed8e96406b38e20e30bb8 100644 --- a/application/modules/admin/controllers/ExternalAgendasController.php +++ b/application/modules/admin/controllers/ExternalAgendasController.php @@ -23,7 +23,7 @@ class Admin_ExternalAgendasController extends ZendAfi_Controller_Action { public function getPlugins() { return ['ZendAfi_Controller_Plugin_ResourceDefinition_ExternalAgenda', - 'ZendAfi_Controller_Plugin_Manager_Manager']; + 'ZendAfi_Controller_Plugin_Manager_ExternalAgenda']; } @@ -32,17 +32,9 @@ class Admin_ExternalAgendasController extends ZendAfi_Controller_Action { return $this->_redirectToIndex(); $this->view->titre = $this->_('Moissonnage des évènements de l\'agenda "%s"', $agenda->getLibelle()); - $agenda->import($this); - } - - - public function visitNewEvents($events) { - $this->view->new_events = $events; - } - - - public function visitUpdatedEvents($events) { - $this->view->updated_events = $events; + $results = $agenda->import(); + $this->view->new_events = $results['new']; + $this->view->updated_events = $results['update']; } diff --git a/application/modules/admin/views/scripts/external-agendas/index.phtml b/application/modules/admin/views/scripts/external-agendas/index.phtml index e79537bceb9b075979f778070a7cccca1b942f59..be3fca0d36c35381ce3ac65ffd9a4351a5fecd9c 100644 --- a/application/modules/admin/views/scripts/external-agendas/index.phtml +++ b/application/modules/admin/views/scripts/external-agendas/index.phtml @@ -15,9 +15,15 @@ $number_of_events = function($model, $attrib) $ical_url = function($model, $attrib) { + $part = $model->getUrl(); + if (strlen($model->getUrl()) >40) { + $parts = explode('/',$part); + $part=reset($parts).'//.../'.end($parts); + } + return $this->tagAnchor($model->getUrl(), - $model->getUrl(), - ['target' => '_blank']); + $part, + ['title' => $model->getUrl(),'target' => '_blank']); }; $category = function($model, $attribs) { @@ -28,27 +34,15 @@ $category = function($model, $attribs) { Class_ArticleCategorie::find($cat_id)->getLibelle()); }; -echo $this->tagModelTable($this->agendas, - - [$this->_('Libellé'), - $this->_('Nombre d\'événements'), - $this->_('URL'), - $this->_('Categorie')], - - ['label', - 'number-of-events', - 'url', - 'category'], - - [ ['action' => 'import', 'content' => $this->boutonIco('type=test', - 'bulle='. $this->_('Moissonner'))], - ['action' => 'edit', 'content' => $this->boutonIco('type=edit')], - ['action' => 'delete', 'content' => $this->boutonIco('type=del')], - ], - - 'agendas', - null, - - ['number-of-events' => $number_of_events, - 'url' => $ical_url, - 'category' => $category]); +$description = (new Class_TableDescription('agendas')) + ->addColumn($this->_('Libellé'), 'label') + ->addColumn($this->_('Nombre d\'événements'), $number_of_events) + ->addColumn($this->_('URL'), $ical_url) + ->addColumn($this->_('Categorie'), $category) + ->addColumn($this->_('MAJ auto.'), function($model) + { + return $model->autoharvest ? $this->_('Oui') : $this->_('Non'); + }) + ->addRowAction(function($model) { return $this->renderPluginsActions($model); }); + +echo $this->renderTable($description, $this->agendas, ['sorter' => true]); diff --git a/cosmogramme/sql/patch/patch_334.php b/cosmogramme/sql/patch/patch_334.php new file mode 100644 index 0000000000000000000000000000000000000000..8bd70b3464b6f10eb20e53ede87e273dd7626526 --- /dev/null +++ b/cosmogramme/sql/patch/patch_334.php @@ -0,0 +1,8 @@ +<?php +try{ + Zend_Db_Table_Abstract::getDefaultAdapter() + ->query('alter table external_agenda add column autoharvest tinyint not null default 0'); + Zend_Db_Table_Abstract::getDefaultAdapter() + ->query('alter table external_agenda add key autoharvest(autoharvest)'); +} catch(Exception $e) {} +?> diff --git a/library/Class/Batch.php b/library/Class/Batch.php index c8469a79541add4601be117ac6e713acb645594c..e5d7f861b7328ca79f2e68f364e1a5a15ae7ce64 100644 --- a/library/Class/Batch.php +++ b/library/Class/Batch.php @@ -41,7 +41,8 @@ class Class_BatchLoader extends Storm_Model_Loader { Class_Batch_AutocompleteRecordAuthor::TYPE => new Class_Batch_AutocompleteRecordAuthor(), Class_Batch_BuildSiteMap::TYPE => new Class_Batch_BuildSiteMap(), Class_Batch_PremierChapitre::TYPE => new Class_Batch_PremierChapitre(), - Class_Batch_NoveltyFacet::TYPE => new Class_Batch_NoveltyFacet()]); + Class_Batch_NoveltyFacet::TYPE => new Class_Batch_NoveltyFacet(), + Class_Batch_ExternalAgenda::TYPE => new Class_Batch_ExternalAgenda]); } diff --git a/library/Class/Batch/ExternalAgenda.php b/library/Class/Batch/ExternalAgenda.php new file mode 100644 index 0000000000000000000000000000000000000000..f69be445238fefb3c91fce7d23ad003fe11e7cae --- /dev/null +++ b/library/Class/Batch/ExternalAgenda.php @@ -0,0 +1,34 @@ +<?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 Class_Batch_ExternalAgenda extends Class_Batch_Abstract { + const TYPE = 'EXTERNAL_AGENDA'; + + public function getLabel() { + return $this->_('Moissonner les agendas externes'); + } + + public function run() { + Class_ExternalAgenda::harvest($this->getLogger()); + } +} +?> \ No newline at end of file diff --git a/library/Class/ExternalAgenda.php b/library/Class/ExternalAgenda.php index 9816b744e7e5507fd3651945c6d44327f55b8533..ada348c13beea5ca555dee3b77937e297cc2cefb 100644 --- a/library/Class/ExternalAgenda.php +++ b/library/Class/ExternalAgenda.php @@ -20,6 +20,19 @@ */ +class Class_ExternalAgendaLoader extends Storm_Model_Loader { + + public function harvest($logger) { + foreach (Class_ExternalAgenda::findAllBy(['autoharvest' => 1]) as $agenda) { + $results = $agenda->import(); + $logger->log($agenda->getLabel().":\n"); + $logger->log($agenda->_("Nombre d\'événements créés : %s\n",count($results['new']))); + $logger->log($agenda->_("Nombre d\'événements mis à jour : %s\n",count($results['update']))); + } + } +} + + class Class_ExternalAgenda extends Storm_Model_Abstract { use Trait_Translator; @@ -30,6 +43,7 @@ class Class_ExternalAgenda extends Storm_Model_Abstract { 'location' => ['model' => 'Class_Lieu', 'referenced_in' => 'id_lieu']]; + protected $_loader_class = 'Class_ExternalAgendaLoader'; public function getLibelle() { return $this->getLabel(); @@ -43,16 +57,13 @@ class Class_ExternalAgenda extends Storm_Model_Abstract { } - public function import($logger) { + public function import() { $service = new Class_WebService_ICalendar(); $events = $service->import($this); - - $logger->visitNewEvents($events->select('isNew')); - $logger->visitUpdatedEvents($events->reject('isNew')); - + $results['new'] = $events->select('isNew'); + $results['update'] = $events->reject('isNew'); $events->eachDo('save'); - - return $events; + return $results; } diff --git a/library/ZendAfi/Controller/Plugin/Manager/ExternalAgenda.php b/library/ZendAfi/Controller/Plugin/Manager/ExternalAgenda.php new file mode 100644 index 0000000000000000000000000000000000000000..3a92d345d0fa282a0c7c9529b7b546b149396525 --- /dev/null +++ b/library/ZendAfi/Controller/Plugin/Manager/ExternalAgenda.php @@ -0,0 +1,40 @@ +<?php +/** + * Copyright (c) 2012-2017, 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_Plugin_Manager_ExternalAgenda extends ZendAfi_Controller_Plugin_Manager_Manager { + public function getActions($model) { + return [ + ['url' => '/admin/external-agendas/import/id/%s', + 'icon' => 'test', + 'label' => $this->_('Moissonner') + ], + ['url' => '/admin/external-agendas/edit/id/%s', + 'icon' => 'edit', + 'label' => $this->_('Modifier'), + 'anchorOptions' => ['data-popup' => 'true']], + ['url' => '/admin/external-agendas/delete/id/%s', + 'label' => $this->_('Supprimer'), + 'icon' => 'delete', + 'anchorOptions' => ['data-popup' => 'true']] + ]; + } +} \ No newline at end of file diff --git a/library/ZendAfi/Form/Admin/ExternalAgenda.php b/library/ZendAfi/Form/Admin/ExternalAgenda.php index bef1b8f0ce6ba0f0ae432b0d0409b96e5f0251c3..295cf12deba7661f7a46cc610fd7cb4be7fba2a8 100644 --- a/library/ZendAfi/Form/Admin/ExternalAgenda.php +++ b/library/ZendAfi/Form/Admin/ExternalAgenda.php @@ -38,6 +38,10 @@ class ZendAfi_Form_Admin_ExternalAgenda extends ZendAfi_Form { 'required' => true, 'allowEmpty' => false, 'title' => $this->_('Le flux doit être au format iCalendar')]) + ->addElement('checkbox', + 'autoharvest', + ['label' => $this->_('Moissonnage automatique'), + ]) ->addElement('comboCategories', 'cat_id', @@ -52,7 +56,7 @@ class ZendAfi_Form_Admin_ExternalAgenda extends ZendAfi_Form { ['label' => $this->_('Lieu'), 'multiOptions' => ['0' => $this->_('Aucun')] + Class_Lieu::getAllLibelles()]); - $elements = ['label', 'url', 'cat_id', 'id_lieu']; + $elements = ['label', 'url','autoharvest', 'cat_id', 'id_lieu']; if (Class_AdminVar::isWorkFlowEnabled()) { $this->addElement('radio', 'status', diff --git a/tests/application/modules/admin/controllers/BatchControllerTest.php b/tests/application/modules/admin/controllers/BatchControllerTest.php index bfd78004098037b925b467c6140081fa181fd835..bb673bdc9c607a5ed720b9af91ea7038989daf12 100644 --- a/tests/application/modules/admin/controllers/BatchControllerTest.php +++ b/tests/application/modules/admin/controllers/BatchControllerTest.php @@ -115,7 +115,8 @@ class BatchControllerAddTest extends BatchControllerTestCase { ['AUTOCOMPLETE_RECORD_TITLE', 'Indexer les titres de notice pour l\'autocompletion', true], ['AUTOCOMPLETE_RECORD_AUTHOR', 'Indexer les auteurs de notice pour l\'autocompletion', true], ['BUILD_SITE_MAP', 'Régénère le sitemap XML', true], - ['NOVELTY_FACET', 'Supprimer les facettes de nouveauté périmées', true]]; + ['NOVELTY_FACET', 'Supprimer les facettes de nouveauté périmées', true], + ['EXTERNAL_AGENDA', 'Moissonner les agendas externes',true]]; } diff --git a/tests/db/UpgradeDBTest.php b/tests/db/UpgradeDBTest.php index 501402b0624aa23fd30a723b1ec5a595c4fa1f26..7a1303bbd2183a2782a3f2993414663f099deff8 100644 --- a/tests/db/UpgradeDBTest.php +++ b/tests/db/UpgradeDBTest.php @@ -1658,4 +1658,23 @@ class UpgradeDB_333_Test extends UpgradeDBTestCase { $album = $this->query('select url_origine from album where id=' . static::$album_id)->fetch(); $this->assertEquals(['url_origine' => 'https://export.1dtouch.com/oai'], $album); } +} + + + +class UpgradeDB_334_Test extends UpgradeDBTestCase { + public function prepare() { + try { + $this->query('ALTER TABLE external_agenda DROP column autoharvest'); + } + catch (Exception $e) { + } + } + + + + /** @test */ + public function columnAutoharvestShouldBePresent() { + $this->assertColumn('external_agenda','autoharvest'); + } } \ No newline at end of file diff --git a/tests/scenarios/ExternalAgendas/ExternalAgendasBatchTest.php b/tests/scenarios/ExternalAgendas/ExternalAgendasBatchTest.php new file mode 100644 index 0000000000000000000000000000000000000000..0bf5fd171e1a76e42500c3a3ddfb6470ce40f450 --- /dev/null +++ b/tests/scenarios/ExternalAgendas/ExternalAgendasBatchTest.php @@ -0,0 +1,104 @@ +<?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 + */ + + +abstract class Class_Batch_ExternalAgendasBatchTestCase extends ModelTestCase { + protected + $_storm_default_to_volatile = true, + $_log = '', + $_debug_log = ''; + + public function setUp() { + parent::setUp(); + } + + public function getLogger() { + return $this->logger = $this->mock() + ->whenCalled('log') + ->willDo( + function($message, $target = '') { + if ($target == 'debug') { + $this->_debug_log .= $message . "\n"; + return; + } + $this->_log .= $message; + }); + } +} + + + +class Class_Batch_ExternalAgendasBatchSimpleTest extends Class_Batch_ExternalAgendasBatchTestCase { + protected $_batch; + + public function setUp() { + parent::setUp(); + + + $this->valleiry = $this->fixture('Class_Bib', + ['id' => 1, + 'libelle' => 'Valleiry']); + + $events_category = $this->fixture('Class_ArticleCategorie', + ['id' => 1, + 'libelle' => 'Events', + 'bib' => $this->valleiry]); + + $this->fixture('Class_ExternalAgenda', + ['id' => 1, + 'label' => 'Personal Agenda', + 'url' => 'http://my.server.com/calendar.ics', + 'autoharvest' => 0, + 'status' => Class_Article::STATUS_VALIDATED, + 'category' => $events_category]); + + $this->fixture('Class_ExternalAgenda', + ['id' => 34, + 'label' => 'Extra Agenda', + 'url' => 'http://external.agenda.com/export?type=ics', + 'category' => $events_category, + 'id_lieu' => 0, + 'autoharvest' => 1, + 'status' => Class_Article::STATUS_VALIDATED]); + + Class_WebService_ICalendar::setDefaultHttpClient($this->mock() + ->whenCalled('open_url') + ->with('http://external.agenda.com/export?type=ics') + ->answers(file_get_contents(__DIR__.'/ical-event-second.ics'))); + + $this->_batch = new Class_Batch_ExternalAgenda(); + $this->_batch->setLogger($this->getLogger()); + $this->_batch->run(); + } + + + /** @test */ + public function labelShouldBeHarvestExternalAgenda() { + $this->assertEquals('Moissonner les agendas externes', $this->_batch->getLabel()); + } + + + /** @test */ + public function logShouldDisplayNumberOfCreatedEvents() { + $this->assertEquals("Extra Agenda:\nNombre d\'événements créés : 4\nNombre d\'événements mis à jour : 0\n",$this->_log); + + } +} diff --git a/tests/scenarios/ExternalAgendas/ExternalAgendasTest.php b/tests/scenarios/ExternalAgendas/ExternalAgendasTest.php index 6d7f510e48b7e4c454f7db1f6d2810f1eb8b3f44..3d45ce45151c0d5be99a0ee9b567a5bd2c4dc373 100644 --- a/tests/scenarios/ExternalAgendas/ExternalAgendasTest.php +++ b/tests/scenarios/ExternalAgendas/ExternalAgendasTest.php @@ -338,6 +338,13 @@ class ExternalAgendasAdminEditWithWorkflowTest extends ExternalAgendasAdminTestC } + /** @test */ + public function checkboxAutomaticHarvestShouldBePresent() { + $this->assertXPathContentContains('//form//label[@for="autoharvest"]','Moissonnage automatique'); + $this->assertXPath('//form//input[@type="checkbox"][@name="autoharvest"]'); + } + + /** @test */ public function titleShouldBeAjouterUnNouvelAgenda() { $this->assertXPathContentContains('//h1', 'Modifier un agenda');