From 0f5946b134b3f1d8f628120e48ab22727e001b6c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?ANDRE=20s=C3=A9bastien?= <sandre@afi-sa.fr>
Date: Tue, 8 Feb 2022 10:57:45 +0100
Subject: [PATCH] dev #145410 : add link in datas items when data is URL valid

---
 FEATURES/145410                               | 10 +++
 VERSIONS_WIP/145410                           |  1 +
 .../View/Helper/Notice/ExemplairesTable.php   | 23 +++--
 .../Intonation/Library/View/Wrapper/Item.php  |  7 +-
 .../NoticeAjaxControllerItemsTest.php         | 20 ++++-
 .../Templates/TemplatesSearchItemsTest.php    | 87 ++++++++++++++++---
 6 files changed, 125 insertions(+), 23 deletions(-)
 create mode 100644 FEATURES/145410
 create mode 100644 VERSIONS_WIP/145410

diff --git a/FEATURES/145410 b/FEATURES/145410
new file mode 100644
index 00000000000..fcf503c412f
--- /dev/null
+++ b/FEATURES/145410
@@ -0,0 +1,10 @@
+        '145410' =>
+            ['Label' => $this->_('Si le champ exemplaire contient une URL l\'afficher sous forme cliquable'),
+             'Desc' => '',
+             'Image' => '',
+             'Video' => '',
+             'Category' => $this->_('Exemplaire'),
+             'Right' => function($feature_description, $user) {return true;},
+             'Wiki' => 'https://wiki.bokeh-library-portal.org/index.php?title=Configurer_le_bloc_Exemplaire#Donn.C3.A9es_exemplaires',
+             'Test' => '',
+             'Date' => '2022-02-08'],
\ No newline at end of file
diff --git a/VERSIONS_WIP/145410 b/VERSIONS_WIP/145410
new file mode 100644
index 00000000000..9862c31900d
--- /dev/null
+++ b/VERSIONS_WIP/145410
@@ -0,0 +1 @@
+ - fonctionnalité #145410 : Exemplaires : si le champ exemplaire contient une URL l'afficher sous forme clicable
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/Notice/ExemplairesTable.php b/library/ZendAfi/View/Helper/Notice/ExemplairesTable.php
index 2da6e210a60..cf8ba589582 100644
--- a/library/ZendAfi/View/Helper/Notice/ExemplairesTable.php
+++ b/library/ZendAfi/View/Helper/Notice/ExemplairesTable.php
@@ -446,9 +446,12 @@ class ZendAfi_View_Helper_Notice_Exemplaires_Emplacement extends ZendAfi_View_He
 
 
 
-class ZendAfi_View_Helper_Notice_ExemplairesTable_CustomColumn extends ZendAfi_View_Helper_Notice_ExemplairesTable {
-  protected $_label, $_code;
+class ZendAfi_View_Helper_Notice_ExemplairesTable_CustomColumn
+  extends ZendAfi_View_Helper_Notice_ExemplairesTable {
 
+  protected
+    $_label,
+    $_code;
 
   public function getLibelle() {
     return $this->_label;
@@ -468,15 +471,21 @@ class ZendAfi_View_Helper_Notice_ExemplairesTable_CustomColumn extends ZendAfi_V
 
 
   public function getContent($exemplaire) {
-    return implode('. ',
-                   (new Class_Exemplaire_Fields($exemplaire))
-                   ->getDecodifiedValues($this->_code));
+    $contents = array_map(fn($value) => $this->_getValueOrUrl($value),
+                          (new Class_Exemplaire_Fields($exemplaire))
+                          ->getDecodifiedValues($this->_code));
+    return implode('. ', $contents);
   }
 
 
   public function getHeadClass() {
-    return 'subfield_'.$this->_code;
+    return 'subfield_' . $this->_code;
   }
 
+
+  protected function _getValueOrUrl(string $value) : string {
+    return Class_Url::isAnUrl($value)
+      ? $this->_tagAnchor($value, $this->_label)
+      : $value;
+  }
 }
-?>
diff --git a/library/templates/Intonation/Library/View/Wrapper/Item.php b/library/templates/Intonation/Library/View/Wrapper/Item.php
index 41e36b0303b..0d504b96401 100644
--- a/library/templates/Intonation/Library/View/Wrapper/Item.php
+++ b/library/templates/Intonation/Library/View/Wrapper/Item.php
@@ -274,11 +274,14 @@ class Intonation_Library_View_Wrapper_Item extends Intonation_Library_View_Wrapp
 
 
   protected function _badgeForSubfield($label, $subfield, $subfield_value) {
+    $is_url = Class_Url::isAnUrl($subfield_value);
+
     return (new Intonation_Library_Badge)
-      ->setTag('span')
+      ->setTag($is_url ? 'a' : 'span')
       ->setClass('badge-secondary datas_items_995_' . $subfield)
       ->setTitle(($label ? $label . ' : ' : '') . $subfield_value)
-      ->setText($subfield_value);
+      ->setText($is_url ? $label : $subfield_value)
+      ->setUrl($is_url ? $subfield_value : '');
   }
 
 
diff --git a/tests/application/modules/opac/controllers/NoticeAjaxControllerItemsTest.php b/tests/application/modules/opac/controllers/NoticeAjaxControllerItemsTest.php
index a8c982d9d7e..df1e5d7f803 100644
--- a/tests/application/modules/opac/controllers/NoticeAjaxControllerItemsTest.php
+++ b/tests/application/modules/opac/controllers/NoticeAjaxControllerItemsTest.php
@@ -50,7 +50,8 @@ abstract class NoticeAjaxControllerItemsTestCase extends AbstractControllerTestC
                              'zone995' => serialize([['code' => '9', 'valeur' => '12'],
                                                      ['code' => 'f', 'valeur' => 'abcd'],
                                                      ['code' => 'e', 'valeur' => 'EMPL1'],
-                                                     ['code' => 'e', 'valeur' => 'DTC']])]);
+                                                     ['code' => 'e', 'valeur' => 'DTC'],
+                                                     ['code' => '7', 'valeur' => 'http://myurl.com']])]);
 
     $itemB = $this->fixture('Class_Exemplaire',
                             ['id' => 134,
@@ -120,8 +121,9 @@ class NoticeAjaxControllerItemsWithoutOrderTest
     $config = Class_Profil::getCurrentProfil()->getCfgNoticeAsArray();
 
     $config['exemplaires']['grouper'] = '1';
-    $config['exemplaires']['datas_items_code'] = ['f', '9', 'e'];
-    $config['exemplaires']['datas_items_label'] = ['Code barre', 'Id', 'Emplacement'];
+    $config['exemplaires']['datas_items_code'] = ['f', '9', 'e', '7'];
+    $config['exemplaires']['datas_items_label'] = ['Code barre', 'Id',
+                                                   'Emplacement', 'Consulter URL'];
 
 
     $data_profile = Class_IntProfilDonnees::forNanook();
@@ -185,6 +187,18 @@ class NoticeAjaxControllerItemsWithoutOrderTest
   }
 
 
+  /** @test */
+  public function urlTitleShouldBePresent() {
+    $this->assertXPathContentContains('//th[@class="subfield_7"]', 'Consulter URL');
+  }
+
+
+  /** @test */
+  public function urlLinkShouldBePresent() {
+    $this->assertXPathContentContains('//td[@class="subfield_7"]/a[@href="http://myurl.com"]', 'Consulter URL');
+  }
+
+
   /** @test */
   public function itemsTableShouldContainsThForSubfieldEmplacement() {
     $this->assertXPath('//th[@class="subfield_e"][text()="Emplacement"]');
diff --git a/tests/scenarios/Templates/TemplatesSearchItemsTest.php b/tests/scenarios/Templates/TemplatesSearchItemsTest.php
index 5fca6e0e726..830042e3835 100644
--- a/tests/scenarios/Templates/TemplatesSearchItemsTest.php
+++ b/tests/scenarios/Templates/TemplatesSearchItemsTest.php
@@ -21,7 +21,9 @@
 
 require_once('TemplatesTest.php');
 
-abstract class TemplatesTestSearchItemsTestCase extends Admin_AbstractControllerTestCase {
+abstract class TemplatesTestSearchItemsTestCase
+  extends Admin_AbstractControllerTestCase {
+
   protected $_storm_default_to_volatile = true;
 
   public function setUp() {
@@ -47,7 +49,7 @@ abstract class TemplatesTestSearchItemsTestCase extends Admin_AbstractController
                     'latitude' => '12312',
                     'longitude' => '23']);
 
-    $exemplaire = $this->fixture('Class_Exemplaire',
+    $exemplaire = $this->fixture(Class_Exemplaire::class,
                                  ['id' => 3,
                                   'code_barres' => '123PS',
                                   'id_bib' => 23,
@@ -184,12 +186,6 @@ class TemplatesSearchItemsResourceWithFewItemsTests
   }
 
 
-  /** @test */
-  /*  public function hideContentShouldContainsVolume() {
-    $this->assertXPathContentContains('//div[contains(@class,"hidde_content")]', utf8_encode('no reliés :1984, no 233, no 234, no 235, 2013, mai-juin,'), $this->_response->getBody());
-    }*/
-
-
   /** @test */
   public function volumeShouldContainsNumberAndDate() {
     $this->assertXPathContentContains('//span[contains(@class,"badge-volume")]',utf8_encode('no reliés :1984, no 233'));
@@ -244,7 +240,7 @@ class TemplatesSearchItemsResourceWithMoreThan21ItemsTests
                'id_bib' => 10,
                'type' => Class_IntBib::COM_KOHA];
     $service = Class_WebService_SIGB_Koha::getService($params);
-    $this->fixture('Class_IntBib',
+    $this->fixture(Class_IntBib::class,
                    ['id' => 10,
                     'comm_sigb' => Class_IntBib::COM_KOHA,
                     'comm_params' => ['url_serveur' => 'https://monsuperkoha.org',
@@ -472,10 +468,10 @@ class TemplatesSearchItemsModulesNoticeExemplairesActionTest extends TemplatesTe
 
 
   /** @test  */
-  /*  public function formShouldContainsOnlyExpectedInputs() {
+  public function formShouldContainsOnlyExpectedInputs() {
     $this->assertXPathCount('//form//fieldset[@id="fieldset-items_fieldset"]//*[self::input or self::select][not(@type="hidden")]',
                             count($this->expectedInputs()));
-                            }*/
+  }
 }
 
 
@@ -522,3 +518,72 @@ class TemplatesSearchItemsModulesNoticeExemplairesMultiInputsTest
     $this->assertXPathContentContains('//script', 'values:{"datas_items_code":[],"datas_items_label":["Cote"]}');
   }
 }
+
+
+
+
+abstract class TemplatesSearchItemsEbookWithUrlTestCase
+  extends TemplatesTestSearchItemsTestCase {
+
+  public function setUp() {
+    parent::setUp();
+
+    $exemplaire = $this->fixture(Class_Exemplaire::class,
+                                 ['id' => 333,
+                                  'code_barres' => '987654',
+                                  'id_bib' => 23,
+                                  'section' => 1,
+                                  'emplacement' => 1,
+                                  'zone995' => serialize([
+                                                          ['code' => '7',
+                                                           'valeur' => $this->_getURL()]
+                                                          ])
+                                 ]);
+
+    $this->fixture(Class_Notice::class,
+                   ['id' => 555,
+                    'type_doc' => 1,
+                    'titre_principal' => 'Design for flooding',
+                    'clef_oeuvre' => 'FLOOD',
+                    'clef_alpha' => 'FLOOD',
+                    'facettes' => 'G13 M12',
+                    'exemplaires' => [ $exemplaire ]]);
+  }
+
+
+  protected function _getURL() : string {
+    return 'https://myurl.com/view-ebook/id/1';
+  }
+
+
+  /** @test */
+  public function withCodeAndLabelPageShouldContainsLinkWithNameConsulterURL() {
+    $this->_addInItemsSettingsAndDispatch(['datas_items_code' => ['7'],
+                                           'datas_items_label' => ['Consulter URL']],
+                                          '/noticeajax/resources/id/555');
+    $this->assertXPathContentContains('//a[contains(@class, "datas_items_995_7")][@href="' . $this->_getURL() . '"]/span',
+                                      'Consulter URL');
+  }
+}
+
+
+
+
+class TemplatesSearchItemsEbookWithHTTPUrlTest
+  extends TemplatesSearchItemsEbookWithUrlTestCase {
+
+  protected function _getURL() : string {
+    return 'http://myurl.com/view-ebook/id/1';
+  }
+}
+
+
+
+
+class TemplatesSearchItemsEbookWithHTTPSUrlTest
+  extends TemplatesSearchItemsEbookWithUrlTestCase {
+
+  protected function _getURL() : string {
+    return 'https://myurl.com/view-ebook/id/1';
+  }
+}
-- 
GitLab