From 784160e39b25fdb92537d22e930f117469f65382 Mon Sep 17 00:00:00 2001
From: Patrick Barroca <pbarroca@afi-sa.fr>
Date: Fri, 16 Apr 2021 10:55:47 +0200
Subject: [PATCH] hotline #126267 : fix open blocks in historic record view

---
 VERSIONS_HOTLINE/126267                       |  1 +
 library/Class/Onglet.php                      | 53 ++++++++---
 .../ZendAfi/View/Helper/Notice/Abstract.php   | 28 ++++--
 library/ZendAfi/View/Helper/Notice/Blocs.php  | 91 ++++++++++---------
 .../RechercheControllerViewnoticeTest.php     | 49 ++++++++++
 5 files changed, 157 insertions(+), 65 deletions(-)
 create mode 100644 VERSIONS_HOTLINE/126267

diff --git a/VERSIONS_HOTLINE/126267 b/VERSIONS_HOTLINE/126267
new file mode 100644
index 00000000000..d195c7a1d5c
--- /dev/null
+++ b/VERSIONS_HOTLINE/126267
@@ -0,0 +1 @@
+ - ticket #126267 : Vue notice : Correction du comportement des blocs dépliés dans le thème historique.
\ No newline at end of file
diff --git a/library/Class/Onglet.php b/library/Class/Onglet.php
index 27ab290e84f..c7f9da3a73a 100644
--- a/library/Class/Onglet.php
+++ b/library/Class/Onglet.php
@@ -22,21 +22,21 @@
 
 class Class_Onglet {
   use Trait_Singleton, Trait_Translator;
-
-  protected $libelle;
-  protected $function_name = 'alwaysDisplay';
-
-  /** Mode d'affichage 0=aucun 1=bloc déplié 2=bloc fermé 3=dans 1 onglet */
-  protected $display=0;
-
-  /** Largeur de l'onglet 0=répartition auto en pourcentage */
-  protected $largeur=0;
-
-  protected $order=0;
-
+  const
+    HIDDEN = 0,
+    OPEN = 1,
+    CLOSED = 2,
+    TAB = 3;
+
+  protected
+    $libelle,
+    $function_name = 'alwaysDisplay',
+    $display = 0,
+    $largeur = 0,
+    $order = 0;
 
   public static function forLibelleAndType($libelle, $type) {
-    return new self($libelle, $type);
+    return new static($libelle, $type);
   }
 
 
@@ -86,7 +86,7 @@ class Class_Onglet {
 
 
   public function callDisplayMethod($param) {
-    return ($this->{$this->function_name}($param));
+    return call_user_func([$this, $this->function_name], $param);
   }
 
 
@@ -149,4 +149,29 @@ class Class_Onglet {
     $this->order = $order;
     return $this;
   }
+
+
+  public function isBlock() {
+    return $this->isOpenBlock() || $this->isClosedBlock();
+  }
+
+
+  public function isOpenBlock() {
+    return static::OPEN == $this->display;
+  }
+
+
+  public function isClosedBlock() {
+    return static::CLOSED == $this->display;
+  }
+
+
+  public function isTab() {
+    return static::TAB == $this->display;
+  }
+
+
+  public function isHidden() {
+    return static::HIDDEN == $this->display;
+  }
 }
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/Notice/Abstract.php b/library/ZendAfi/View/Helper/Notice/Abstract.php
index b183a0d6c72..49ac6eee764 100644
--- a/library/ZendAfi/View/Helper/Notice/Abstract.php
+++ b/library/ZendAfi/View/Helper/Notice/Abstract.php
@@ -18,9 +18,7 @@
  * along with BOKEH; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
-abstract class ZendAfi_View_Helper_Notice_Abstract extends Zend_View_Helper_HtmlElement {
-  use Trait_Translator;
-
+abstract class ZendAfi_View_Helper_Notice_Abstract extends ZendAfi_View_Helper_BaseHelper {
   const BLOC_DEPLIE = 1;
   const BLOC_FERME = 2;
   const ONGLET = 3;
@@ -47,12 +45,15 @@ abstract class ZendAfi_View_Helper_Notice_Abstract extends Zend_View_Helper_Html
 
 
   public function selectOngletsFromPreferences($preferences, $aff_values, $notice) {
-    $onglets = [];
-
-    foreach($preferences['onglets'] as $nom => $config) {
-      if (!in_array((int)$config['aff'], $aff_values))
-        continue;
+    if (! $preferences = array_filter($preferences['onglets'],
+                                      function($pref) use($aff_values)
+                                      {
+                                        return in_array((int)$pref['aff'], $aff_values);
+                                      }))
+      return [];
 
+    $onglets = [];
+    foreach($preferences as $nom => $config) {
       $onglet = Class_Codification::getInstance()->getOnglet($nom);
       if ($config['titre'])
         $onglet->setLibelle($config['titre']);
@@ -64,11 +65,18 @@ abstract class ZendAfi_View_Helper_Notice_Abstract extends Zend_View_Helper_Html
     }
 
     uasort($onglets,
-           function($cfg_a, $cfg_b)
+           function($a, $b)
            {
-             return (int)$cfg_a->getOrder() - (int)$cfg_b->getOrder();
+             return (int)$a->getOrder() - (int)$b->getOrder();
            });
 
     return $onglets;
   }
+
+
+  protected function _selectBlocksFromPreferences($preferences, $record) {
+    return $this->selectOngletsFromPreferences($preferences,
+                                               [static::BLOC_DEPLIE, static::BLOC_FERME],
+                                               $record);
+  }
 }
diff --git a/library/ZendAfi/View/Helper/Notice/Blocs.php b/library/ZendAfi/View/Helper/Notice/Blocs.php
index e5936181eb6..7f9b76b4f7f 100644
--- a/library/ZendAfi/View/Helper/Notice/Blocs.php
+++ b/library/ZendAfi/View/Helper/Notice/Blocs.php
@@ -18,60 +18,69 @@
  * along with BOKEH; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
+
+
 class ZendAfi_View_Helper_Notice_Blocs extends ZendAfi_View_Helper_Notice_Abstract {
+  protected
+    $_record,
+    $_preferences;
+
   public function notice_Blocs($notice, $preferences) {
-    if (!array_isset('onglets', $preferences))
+    if (!array_isset('onglets', $preferences) || !$notice)
       return '';
 
-    $blocs = $this->getBlocsFromPreferences($preferences, $notice);
+    $this->_record = $notice;
+    $this->_preferences = $preferences;
 
-    return $this->renderBlocsForNotice($blocs, $notice);
+    return $this->_renderBlocsForNotice();
   }
 
 
-  public function getBlocsFromPreferences($preferences, $notice) {
-    return $this->selectOngletsFromPreferences($preferences,
-                                               [self::BLOC_DEPLIE, self::BLOC_FERME],
-                                               $notice);
-  }
-
-
-  public function renderBlocsForNotice($blocs, $notice) {
-    $id = $notice->getId();
-    $isbn = $notice->getIsbn();
-
+  protected function _renderBlocsForNotice() {
+    $id = $this->_record->getId();
     $html = '';
-
-    // Blocs
     $i = 0;
-    foreach($blocs as $bloc)  {
-      $type = $bloc->getType();
-      $id_bloc="bloc_".$id."_".$i++;
-      $js ='infos_bloc'.$this->getOnclick($type, $notice, $id_bloc);
-
-      if ((int)$bloc->getDisplayMode()==1)
-        Class_ScriptLoader::getInstance()
-          ->addJQueryReady('infos_bloc'. str_replace('this.id',
-                                                     '"'.$id_bloc.'"',
-                                                     $this->getOnclick($type, $notice, $id_bloc)));
-
-        Class_ScriptLoader::getInstance()
-        ->addJQueryReady('$("#'.$id_bloc.'").click(function(){'.$js.'})');
-
-      // Titre
-        $html.='<div  class="'.$type.' block_info_notice">';
-        $html.='<div id="'.$id_bloc.'" class="notice_bloc_titre"><img id="I'.$id_bloc.'" src="'.URL_IMG.'bouton/plus_carre.gif"  alt="Déplier"  /><h2>'.$bloc->getLibelle().'</h2></div>';
-        $html.='<div id="'.$id_bloc.'_contenu_row"></div>';
-        $html.=  '<div id="'.$id_bloc.'_contenu" class="notice_bloc">';
-        $html.=  '<div class="notice_patience" ><img src="'.URL_IMG.'patience.gif" alt="'.$this->_('Chargement en cours').'" />';
-        $html.=     $this->_translate->_('Veuillez patienter : lecture en cours...');
-        $html.=  '</div>';
-        $html.='</div>';
-        $html.='</div>';
+    foreach($this->_selectBlocksFromPreferences($this->_preferences, $this->_record)
+            as $bloc) {
+      $id_bloc = "bloc_" . $id . "_" . $i++;
+      $html .= $this->_renderBloc($bloc, $id_bloc);
     }
 
     return $html;
   }
 
+
+  protected function _renderBloc($bloc, $id_bloc) {
+    $type = $bloc->getType();
+    $js = 'infos_bloc' . $this->getOnclick($type, $this->_record, $id_bloc) . ';';
+
+    if ($bloc->isOpenBlock()) {
+      Class_ScriptLoader::getInstance()
+        ->addJQueryReady('$("#'.$id_bloc.'_contenu").hide();' // needed by toggling logic in infos_bloc
+                         . str_replace('this.id', '"'.$id_bloc.'"', $js));
+    }
+
+    Class_ScriptLoader::getInstance()
+      ->addJQueryReady('$("#'.$id_bloc.'").click(function(){' . $js .'});');
+
+    $profil = Class_Profil::getCurrentProfil();
+
+    return $this
+      ->_div(['class' => $type . ' block_info_notice'],
+             $this->_div(['id' => $id_bloc,
+                          'class' => 'notice_bloc_titre'],
+                         $this->view->tagImg($profil->getUrlImage('bouton/plus_carre.gif'),
+                                             ['id' => 'I'.$id_bloc,
+                                              'alt' => $this->_('Déplier')])
+                         . $this->_tag('h2', $bloc->getLibelle()))
+
+             . $this->_div(['id' => $id_bloc . '_contenu_row'], '')
+
+             . $this->_div(['id' => $id_bloc . '_contenu',
+                            'class' => 'notice_bloc' . ($bloc->isOpenBlock() ? ' notice_bloc_open' : '')],
+                           $this->_div(['class' => 'notice_patience'],
+                                       $this->view->tagImg($profil->getUrlImage('patience.gif'))
+                                       . $this->_('Veuillez patienter : lecture en cours...')))
+      );
+  }
 }
-?>
diff --git a/tests/application/modules/opac/controllers/RechercheControllerViewnoticeTest.php b/tests/application/modules/opac/controllers/RechercheControllerViewnoticeTest.php
index 77f94e0f842..f3f5ee0280a 100644
--- a/tests/application/modules/opac/controllers/RechercheControllerViewnoticeTest.php
+++ b/tests/application/modules/opac/controllers/RechercheControllerViewnoticeTest.php
@@ -250,6 +250,8 @@ class RechercheControllerViewnoticeVignetteFromUnimarcTest
 
 /** @see http://forge.afi-sa.fr/issues/125382 */
 class RechercheControllerViewnoticeTitleWithChapeauTest extends AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
   /** @test */
   public function h1ShouldContainsASpaceBetweenChapeauAndTitle() {
     $record = (new Class_NoticeUnimarc_Fluent)
@@ -271,4 +273,51 @@ class RechercheControllerViewnoticeTitleWithChapeauTest extends AbstractControll
     $this->assertXPathContentContains('//h1',
                                       'The promised Neverland n° 14 Retrouvailles inattendues');
   }
+}
+
+
+
+
+/** @see http://forge.afi-sa.fr/issues/126267 */
+class RechercheControllerViewnoticeOpenBlockTest extends AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
+  public function setUp() {
+    parent::setUp();
+
+    $record = (new Class_NoticeUnimarc_Fluent)
+      ->zoneWithContent('001', '25203')
+      ->zoneWithChildren('200', ['a' => 'Liseuse Vivlio Touch Lux 5'])
+      ;
+
+    $this->fixture(Class_Notice::class,
+                   ['id' => 12,
+                    'type_doc' => 11,
+                    'unimarc' => $record->render()
+                   ]);
+
+    Class_Profil::getCurrentProfil()
+      ->setModulePreference('recherche', 'viewnotice11', 'onglets',
+                            ['detail' => ['aff' => Class_Onglet::OPEN,
+                                          'ordre' => 1,
+                                          'titre' => 'Desc'],
+                             'exemplaires' => ['aff' => Class_Onglet::CLOSED,
+                                               'ordre' => 3,
+                                               'titre' => 'Items']]);
+
+    $this->dispatch('/recherche/viewnotice/id/12');
+  }
+
+
+  /** @test */
+  public function pageShouldContainsScriptHideThenToggleDescBlock() {
+    $this->assertXPathContentContains('//script',
+                                      '$("#bloc_12_0_contenu").hide();infos_bloc("bloc_12_0",');
+  }
+
+
+  /** @test */
+  public function pageShouldNotContainsScriptHideItemsBlock() {
+    $this->assertNotXPathContentContains('//script', '$("#bloc_12_2_contenu").hide()');
+  }
 }
\ No newline at end of file
-- 
GitLab