diff --git a/library/Trait/Tree.php b/application/modules/admin/controllers/Pcdm4BrowserController.php similarity index 82% rename from library/Trait/Tree.php rename to application/modules/admin/controllers/Pcdm4BrowserController.php index 93aa996a77afa01d223aa081609fc33ee93f3dbe..890487f1a472395a69ac7b64667c3d451dc78a39 100644 --- a/library/Trait/Tree.php +++ b/application/modules/admin/controllers/Pcdm4BrowserController.php @@ -20,7 +20,8 @@ */ -trait Trait_Tree { - abstract public function getParent(); - abstract public function getChildren(); +class Admin_Pcdm4BrowserController extends ZendAfi_Controller_Action { + public function getPlugins() { + return ['ZendAfi_Controller_Plugin_ResourceDefinition_Codification_Pcdm4']; + } } \ No newline at end of file diff --git a/library/Class/CodifPcdm4.php b/library/Class/CodifPcdm4.php index f150873e038899a3fa0a74f3447ef9d11c313ad2..e41d627762b2b211bad190b3ca6fddee9c437a29 100644 --- a/library/Class/CodifPcdm4.php +++ b/library/Class/CodifPcdm4.php @@ -20,30 +20,133 @@ */ class Class_CodifPcdm4Loader extends Storm_Model_Loader { -// ---------------------------------------------------------------- -// Rend le libelle ou le code si le libelle est vide -// ---------------------------------------------------------------- + + public function findParentOf($instance) { + if (!$instance || $instance->isNew()) + return; + + if ('' === $parent_id = substr($instance->getId(), 0, -1)) + return; + + return Class_CodifPcdm4::find($parent_id); + } + + + public function findLeavesOfBy($instance, $params = []) { + return array_filter($instance->getChildren($params), + function ($child) + { + return !$child->hasChildren(); + }); + } + + + public function findNodesOfBy($instance, $params = []) { + return array_filter($instance->getChildren($params), + function ($child) + { + return $child->hasChildren(); + }); + } + + + public function findChildrenOfBy($instance, $params = []) { + if(!$instance) + return []; + + $id = $instance->getId(); + $length = $instance->isNew() + ? ' = 1' + : ' = ' . (strlen($id) + 1); + + $where = sprintf('id_pcdm4 like "%s%%" and LENGTH(id_pcdm4) %s', + $id, + $length); + + $params = array_merge(['order' => 'id_pcdm4'], + $params, + ['where' => $where]); + + return Class_CodifPcdm4::findAllBy($params); + } + + + public function recursiveNumberOfChildrenOf($instance) { + if($instance->isNew()) + return 0; + + $id = $instance->getId(); + $where = sprintf('id_pcdm4 like "%s%%" and LENGTH(id_pcdm4) > %s', + $id, + strlen($id)); + + return Class_CodifPcdm4::countBy(['where' => $where]); + } + + public function getLibelle($indice) { - return (($pcdm4 = Class_CodifPcdm4::find($indice)) && $pcdm4->getLibelle()) - ? $pcdm4->getLibelle() - : Class_CodifPcdm4::formatIndice($indice); + return ($pcdm4 = Class_CodifPcdm4::find($indice)) + ? $pcdm4->getLibelle() + : Class_CodifPcdm4::formatIndice($indice); + } + + + public function formatIndice($indice) { + return (strlen($indice) < 2) + ? $indice + : substr($indice, 0, 1) . '.' . substr($indice, 1); + } + + + public function filtreIndice($indice) { + $indice=trim($indice); + if(strlen($indice) > 1 and substr($indice,1,1) != ".") + return ""; + + $new=""; + for($i=0; $i<strlen($indice); $i++) { + $car = substr($indice, $i, 1); + if ($car >= "0" and $car<="9") + $new .= $car; + } + + return $new; + } + + + public function getIndices($pere) { + $sql = Zend_Registry::get('sql'); + if ($pere == "root") + $liste=$sql->fetchAll("select * from codif_pcdm4 where LENGTH(id_pcdm4)=1 order by id_pcdm4"); + else { + $long=strlen($pere)+1; + $req="select * from codif_pcdm4 where id_pcdm4 like '$pere%' and LENGTH(id_pcdm4)=$long order by id_pcdm4"; + $liste =$sql->fetchAll($req); + } + return $liste; + } + + + public function root() { + return new Class_CodifPcdm4; } } + + + class Class_CodifPcdm4 extends Storm_Model_Abstract { + use Trait_Facetable, Trait_TreeNode; const CODE_FACETTE = 'P'; - protected $_table_name = 'codif_pcdm4'; - protected $_table_primary = 'id_pcdm4'; - protected $_loader_class = 'Class_CodifPcdm4Loader'; + protected + $_table_name = 'codif_pcdm4', + $_table_primary = 'id_pcdm4', + $_loader_class = 'Class_CodifPcdm4Loader'; + - // ---------------------------------------------------------------- -// Rend une liste pour un champ suggestion -// ---------------------------------------------------------------- - public function getListeSuggestion($recherche,$mode,$limite_resultat) - { - // Lancer la recherche + public function getListeSuggestion($recherche,$mode,$limite_resultat) { $new = ''; if($mode=="1") { @@ -55,7 +158,6 @@ class Class_CodifPcdm4 extends Storm_Model_Abstract { $resultat=fetchAll($req); - // Mettre l'indice et le libelle if(!$resultat) return false; foreach($resultat as $enreg) { @@ -65,46 +167,11 @@ class Class_CodifPcdm4 extends Storm_Model_Abstract { return $liste; } -// ---------------------------------------------------------------- -// Rend une liste d'indices par niveau -// ---------------------------------------------------------------- - static function getIndices($pere) - { - $sql = Zend_Registry::get('sql'); - if ($pere == "root") - $liste=$sql->fetchAll("select * from codif_pcdm4 where LENGTH(id_pcdm4)=1 order by id_pcdm4"); - else { - $long=strlen($pere)+1; - $req="select * from codif_pcdm4 where id_pcdm4 like '$pere%' and LENGTH(id_pcdm4)=$long order by id_pcdm4"; - $liste =$sql->fetchAll($req); - } - return $liste; - } -// ---------------------------------------------------------------- -// Ponctue un indice pcdm4 -// ---------------------------------------------------------------- - static function formatIndice($indice) - { - if(strlen($indice)< 2) return $indice; - $new=substr($indice,0,1).".".substr($indice,1); - return $new; - } -// ---------------------------------------------------------------- -// Analyse et rend l'indice s'il est valide -// ---------------------------------------------------------------- - static function filtreIndice($indice) - { - $indice=trim($indice); - if(strlen($indice) > 1 and substr($indice,1,1) != ".") return ""; - $new=""; - for($i=0; $i<strlen($indice); $i++) - { - $car=$indice[$i]; - if($car >="0" and $car<="9") $new.=$car; - } - return $new; - } - -} -?> \ No newline at end of file + public function getLibelle() { + $libelle = parent::_get('libelle'); + return $libelle + ? $libelle + : $this->getLoader()->formatIndice($this->getId()); + } +} \ No newline at end of file diff --git a/library/Class/CodifTypeDoc.php b/library/Class/CodifTypeDoc.php index 8b8ad871a3d709fcb73e74769a340f4c2933332c..5aef7d14fbb63054d4c5122950f112248d7c6231 100644 --- a/library/Class/CodifTypeDoc.php +++ b/library/Class/CodifTypeDoc.php @@ -35,7 +35,8 @@ class Class_CodifTypeDoc extends Storm_Model_Abstract { protected $_table_primary = 'type_doc_id'; protected $_default_attribute_values = ['bibliotheques' => '', 'annexes' => '', - 'sections' => '']; + 'sections' => '', + 'famille_id' => '']; protected static $_libelles = [self::INCONNU => 'Non identifié', self::LIVRE => 'Livre', diff --git a/library/Class/ListViewModeDescription/Pcdm4.php b/library/Class/ListViewModeDescription/Pcdm4.php new file mode 100644 index 0000000000000000000000000000000000000000..295e06a6625bbc6609eb7615a252457a98db770f --- /dev/null +++ b/library/Class/ListViewModeDescription/Pcdm4.php @@ -0,0 +1,71 @@ +<?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 Class_ListViewModeDescription_Pcdm4 extends Class_ListViewModeDescription { + + public function __construct($context) { + parent::__construct($context); + if(!$this->_context->getOrder()) + $this->_context->setOrder('id_pcdm4'); + } + + + protected function _getLabel() { + return $this->_('PCDM4'); + } + + + protected function _getController() { + return 'pcdm4-browser'; + } + + + protected function _getModel() { + return null === $this->_context->getParentId() + ? Class_CodifPcdm4::root() + : Class_CodifPcdm4::find($this->_context->getParentId()); + } + + + protected function _getSearchColumns() { + return ['libelle', + 'id_pcdm4']; + } + + + public function describeCategoriesIn($description, $list_view_mode) { + return $description + ->addColumn($this->_('PCDM4'), ['attribute' => 'libelle', + 'callback' => $list_view_mode->renderCategoryClosure()]) + ->addColumn($this->_('Code facette'), 'facet_code'); + } + + + public function describeItemsIn($description, $list_view_mode) { + return $description + ->addColumn($this->_('PCDM4'), ['attribute' => 'libelle', + 'callback' => $list_view_mode->renderItemClosure()]) + ->addColumn($this->_('Code facette'), ['attribute' => 'facet_code', + 'sort_attribute' => 'id_pcdm4']) + ->setSorterServer(); + } +} \ No newline at end of file diff --git a/library/Trait/TreeNode.php b/library/Trait/TreeNode.php index f35e89f486f22618ec46df6c0c4371f1b49f4bf8..265bcb563ed17fb051c988bf7a76b82a4c66d2f9 100644 --- a/library/Trait/TreeNode.php +++ b/library/Trait/TreeNode.php @@ -20,7 +20,6 @@ */ trait Trait_TreeNode { - use Trait_Tree; public static $PATH_SEPARATOR = '/'; @@ -89,20 +88,35 @@ trait Trait_TreeNode { } - public function getLeaves() { - ; + public function getParent() { + return $this->getLoader()->findParentOf($this); } - public function getNodes() { - ; + public function getLeaves($params = []) { + if($this->isNew()) + return []; + + return $this->getLoader()->findLeavesOfBy($this, $params); + } + + + public function getNodes($params = []) { + return $this->getLoader()->findNodesOfBy($this, $params); + } + + + public function getChildren($params = []) { + return $this->getLoader()->findChildrenOfBy($this, $params); } public function numberOfLeaves() { + return count($this->getLeaves()); } public function recursiveNumberOfChildren() { + return $this->getLoader()->recursiveNumberOfChildrenOf($this); } } \ No newline at end of file diff --git a/library/Trait/TreeViewableCategorie.php b/library/Trait/TreeViewableCategorie.php index 56dd3940c382eb36870a40a6d5a476f80fbe3aa3..e18d9ce944144e07062dfef7a8ae69436332a526 100644 --- a/library/Trait/TreeViewableCategorie.php +++ b/library/Trait/TreeViewableCategorie.php @@ -20,7 +20,6 @@ */ trait Trait_TreeViewableCategorie { - use Trait_Tree; /** * @return bool diff --git a/library/Trait/TreeViewableItem.php b/library/Trait/TreeViewableItem.php index eb01606fe2c3cf5c2aea1f85705014a4a66cdce7..ef7d466ca2ed5ec0de7d273cffa453d875d69545 100644 --- a/library/Trait/TreeViewableItem.php +++ b/library/Trait/TreeViewableItem.php @@ -20,7 +20,6 @@ */ trait Trait_TreeViewableItem { - use Trait_Tree; public function getBib() { return $this->getCategorie() diff --git a/library/ZendAfi/Controller/Action/Helper/AbstractListViewMode.php b/library/ZendAfi/Controller/Action/Helper/AbstractListViewMode.php index 892c7802fb67f62f24acc3c0d2d797e6f6c97126..a5f2b345238bb8d2db5fb6489216a16bc3c2b6c3 100644 --- a/library/ZendAfi/Controller/Action/Helper/AbstractListViewMode.php +++ b/library/ZendAfi/Controller/Action/Helper/AbstractListViewMode.php @@ -63,7 +63,7 @@ abstract class ZendAfi_Controller_Action_Helper_AbstractListViewMode extends Zen $url = $this->_view->url($this->renderCategoryUrlParams($model), null, true); $label = Class_Admin_Skin::current()->renderActionIconOn('category', $this->_view) - . $model->$attrib; + . $model->callGetterByAttributeName($attrib); $count = ''; @@ -94,7 +94,7 @@ abstract class ZendAfi_Controller_Action_Helper_AbstractListViewMode extends Zen protected function _renderItem($model, $attrib) { - $value = call_user_func([$model, 'get' . Storm_Inflector::camelize($attrib)]); + $value = $model->callGetterByAttributeName($attrib); if (!$this->isSearching()) return $value; diff --git a/library/ZendAfi/Controller/Action/Helper/CodificationListViewMode.php b/library/ZendAfi/Controller/Action/Helper/CodificationListViewMode.php index 6b575147760edeaf75aa110bd86df3ee368280ce..dad1b0188e1529b53826090396607ed0e200774b 100644 --- a/library/ZendAfi/Controller/Action/Helper/CodificationListViewMode.php +++ b/library/ZendAfi/Controller/Action/Helper/CodificationListViewMode.php @@ -52,6 +52,10 @@ class ZendAfi_Controller_Action_Helper_CodificationListViewMode ->setLibelle($this->_('Langues')) ->setController('language-browser'), + (new Class_CodifPcdm4) + ->setLibelle($this->_('PCDM4')) + ->setController('pcdm4-browser'), + (new Class_CodifSection) ->setLibelle($this->_('Sections')) ->setController('section-browser'), @@ -68,8 +72,8 @@ class ZendAfi_Controller_Action_Helper_CodificationListViewMode ->setLibelle($this->_('Thesaurus')) ->setController('thesauri'), - (new Class_CodifTypeDoc) - ->setLibelle($this->_('Types de documents')) + (new Class_TypeDoc) + ->setLabel($this->_('Types de documents')) ->setController('doctype-browser')]; } diff --git a/library/ZendAfi/Controller/Plugin/ResourceDefinition/Codification/Pcdm4.php b/library/ZendAfi/Controller/Plugin/ResourceDefinition/Codification/Pcdm4.php new file mode 100644 index 0000000000000000000000000000000000000000..2b34cf827016f46d6475c842783dfca4495cd261 --- /dev/null +++ b/library/ZendAfi/Controller/Plugin/ResourceDefinition/Codification/Pcdm4.php @@ -0,0 +1,36 @@ +<?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_ResourceDefinition_Codification_Pcdm4 + extends ZendAfi_Controller_Plugin_ResourceDefinition_Codification_Abstract { + + public function getDefinitions() { + return + ['model' => ['class' => 'Class_CodifPcdm4', + 'name' => 'pcdm4', + 'order' => 'libelle'], + + 'listViewMode' => 'Class_ListViewModeDescription_Pcdm4', + + 'actions' => ['index' => ['title' => $this->_('Parcourir la codification PCDM4')]]]; + } +} \ No newline at end of file diff --git a/tests/scenarios/CodificationBrowser/CodificationBrowserTest.php b/tests/scenarios/CodificationBrowser/CodificationBrowserTest.php index 69bd6051bd0b2a55793b58df779845e19a201036..1f751f9aae3b19a48e854d918c4ec267c7ab98ef 100644 --- a/tests/scenarios/CodificationBrowser/CodificationBrowserTest.php +++ b/tests/scenarios/CodificationBrowser/CodificationBrowserTest.php @@ -42,7 +42,8 @@ class CodificationBrowserIndexDispatchTest extends Admin_AbstractControllerTestC ['genre-browser', 'Genres'], ['subject-browser', 'Sujets et matières'], ['tag-browser', 'Tags'], - ['doctype-browser', 'Types de documents']]; + ['doctype-browser', 'Types de documents'], + ['pcdm4-browser', 'PCDM4']]; } @@ -200,3 +201,12 @@ class CodificationBrowserDoctypeSimpleIndexTest extends CodificationBrowserSimpl $_model = 'Class_TypeDoc', $_attribs = ['id' => 1, 'label' => 'Livres']; } + + + +class CodificationBrowserPCDM4SimpleIndexTest extends CodificationBrowserSimpleIndexTestCase { + protected + $_controller = 'pcdm4-browser', + $_model = 'Class_CodifPcdm4', + $_attribs = ['id' => '0', 'libelle' => 'Histoire']; +} diff --git a/tests/scenarios/Pcdm4Browser/Pcdm4BrowserTest.php b/tests/scenarios/Pcdm4Browser/Pcdm4BrowserTest.php new file mode 100644 index 0000000000000000000000000000000000000000..117f236e09b41fff5072688ca1a3820aec2750d0 --- /dev/null +++ b/tests/scenarios/Pcdm4Browser/Pcdm4BrowserTest.php @@ -0,0 +1,77 @@ +<?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 Pcdm4BrowserIndexChildrenTest extends Admin_AbstractControllerTestCase{ + protected $_storm_default_to_volatile = true; + + public function setUp() { + parent::setUp(); + $mainstream = $this->fixture('Class_CodifPcdm4', + ['id' => '0', + 'libelle' => 'Mainstream']); + + $notso = $this->fixture('Class_CodifPcdm4', + ['id' => '01', + 'libelle' => 'Not so mainstream']); + + $notsoleaf = $this->fixture('Class_CodifPcdm4', + ['id' => '02', + 'libelle' => 'Not so leaf']); + + $this->onLoaderOfModel('Class_CodifPcdm4') + ->whenCalled('find')->with('0')->answers($mainstream) + ->whenCalled('findParentOf')->with($mainstream)->answers(null) + ->whenCalled('findNodesOfBy')->with($mainstream, [])->answers([$notso]) + ->whenCalled('recursiveNumberOfChildrenOf')->with($notso)->answers(1) + + ->whenCalled('findLeavesOfBy') + ->with($mainstream, ['limitPage' => [null, 25], + 'order' => 'id_pcdm4']) + ->answers([$notsoleaf]) + + ->whenCalled('findLeavesOfBy') + ->with($mainstream, []) + ->answers([$notsoleaf]) + + ->beStrict(); + + $this->dispatch('/admin/pcdm4-browser/index/parent_id/0', true); + } + + + /** @test */ + public function mainstreamShouldBeDisplay() { + $this->assertXpathContentContains('//a', 'Mainstream', $this->_response->getBody()); + } + + + /** @test */ + public function notsoShouldBeInTable() { + $this->assertXpathContentContains('//td', 'Not so mainstream'); + } + + + /** @test */ + public function notsoleafShouldBeInTable() { + $this->assertXpathContentContains('//td', 'Not so leaf'); + } +}