From 13e311253304707678af8513a2848d8c64c5ff7c Mon Sep 17 00:00:00 2001
From: gloas <gloas@afi-sa.fr>
Date: Thu, 12 Apr 2018 14:16:36 +0200
Subject: [PATCH] dev #73871 implementing xslt

---
 library/Class/Notice/Xsl.php                  | 21 +++++-
 library/Class/Testing/Yaz.php                 | 14 +++-
 library/ZendAfi/Form/Configuration/Record.php |  4 +-
 library/ZendAfi/View/Helper/Notice/Xsl.php    | 21 +++++-
 .../RechercheControllerViewnoticeTest.php     | 55 ---------------
 tests/scenarios/Xsl/XslTest.php               | 70 +++++++++++++++++--
 6 files changed, 116 insertions(+), 69 deletions(-)

diff --git a/library/Class/Notice/Xsl.php b/library/Class/Notice/Xsl.php
index c8b8764ceb8..4d490e31581 100644
--- a/library/Class/Notice/Xsl.php
+++ b/library/Class/Notice/Xsl.php
@@ -21,7 +21,9 @@
 
 
 class Class_Notice_Xsl {
-  use Trait_StaticPhpCommand;
+  use Trait_StaticPhpCommand, Trait_Yaz;
+
+  const KEY = 'xslt';
 
   protected
     $_record,
@@ -58,6 +60,19 @@ class Class_Notice_Xsl {
   }
 
 
+  public function getMarcXmlFile() {
+    if(!$this->_record)
+      return '';
+
+    if(!$marc = $this->_record->getUnimarc())
+      return '';
+
+    return ($marc_xml_array = static::getYaz()->marcToMarcXml($marc))
+      ? static::getYaz()->writeMarcXmlInFile(implode($marc_xml_array))
+      : '';
+  }
+
+
   protected function _getXslFileFromProfile() {
     $settings = $this->_profile->getCfgModulesPreferences('recherche', 'viewnotice', $this->_record->getTypeDoc());
     if(!$settings)
@@ -66,9 +81,9 @@ class Class_Notice_Xsl {
     if(empty($settings))
       return;
 
-    if(!array_key_exists('xsl', $settings))
+    if(!array_key_exists(Class_Notice_Xsl::KEY, $settings))
       return;
 
-    return $settings['xsl'];
+    return $settings[Class_Notice_Xsl::KEY];
   }
 }
\ No newline at end of file
diff --git a/library/Class/Testing/Yaz.php b/library/Class/Testing/Yaz.php
index ab103b5f078..f523ec1eab3 100644
--- a/library/Class/Testing/Yaz.php
+++ b/library/Class/Testing/Yaz.php
@@ -40,9 +40,19 @@ class Class_Testing_Yaz {
 
 
   protected function _writeUnimarcInFile($unimarc) {
-    $filename = PATH_TEMP . md5($unimarc) . '.marc';
+    return $this->_writeContentInTempFolder($unimarc, 'marc');
+  }
+
+
+  public function writeMarcXmlInFile($marc_xml) {
+    return $this->_writeContentInTempFolder($marc_xml, 'xml');
+  }
+
+
+  protected function _writeContentInTempFolder($content, $extension) {
+    $filename = 'temp/' . md5($content) . '.' . $extension;
     static::getFileSystem()->unlink($filename);
-    static::getFileSystem()->file_put_contents($filename, $unimarc);
+    static::getFileSystem()->file_put_contents($filename, $content);
     return $filename;
   }
 }
\ No newline at end of file
diff --git a/library/ZendAfi/Form/Configuration/Record.php b/library/ZendAfi/Form/Configuration/Record.php
index 8cf8cc70a2f..a5f67d06412 100644
--- a/library/ZendAfi/Form/Configuration/Record.php
+++ b/library/ZendAfi/Form/Configuration/Record.php
@@ -30,7 +30,7 @@ class ZendAfi_Form_Configuration_Record extends ZendAfi_Form {
                    ['label' => $this->_('Composition de l\'affichage')])
 
       ->addElement('userfile',
-                   'xslt',
+                   Class_Notice_Xsl::KEY,
                    ['label' => $this->_('Remplacer la description par la XSLT suivante :'),
                     'allowEmpty' => true,
                     'validators' => [(new Zend_Validate_Regex('/^.*\.xsl$/i'))
@@ -93,7 +93,7 @@ class ZendAfi_Form_Configuration_Record extends ZendAfi_Form {
                         'head_group',
                         ['legend' => $this->_('Entête')])
       ->addDisplayGroup(['record_tabs',
-                         'xslt'],
+                         Class_Notice_Xsl::KEY],
                         'record_display_group',
                         ['legend' => $this->_('Affichage')])
       ->addDisplayGroup(['links_zones'],
diff --git a/library/ZendAfi/View/Helper/Notice/Xsl.php b/library/ZendAfi/View/Helper/Notice/Xsl.php
index c7cf20e201b..23d6f00483b 100644
--- a/library/ZendAfi/View/Helper/Notice/Xsl.php
+++ b/library/ZendAfi/View/Helper/Notice/Xsl.php
@@ -22,15 +22,30 @@
 
 class ZendAfi_View_Helper_Notice_Xsl extends ZendAfi_View_Helper_BaseHelper {
   public function Notice_Xsl($xsl) {
+    if(!$xsl_file = $xsl->getXslFile())
+      return '';
+
+    if(!$marc_xml = $xsl->getMarcXmlFile())
+      return '';
+
     $xsl_doc = new DOMDocument();
-    $xsl_doc->load($xsl->getXslFile());
+    $xsl_doc->load($xsl_file);
 
     $xml = new DOMDocument();
-    $xml->load($xsl->getMarcXml());
+    $xml->load($marc_xml);
 
     $xslt = new XSLTProcessor();
     $xslt->importStylesheet($xsl_doc);
 
-    return $xslt->transformToXml($xml);
+    if(!$response = $xslt->transformToXml($xml))
+      return $this->_tag('p', $this->_('La transformation du %s en HTML par le fichier %s n\'a pas fonctionné.',
+                                       $this->view->tagAnchor(Class_Url::absolute($marc_xml),
+                                                              $this->_('marc-xml'),
+                                                              ['target' => 'blank']),
+                                       $this->view->tagAnchor(Class_Url::absolute($xsl_file),
+                                                              $this->_('xsl'),
+                                                              ['target' => 'blank'])),
+                         ['class' => 'error']);
+    return $response;
   }
 }
\ No newline at end of file
diff --git a/tests/application/modules/opac/controllers/RechercheControllerViewnoticeTest.php b/tests/application/modules/opac/controllers/RechercheControllerViewnoticeTest.php
index 3b7dc0d0991..a382cf40781 100644
--- a/tests/application/modules/opac/controllers/RechercheControllerViewnoticeTest.php
+++ b/tests/application/modules/opac/controllers/RechercheControllerViewnoticeTest.php
@@ -91,59 +91,4 @@ class RechercheControllerSearchResultWithInspectorGadgetTest extends AbstractCon
   public function buttonConfigurationOfSearchShouldBePresent() {
     $this->assertXPathContentContains('//button', 'Configuration de la recherche');
   }
-}
-
-
-
-
-class RechercheControllerViewnoticeWithInspectorGadgetAndMarcXMLEnabledTest extends AbstractControllerTestCase {
-  protected $_storm_default_to_volatile = true;
-
-  public function setUp() {
-    parent::setUp();
-    Class_AdminVar::set('INSPECTOR_GADGET_MARC_XML', 1);
-
-    $cmd = $this->mock()
-                ->whenCalled('exec')
-                ->answers(true)
-
-                ->whenCalled('getOutput')
-                ->answers(['<collection xmlns="http://www.loc.gov/MARC21/slim">',
-                           '<record>',
-                           '<leader>01185nam0a2200217 450 </leader>',
-                           '<controlfield tag="001">2774</controlfield>',
-                           '<datafield tag="010" ind1=" " ind2=" ">',
-                           '<subfield code="a">2-84563-280-0</subfield>']);
-
-    $filesystem = $this->mock()
-                       ->whenCalled('unlink')
-                       ->answers(true)
-
-                       ->whenCalled('file_put_contents')
-                       ->answers(true);
-
-    Class_Testing_Yaz::setCommand($cmd);
-    Class_Testing_Yaz::setFileSystem($filesystem);
-
-    $this->fixture('Class_Notice',
-                   ['id' => 2,
-                    'type_doc' => Class_TypeDoc::DILICOM,
-                    '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",
-                    'alpha_titre' => '',
-                    'alpha_auteur' => '']);
-
-    $this->dispatch('/opac/recherche/viewnotice/id/2/inspector_gadget/1', true);
-  }
-
-
-  /** @test */
-  public function tabMarcXMLShouldBePresent() {
-    $this->assertXPathContentContains('//button[contains(@onclick, "#ig-tab-marc-xml")]', 'Notice Bokeh');
-  }
-
-
-  /** @test */
-  public function marcXMLShouldBePresent() {
-    $this->assertXPathContentContains('//button[contains(@onclick, "controlfield")]', 'Notice Bokeh');
-  }
 }
\ No newline at end of file
diff --git a/tests/scenarios/Xsl/XslTest.php b/tests/scenarios/Xsl/XslTest.php
index eee08703b34..f8de2ad572d 100644
--- a/tests/scenarios/Xsl/XslTest.php
+++ b/tests/scenarios/Xsl/XslTest.php
@@ -20,6 +20,61 @@
  */
 
 
+class XslRechercheControllerViewnoticeWithInspectorGadgetAndMarcXMLEnabledTest extends AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
+  public function setUp() {
+    parent::setUp();
+    Class_AdminVar::set('INSPECTOR_GADGET_MARC_XML', 1);
+
+    $cmd = $this->mock()
+                ->whenCalled('exec')
+                ->answers(true)
+
+                ->whenCalled('getOutput')
+                ->answers(['<collection xmlns="http://www.loc.gov/MARC21/slim">',
+                           '<record>',
+                           '<leader>01185nam0a2200217 450 </leader>',
+                           '<controlfield tag="001">2774</controlfield>',
+                           '<datafield tag="010" ind1=" " ind2=" ">',
+                           '<subfield code="a">2-84563-280-0</subfield>']);
+
+    $filesystem = $this->mock()
+                       ->whenCalled('unlink')
+                       ->answers(true)
+
+                       ->whenCalled('file_put_contents')
+                       ->answers(true);
+
+    Class_Testing_Yaz::setCommand($cmd);
+    Class_Testing_Yaz::setFileSystem($filesystem);
+
+    $this->fixture('Class_Notice',
+                   ['id' => 2,
+                    'type_doc' => Class_TypeDoc::DILICOM,
+                    '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",
+                    'alpha_titre' => '',
+                    'alpha_auteur' => '']);
+
+    $this->dispatch('/opac/recherche/viewnotice/id/2/inspector_gadget/1', true);
+  }
+
+
+  /** @test */
+  public function tabMarcXMLShouldBePresent() {
+    $this->assertXPathContentContains('//button[contains(@onclick, "#ig-tab-marc-xml")]', 'Notice Bokeh');
+  }
+
+
+  /** @test */
+  public function marcXMLShouldBePresent() {
+    $this->assertXPathContentContains('//button[contains(@onclick, "controlfield")]', 'Notice Bokeh');
+  }
+}
+
+
+
+
 class XslDocTypeConfigurationDispatchTest extends Admin_AbstractControllerTestCase {
   protected $_storm_default_to_volatile = true;
 
@@ -41,7 +96,7 @@ class XslDocTypeConfigurationPostDispatchTest extends Admin_AbstractControllerTe
     parent::setUp();
 
     $this->postDispatch('/admin/modules/recherche?config=site&type_module=recherche&id_profil=2&action1=viewnotice&action2=1',
-                        ['xslt' => 'fichier.xsl']);
+                        [Class_Notice_Xsl::KEY => 'fichier.xsl']);
 
     $this->viewnotice_pref = Class_Profil::getCurrentProfil()
       ->getCfgModulesAsArray()['recherche']['viewnotice1'];
@@ -51,7 +106,7 @@ class XslDocTypeConfigurationPostDispatchTest extends Admin_AbstractControllerTe
   /** @test */
   public function preferencesShouldContainsXslt() {
     $this->assertEquals('fichier.xsl',
-                        $this->viewnotice_pref['xslt']);
+                        $this->viewnotice_pref[Class_Notice_Xsl::KEY]);
   }
 }
 
@@ -68,7 +123,7 @@ class XslNoticeajaxDetailDispatchTest extends AbstractControllerTestCase {
     Class_Notice_Xsl::setPhpCommand($php_command);
 
     $profile = Class_Profil::getCurrentProfil();
-    $profile->setCfgModulesPreferences(['xsl' => 'tests/scenarios/Xsl/record_description.xsl'],
+    $profile->setCfgModulesPreferences(['xslt' => 'tests/scenarios/Xsl/record_description.xsl'],
                                        'recherche',
                                        'viewnotice',
                                        '1');
@@ -76,7 +131,8 @@ class XslNoticeajaxDetailDispatchTest extends AbstractControllerTestCase {
 
     $this->fixture('Class_Notice',
                    ['id' => 5,
-                    'type_doc' => 1]);
+                    '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/noticeajax/detail/id_notice/5', true);
   }
@@ -86,4 +142,10 @@ class XslNoticeajaxDetailDispatchTest extends AbstractControllerTestCase {
   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());
+  }
 }
\ No newline at end of file
-- 
GitLab