From b08c1d2c4d613f0bb06e85e15396fe543b331fee Mon Sep 17 00:00:00 2001 From: gloas <gloas@afi-sa.fr> Date: Wed, 22 Aug 2018 15:46:19 +0200 Subject: [PATCH] dev #74897 add xslt input to search result configuration form --- FEATURES/74897 | 10 ++ VERSIONS_WIP/74897 | 2 + .../scripts/recherche/resultatRecherche.phtml | 1 - .../Form/Configuration/SearchResult.php | 14 ++ library/ZendAfi/View/Helper/ListeNotices.php | 8 +- library/ZendAfi/View/Helper/Notice/Entete.php | 1 + tests/scenarios/Xsl/XslTest.php | 132 +++++++++++++++++- tests/scenarios/Xsl/search_result.xsl | 90 ++++++++++++ 8 files changed, 251 insertions(+), 7 deletions(-) create mode 100644 FEATURES/74897 create mode 100644 VERSIONS_WIP/74897 create mode 100644 tests/scenarios/Xsl/search_result.xsl diff --git a/FEATURES/74897 b/FEATURES/74897 new file mode 100644 index 00000000000..2fde0164887 --- /dev/null +++ b/FEATURES/74897 @@ -0,0 +1,10 @@ + '74897' => + ['Label' => $this->_('Personnalisation des notices avec XSLT'), + 'Desc' => $this->_('Personnalisation de l\'affichage du résultat de recherche et d\'une notice par des fichiers XLST'), + 'Image' => '', + 'Video' => '', + 'Category' => $this->_('Mise en page'), + 'Right' => function($feature_description, $user) {return true;}, + 'Wiki' => '', + 'Test' => '', + 'Date' => '2018-08-22'], \ No newline at end of file diff --git a/VERSIONS_WIP/74897 b/VERSIONS_WIP/74897 new file mode 100644 index 00000000000..d9d27092767 --- /dev/null +++ b/VERSIONS_WIP/74897 @@ -0,0 +1,2 @@ + - ticket #74897 : Résultat de recherche : en mode d'affichage "vignettes", vous avez la possibilité de remplacer l'entête des notices par un fichier XSLT. + \ No newline at end of file diff --git a/application/modules/opac/views/scripts/recherche/resultatRecherche.phtml b/application/modules/opac/views/scripts/recherche/resultatRecherche.phtml index 931d49e038e..b667b57311e 100644 --- a/application/modules/opac/views/scripts/recherche/resultatRecherche.phtml +++ b/application/modules/opac/views/scripts/recherche/resultatRecherche.phtml @@ -3,4 +3,3 @@ $this->openBoite($this->titre); echo $this->Search_Header($this->search_result); $this->closeBoite(); echo $this->Search_Result($this->search_result); -?> diff --git a/library/ZendAfi/Form/Configuration/SearchResult.php b/library/ZendAfi/Form/Configuration/SearchResult.php index 9fcb2016324..7fa9e2251b7 100644 --- a/library/ZendAfi/Form/Configuration/SearchResult.php +++ b/library/ZendAfi/Form/Configuration/SearchResult.php @@ -41,6 +41,11 @@ class ZendAfi_Form_Configuration_SearchResult extends ZendAfi_Form { public function init() { parent::init(); + + Class_ScriptLoader::getInstance() + ->addJQueryReady( + 'formSelectToggleVisibilityForElement("#liste_format", $("#' . Class_Notice_Xsl::KEY . '").closest("tr"), ["3"]);'); + $this ->setAttrib('id', 'configuration_searchResult') @@ -204,9 +209,18 @@ class ZendAfi_Form_Configuration_SearchResult extends ZendAfi_Form { 'bookmarks_enabled', ['label' => $this->_('Afficher les favoris utilisateur')]) + ->addElement('userfile', + Class_Notice_Xsl::KEY, + ['label' => $this->_('Remplacer l\'entête des notices par la XSLT suivante :'), + 'allowEmpty' => true, + 'validators' => [(new Zend_Validate_Regex('/^.*\.xsl$/i')) + ->setMessage($this->_('Le fichier doit être de type "xsl"'))]]) + + ->addToDisplaySettingsGroup(['liste_format', 'liste_nb_par_page', 'liste_codes', + Class_Notice_Xsl::KEY, 'zones_titre', 'suggests_enabled', 'suggests_number', diff --git a/library/ZendAfi/View/Helper/ListeNotices.php b/library/ZendAfi/View/Helper/ListeNotices.php index 39f057e5ab1..a48e848c12f 100644 --- a/library/ZendAfi/View/Helper/ListeNotices.php +++ b/library/ZendAfi/View/Helper/ListeNotices.php @@ -61,14 +61,12 @@ class ZendAfi_View_Helper_ListeNotices extends ZendAfi_View_Helper_BaseHelper { } - protected function _displayList($notices,$preferences) { - $helpers = [ - Class_Systeme_ModulesAppli::LISTE_FORMAT_TABLEAU => 'ListeNotices_Tableau', + protected function _displayList($notices, $preferences) { + $helpers = [Class_Systeme_ModulesAppli::LISTE_FORMAT_TABLEAU => 'ListeNotices_Tableau', Class_Systeme_ModulesAppli::LISTE_FORMAT_ACCORDEON => 'ListeNotices_Accordeon', Class_Systeme_ModulesAppli::LISTE_FORMAT_VIGNETTES => 'ListeNotices_Vignettes', Class_Systeme_ModulesAppli::LISTE_FORMAT_MUR => 'ListeNotices_Mur', - Class_Systeme_ModulesAppli::LISTE_FORMAT_CHRONO => 'ListeNotices_Chrono', - ]; + Class_Systeme_ModulesAppli::LISTE_FORMAT_CHRONO => 'ListeNotices_Chrono']; $helper = $helpers[$preferences['liste_format']]; return call_user_func_array([$this->view, $helper], [$notices, $preferences]); diff --git a/library/ZendAfi/View/Helper/Notice/Entete.php b/library/ZendAfi/View/Helper/Notice/Entete.php index 08c35cc06cd..b1d393ce032 100644 --- a/library/ZendAfi/View/Helper/Notice/Entete.php +++ b/library/ZendAfi/View/Helper/Notice/Entete.php @@ -21,6 +21,7 @@ class ZendAfi_View_Helper_Notice_Entete extends ZendAfi_View_Helper_BaseHelper { + public function notice_Entete($notice, $preferences) { if(!$notice) return ''; diff --git a/tests/scenarios/Xsl/XslTest.php b/tests/scenarios/Xsl/XslTest.php index 3357c6ccfb9..f8763b5cb18 100644 --- a/tests/scenarios/Xsl/XslTest.php +++ b/tests/scenarios/Xsl/XslTest.php @@ -113,6 +113,7 @@ class XslDocTypeConfigurationPostDispatchTest extends Admin_AbstractControllerTe class XslNoticeajaxDetailDispatchTest extends AbstractControllerTestCase { + protected $_storm_default_to_volatile = true; public function setUp() { @@ -289,4 +290,133 @@ class XslFileManagerControllerWithXslInRechercheViewnoticeTest extends Admin_Abs $xslt = Class_Profil::getCurrentProfil()->getModulePreference('recherche', 'viewnoticeAssimil', 'xslt'); $this->assertContains('userfiles/bib1/xsl/titi.xsl', $xslt); } -} \ No newline at end of file +} + + + + +class XslSearchResultConfigurationDispatchTest extends Admin_AbstractControllerTestCase { + protected $_storm_default_to_volatile = true; + + + public function setUp() { + parent::setUp(); + $this->dispatch('/admin/modules/recherche/id_profil/2/action1/resultat/action2/simple/type_module/recherche/config/site', true); + } + + /** @test */ + public function inputReplaceDescriptionWithXSLTShouldBePresent() { + $this->assertXPath('//input[@type="text"][@name="xslt"]'); + } + + + /** @test */ + public function scriptSelectToggleVisibilityShouldBePresent() { + $this->assertXPathContentContains('//script', 'formSelectToggleVisibilityForElement("#liste_format"'); + } +} + + + + +class XslSearchResultPostDispatchTest extends Admin_AbstractControllerTestCase { + protected + $_storm_default_to_volatile = true, + $viewnotice_pref; + + public function setUp() { + parent::setUp(); + + $this->postDispatch('/admin/modules/recherche?config=site&type_module=recherche&id_profil=2&action1=viewnotice&action2=1', + [Class_Notice_Xsl::KEY => 'fichier.xsl']); + + $this->viewnotice_pref = Class_Profil::getCurrentProfil() + ->getCfgModulesAsArray()['recherche']['viewnotice1']; + } + + + /** @test */ + public function preferencesShouldContainsXslt() { + $this->assertEquals('fichier.xsl', + $this->viewnotice_pref[Class_Notice_Xsl::KEY]); + } +} + + + + +class XslSearchResultDispatchTest extends AbstractControllerTestCase { + + protected $_storm_default_to_volatile = true; + + + public function setUp() { + parent::setUp(); + + $disk = $this->mock() + ->whenCalled('directoryAt') + ->answers(null) + + ->whenCalled('fileAt') + ->answers((new Class_FileManager) + ->setRealpath('tests/scenarios/Xsl/search_result.xsl')); + + Class_FileManager::setFileSystem($disk); + + $php_command = $this->mock() + ->whenCalled('extension_loaded') + ->answers(true) + + ->whenCalled('unlink') + ->answers(true) + + ->whenCalled('libxml_use_internal_errors') + ->answers(true) + + ->whenCalled('libxml_get_errors') + ->answers([]); + + Class_Notice_Xsl::setPhpCommand($php_command); + + $dom_document = $this->mock() + ->whenCalled('load') + ->answers(true); + + Class_Notice_Xsl::setDomDocument($dom_document); + + $xslt_processor = $this->mock() + ->whenCalled('importStylesheet') + ->answers(true) + + ->whenCalled('transformToXml') + ->answers('<li><strong>Numéro de notice Koha : </strong>2774</li><br><li>'); + + Class_Notice_Xsl::setXSLTProcessor($xslt_processor); + + $profile = Class_Profil::getCurrentProfil(); + $profile->setCfgModulesPreferences(['xslt' => '/tests/scenarios/Xsl/search_result.xsl'], + 'recherche', + 'resultat', + 'simple'); + $profile->save(); + + $this->fixture('Class_Notice', + ['id' => 5, + 'type_doc' => 1, + 'unimarc' => "01185nam0 2200217 450 0010005000000100031000050350016000360900009000520990038000611000041000991010008001402000036001482100013001842150011001973300660002083330010008686760006008787000028008848010026009129020029009382774 a2-84563-280-0d19,90 Euros aALOES355754 a2774 c2017-12-11d2018-03-16tLIVREx12 a20171211 frey50 afre aSeras-tu là ?fGuillaume Musso cXOd2012 a301 p. aUn seul geste aurait suffi pour tout changer. Qui n'a jamais rêvé de revenir à cet instant décisif où le bonheur était possible ? San Francisco. Elliott, médecin passionné, ne s'est jamais consolé de la disparition d'Ilena, la femme qu'il aimait, morte il y a trente ans. Un jour, par une circonstance extraordinaire, il est ramené en arrière et rencontre le jeune homme qu'il était, trente ans plus tôt. Il est revenu à l'instant décisif où un geste de lui peut sauver Ilena. Et modifier l'implacable destin qui a figé son sort à jamais. Un stupéfiant face-à -face, Une histoire d'amour bouleversante, Un suspense à couper le souffle. aAG 14 aR aMussobGuillaume960415 aFRbCALUIREc20060516 981440aroman francophone"]); + + $this->dispatch('/opac/recherche/simple', true); + } + + + /** @test */ + public function shouldNotRedirect() { + $this->assertNotRedirect(); + } + + + /** @test */ + public function shouldDisplayMarcWithXslt() { + $this->assertContains('<strong>Numéro de notice Koha : </strong>2774</li><br><li>', $this->_response->getBody()); + } +} diff --git a/tests/scenarios/Xsl/search_result.xsl b/tests/scenarios/Xsl/search_result.xsl new file mode 100644 index 00000000000..55a5cbcf84c --- /dev/null +++ b/tests/scenarios/Xsl/search_result.xsl @@ -0,0 +1,90 @@ + + +<!DOCTYPE stylesheet [<!ENTITY nbsp " " >]> + +<!-- $Id: MARC21slim2DC.xsl,v 1.1 2003/01/06 08:20:27 adam Exp $ --> +<xsl:stylesheet version="1.0" + xmlns:marc="http://www.loc.gov/MARC21/slim" + xmlns:items="http://www.koha-community.org/items" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + exclude-result-prefixes="marc items"> +<xsl:import href="UNIMARCslimUtils.xsl"/> +<xsl:output method = "html" indent="yes" omit-xml-declaration = "yes" encoding="UTF-8"/> +<!--<xsl:key name="item-by-status" match="items:item" use="items:status"/> +<xsl:key name="item-by-status-and-branch" match="items:item" use="concat(items:status, ' ', items:homebranch)"/>--> + +<xsl:template match="/"> + <xsl:apply-templates/> +</xsl:template> + +<xsl:template match="marc:record"> + <xsl:variable name="IntranetBiblioDefaultView" select="marc:sysprefs/marc:syspref[@name='IntranetBiblioDefaultView']"/> + <xsl:variable name="leader" select="marc:leader"/> + <xsl:variable name="leader6" select="substring($leader,7,1)"/> + <xsl:variable name="leader7" select="substring($leader,8,1)"/> + <xsl:variable name="biblionumber" select="marc:controlfield[@tag=001]"/> + <xsl:variable name="isbn" select="marc:datafield[@tag=010]/marc:subfield[@code='a']"/> + + <xsl:if test="marc:datafield[@tag=200]"> + <xsl:for-each select="marc:datafield[@tag=200]"> + <a> + <xsl:attribute name="href"> + <xsl:call-template name="buildBiblioDefaultViewURL"> + <xsl:with-param name="IntranetBiblioDefaultView"> + <xsl:value-of select="$IntranetBiblioDefaultView"/> + </xsl:with-param> + </xsl:call-template> + <xsl:value-of select="$biblionumber"/> + </xsl:attribute> + <xsl:attribute name="class">title</xsl:attribute> + + <xsl:variable name="title" select="marc:subfield[@code='a']"/> + <xsl:variable name="ntitle" + select="translate($title, '˜œ슜슛슘슈슉','')"/> + <xsl:value-of select="$ntitle" /> + </a> + <xsl:if test="marc:subfield[@code='e']"> + <xsl:for-each select="marc:subfield[@code='e']"> + <xsl:text> : </xsl:text> + <xsl:value-of select="."/> + </xsl:for-each> + </xsl:if> + <xsl:if test="marc:subfield[@code='d']"> + <xsl:for-each select="marc:subfield[@code='d']"> + <xsl:text> = </xsl:text> + <xsl:value-of select="."/> + </xsl:for-each> + </xsl:if> + <xsl:if test="marc:subfield[@code='b']"> + <xsl:text> [</xsl:text> + <xsl:value-of select="marc:subfield[@code='b']"/> + <xsl:text>]</xsl:text> + </xsl:if> + <xsl:if test="marc:subfield[@code='h']"> + <xsl:text> : </xsl:text> + <xsl:value-of select="marc:subfield[@code='h']"/> + </xsl:if> + <xsl:if test="marc:subfield[@code='i']"> + <xsl:text> : </xsl:text> + <xsl:value-of select="marc:subfield[@code='i']"/> + </xsl:if> + <xsl:if test="marc:subfield[@code='f']"> + <xsl:text> / </xsl:text> + <xsl:value-of select="marc:subfield[@code='f']"/> + </xsl:if> + <xsl:if test="marc:subfield[@code='g']"> + <xsl:text> ; </xsl:text> + <xsl:value-of select="marc:subfield[@code='g']"/> + </xsl:if> + <xsl:text> </xsl:text> + </xsl:for-each> + </xsl:if> + + <xsl:call-template name="tag_4xx" /> + + <xsl:call-template name="tag_210" /> + + <xsl:call-template name="tag_215" /> + +</xsl:template> +</xsl:stylesheet> -- GitLab