From 4e411e726bcde03223fe3b8d1cc3fdb4e8ed8c71 Mon Sep 17 00:00:00 2001
From: Laurent Laffont <llaffont@afi-sa.fr>
Date: Tue, 16 Jul 2019 10:30:42 +0200
Subject: [PATCH] Add authors widget

---
 FEATURES/95222                                |  10 +
 VERSIONS_WIP/95222                            |   1 +
 .../admin/controllers/AjaxController.php      |   3 +-
 .../admin/controllers/WidgetController.php    |  17 +
 cosmogramme/sql/patch/patch_376.php           |   6 +
 library/Class/Auteur.php                      |  62 ---
 library/Class/CodifAuteur.php                 |  29 +-
 library/Class/CodifAuteur/Description.php     |  63 +--
 library/Class/CodifAuteurFonction.php         |  25 +-
 library/Class/Notice.php                      |  23 +-
 library/Class/Notice/Facette.php              |  18 +
 library/Class/Systeme/ModulesAccueil.php      |   3 +-
 .../Class/Systeme/ModulesAccueil/Authors.php  |  57 ++
 .../Form/Configuration/Widget/Authors.php     |  80 +++
 .../ZendAfi/View/Helper/Accueil/Authors.php   | 203 +++++++
 library/ZendAfi/View/Helper/Accueil/Base.php  |   5 +
 .../ZendAfi/View/Helper/Accueil/Kiosque.php   |  22 +-
 .../View/Helper/Admin/TagListeSuggestion.php  |   1 +
 .../View/Helper/RenderAuthorMetadata.php      |  16 +-
 public/opac/css/global.css                    |   7 +-
 public/opac/js/widget_templates/authors.jpg   | Bin 0 -> 32175 bytes
 .../js/widget_templates/widget_templates.json |   9 +-
 tests/db/UpgradeDBTest.php                    |  18 +-
 tests/scenarios/AuthorPage/AuthorPageTest.php |  13 +-
 .../scenarios/AuthorPage/AuthorWidgetTest.php | 501 ++++++++++++++++++
 tests/scenarios/AuthorPage/notre_dame.marc    |   1 +
 26 files changed, 1053 insertions(+), 140 deletions(-)
 create mode 100644 FEATURES/95222
 create mode 100644 VERSIONS_WIP/95222
 create mode 100644 cosmogramme/sql/patch/patch_376.php
 delete mode 100644 library/Class/Auteur.php
 create mode 100644 library/Class/Systeme/ModulesAccueil/Authors.php
 create mode 100644 library/ZendAfi/Form/Configuration/Widget/Authors.php
 create mode 100644 library/ZendAfi/View/Helper/Accueil/Authors.php
 create mode 100644 public/opac/js/widget_templates/authors.jpg
 create mode 100644 tests/scenarios/AuthorPage/AuthorWidgetTest.php
 create mode 100644 tests/scenarios/AuthorPage/notre_dame.marc

diff --git a/FEATURES/95222 b/FEATURES/95222
new file mode 100644
index 00000000000..fb0b6c9913f
--- /dev/null
+++ b/FEATURES/95222
@@ -0,0 +1,10 @@
+        '95222' =>
+            ['Label' => $this->_('Boite Auteurs'),
+             'Desc' => $this->_('Permet d\'afficher dynamiquement des auteurs à partir d\'une sélection de notices (domaines, paniers)'),
+             'Image' => '',
+             'Video' => 'https://www.youtube.com/watch?v=aK4Dz3LVOIo',
+             'Category' => 'Recherche',
+             'Right' => function($feature_description, $user) {return true;},
+             'Wiki' => 'http://wiki.bokeh-library-portal.org/index.php?title=Boite_auteurs',
+             'Test' => '',
+             'Date' => '2019-07-18'],
\ No newline at end of file
diff --git a/VERSIONS_WIP/95222 b/VERSIONS_WIP/95222
new file mode 100644
index 00000000000..8cd4aaec3ba
--- /dev/null
+++ b/VERSIONS_WIP/95222
@@ -0,0 +1 @@
+ - ticket #95222 : Ajout de la boite Auteurs
\ No newline at end of file
diff --git a/application/modules/admin/controllers/AjaxController.php b/application/modules/admin/controllers/AjaxController.php
index 983c3ff7a9e..ce63c3a2215 100644
--- a/application/modules/admin/controllers/AjaxController.php
+++ b/application/modules/admin/controllers/AjaxController.php
@@ -53,7 +53,8 @@ class Admin_AjaxController extends ZendAfi_Controller_Action {
 
 
   protected function getAuthorityFor($code) {
-    $authorities = ['auteur' => new Class_Auteur(),
+    $authorities = ['auteur' => new Class_CodifAuteur(),
+                    'responsibility' => new Class_CodifAuteurFonction(),
                     'matiere' => new Class_Matiere(),
                     'interet' => new Class_CodifCentreInteret(),
                     'dewey' => new Class_CodifDewey(),
diff --git a/application/modules/admin/controllers/WidgetController.php b/application/modules/admin/controllers/WidgetController.php
index 5ca52152035..55058fe4d15 100644
--- a/application/modules/admin/controllers/WidgetController.php
+++ b/application/modules/admin/controllers/WidgetController.php
@@ -305,4 +305,21 @@ class Admin_WidgetController extends ZendAfi_Controller_Action {
   public function formProvider($widget) {
     return call_user_func_array([$widget->getForm(), 'newWith'], [$widget->forForm()]);
   }
+
+
+  public function widgetActionAction() {
+    $id_module = $this->_getParam('id_module');
+
+    if (Class_Profil::getCurrentProfil()->getId() !== (int)$this->_getParam('id_profil'))
+      throw new Zend_Controller_Action_Exception($this->view->_('Profil inexistant'), 404);
+
+    if (!$config = Class_Profil::getCurrentProfil()->getLocalModuleAccueilConfig($id_module))
+      throw new Zend_Controller_Action_Exception($this->view->_('Boite inexistante'), 404);
+
+    $helper = ZendAfi_View_Helper_Accueil_Base::getModuleHelperFromParams($id_module,
+                                                                          $config,
+                                                                          $this->view);
+    $helper->performAction($this->_getParam('named'));
+    $this->_redirectToReferer();
+  }
 }
\ No newline at end of file
diff --git a/cosmogramme/sql/patch/patch_376.php b/cosmogramme/sql/patch/patch_376.php
new file mode 100644
index 00000000000..823c2cd028a
--- /dev/null
+++ b/cosmogramme/sql/patch/patch_376.php
@@ -0,0 +1,6 @@
+<?php
+$adapter = Zend_Db_Table_Abstract::getDefaultAdapter();
+try {
+  $adapter->query('alter table codif_auteur add column thumbnail_url varchar(255)');
+
+} catch(Exception $e) {}
diff --git a/library/Class/Auteur.php b/library/Class/Auteur.php
deleted file mode 100644
index 4cc4bc90f94..00000000000
--- a/library/Class/Auteur.php
+++ /dev/null
@@ -1,62 +0,0 @@
-<?PHP
-/**
- * Copyright (c) 2012, 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 
- */
-////////////////////////////////////////////////////////////////////////////////////////
-// OPAC 3 :AUTEURS
-///////////////////////////////////////////////////////////////////////////////////////
-
-class Class_Auteur
-{
-
-// ----------------------------------------------------------------
-// Rend une liste pour un champ suggestion
-// ----------------------------------------------------------------
-  public function getListeSuggestion($recherche,$mode,$limite_resultat)
-  {
-    // Lancer la recherche
-    $ix=new Class_Indexation();
-    $code_alpha=$ix->alphaMaj($recherche);
-    $code_alpha=str_replace(" ","x",$code_alpha);
-    if($mode=="1") $req="select id_auteur,libelle from codif_auteur where formes like'".$code_alpha."%' order by FORMES limit ".$limite_resultat;
-  
-    $resultat=fetchAll($req);
-    
-    // Mettre l'indice et le libelle
-    if(!$resultat) return false;
-    foreach($resultat as $enreg)
-    {
-      $liste[]=array($enreg["id_auteur"],$enreg["libelle"]);
-    }
-    
-    return $liste;
-  } 
-
-
-// ----------------------------------------------------------------
-// Rend prénom et nom
-// ----------------------------------------------------------------
-  static function getLibelle($id_auteur)
-  {
-    $libelle = fetchEnreg("select libelle from codif_auteur where id_auteur='$id_auteur'");
-    return $libelle;
-  }
-}
-
-?>
\ No newline at end of file
diff --git a/library/Class/CodifAuteur.php b/library/Class/CodifAuteur.php
index cf45e5818da..1ae9b079875 100644
--- a/library/Class/CodifAuteur.php
+++ b/library/Class/CodifAuteur.php
@@ -122,9 +122,36 @@ class Class_CodifAuteur extends Storm_Model_Abstract {
                                   'wikidata_id' => '',
                                   'youtube_channel_id' => '',
                                   'isni' => '',
-                                  'ark' => ''];
+                                  'ark' => '',
+                                  'thumbnail_url' => ''];
 
   public function getCategorie() {
     return;
   }
+
+
+  public function getListeSuggestion($recherche, $mode, $limite_resultat)  {
+    $code_alpha = str_replace(' ',
+                              'x',
+                              Class_Indexation::getInstance()->alphaMaj($recherche));
+
+    $authors = Class_CodifAuteur::getLoader()
+      ->findAllBy(['where' => 'formes like "' . $code_alpha . '%"',
+                   'order' => 'FORMES',
+                   'limit' => $limite_resultat]);
+
+    return array_map(function($author)
+                     {
+                       return [$author->getId(), $author->getLibelle()];
+                     },
+                     $authors);
+  }
+
+
+  public function isThumbnailValid() {
+    return
+      (!empty($this->getThumbnailUrl()))
+      &&
+      (false == strpos($this->getThumbnailUrl(), 'Defaut.svg'));
+  }
 }
\ No newline at end of file
diff --git a/library/Class/CodifAuteur/Description.php b/library/Class/CodifAuteur/Description.php
index 1b72d9dbc1e..a916cf8659b 100644
--- a/library/Class/CodifAuteur/Description.php
+++ b/library/Class/CodifAuteur/Description.php
@@ -106,19 +106,9 @@ class Class_CodifAuteur_Description {
     if (!count($this->getRecords()))
       return '';
 
-    $data = $this->_fetchBiography($this->_author,
-                                   $this->getRecords(),
-                                   $this->getAssociatedAuthors());
-
-    $author_attribs = array_intersect_key($data, ['wikidata_id' => '',
-                                                  'youtube_channel_id' => '',
-                                                  'ark' => '',
-                                                  'isni' => '']);
-    $this->_author
-      ->updateAttributes($author_attribs)
-      ->save();
+    $data = $this->fetchBiography();
 
-    if ($biography = $data['biographie']) {
+    if ($biography = $data->getbiographie()) {
       $biography = $this->_enrichBiographyWithRecords($biography,
                                                       $this->getRecords(),
                                                       $view);
@@ -129,17 +119,19 @@ class Class_CodifAuteur_Description {
     }
 
     $thumbnail = '';
-    if ($data['vignette'])
+    if ($this->_author->getThumbnailUrl())
       $thumbnail = $view->tag('img',
                               null,
-                              ['src' => $data['vignette'],
+                              ['src' => $this->_author->getThumbnailUrl(),
                                'alt' => $this->getLabel() . '. ' . $this->_('Source: Wikipedia')]);
 
 
     $update_button = $view->biographie_UpdateButton($this->getRecords()[0],
                                                     $this->getLabel());
 
-    $licence = $view->biographie_Licence($this->getLabel(), $data['source'], $data['url_source']);
+    $licence = $view->biographie_Licence($this->getLabel(),
+                                         $data->getsource(),
+                                         $data->geturl_source());
 
     return $update_button . $thumbnail . $biography . $licence;
   }
@@ -222,9 +214,23 @@ class Class_CodifAuteur_Description {
 
 
   public function fetchBiography() {
-    return new Class_Entity($this->_fetchBiography($this->_author,
-                                                   $this->getRecords(),
-                                                   $this->getAssociatedAuthors()));
+    $bio =  new Class_Entity($this->_fetchBiography($this->_author,
+                                                    $this->getRecords(),
+                                                    $this->getAssociatedAuthors()));
+
+    $author_attribs = array_intersect_key($bio->toArray(),
+                                          ['wikidata_id' => '',
+                                           'youtube_channel_id' => '',
+                                           'ark' => '',
+                                           'isni' => '']);
+    if ($bio->getvignette())
+      $author_attribs['thumbnail_url'] = $bio->getvignette();
+
+    $this->_author
+      ->updateAttributes($author_attribs)
+      ->save();
+
+    return $bio;
   }
 
 
@@ -309,30 +315,19 @@ class Class_CodifAuteur_Description {
 
 
   public function renderThumbnailOn($view) {
-    $data = new Class_Entity($this->_fetchBiography($this->_author,
-                                                    $this->getRecords(),
-                                                    $this->getAssociatedAuthors()));
-    return $data->getvignette()
+    $this->fetchBiography();
+
+    return $this->_author->getThumbnailUrl()
       ? $view->tag('img',
                    null,
-                   ['src' => $data->getvignette(),
+                   ['src' => $this->_author->getThumbnailUrl(),
                     'alt' => $this->getLabel() . '. ' . $this->_('Source: Wikipedia')])
       : '';
   }
 
 
   public function renderWikipediaOn($view) {
-    $data = new Class_Entity($this->_fetchBiography($this->_author,
-                                                    $this->getRecords(),
-                                                    $this->getAssociatedAuthors()));
-
-    $author_attribs = array_intersect_key($data->toArray(), ['wikidata_id' => '',
-                                                             'youtube_channel_id' => '',
-                                                             'ark' => '',
-                                                             'isni' => '']);
-    $this->_author
-      ->updateAttributes($author_attribs)
-      ->save();
+    $data = $this->fetchBiography();
 
     if (!$biography = $data->getbiographie())
       return '';
diff --git a/library/Class/CodifAuteurFonction.php b/library/Class/CodifAuteurFonction.php
index 4ae6196f045..465bdcda6a6 100644
--- a/library/Class/CodifAuteurFonction.php
+++ b/library/Class/CodifAuteurFonction.php
@@ -16,7 +16,7 @@
  *
  * 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 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
 class Class_CodifAuteurFonctionLoader extends Storm_Model_Loader {
@@ -24,12 +24,29 @@ class Class_CodifAuteurFonctionLoader extends Storm_Model_Loader {
     return array_map(function ($model) {return $model->getLibelle();},
                      Class_CodifAuteurFonction::findAllBy(['order' => 'libelle']));
   }
+
 }
 
+
+
 class Class_CodifAuteurFonction extends Storm_Model_Abstract {
-  protected $_table_name = 'codif_auteurs_fonctions';
-  protected $_table_primary = 'id_fonction';
-  protected $_loader_class = 'Class_CodifAuteurFonctionLoader';
+  protected
+    $_table_name = 'codif_auteurs_fonctions',
+    $_table_primary = 'id_fonction',
+    $_loader_class = 'Class_CodifAuteurFonctionLoader';
+
+
+  public function getListeSuggestion($recherche, $mode, $limite_resultat) {
+    $responsibilities = Class_CodifAuteurFonction::getLoader()
+      ->findAllBy(['where' => 'libelle like "' . $recherche .'%"',
+                   'order' => 'libelle']);
+
+    return array_map(function($responsibility)
+                     {
+                       return [$responsibility->getId(), $responsibility->getLibelle()];
+                     },
+                     $responsibilities);
+  }
 }
 
 ?>
\ No newline at end of file
diff --git a/library/Class/Notice.php b/library/Class/Notice.php
index a4ed9fa41db..e2383cb9266 100644
--- a/library/Class/Notice.php
+++ b/library/Class/Notice.php
@@ -1029,12 +1029,14 @@ class Class_Notice extends Storm_Model_Abstract {
     return $this->_auteur_principal;
   }
 
+
   public function getFirstAuthor() {
     if (!$auteurs = $this->getAuteursUnimarc(true))
       return '';
     return $auteurs[0];
   }
 
+
   public function setAuteurPrincipal($auteur) {
     $this->_auteur_principal = $auteur;
     return $this;
@@ -1047,7 +1049,6 @@ class Class_Notice extends Storm_Model_Abstract {
 
 
   public function getAuteursUnimarc($auteurPrincipal = false, $getFonction = false) {
-
     $indexation = Class_Indexation::getInstance();
     $auteurs = [];
     $zones = ['700', '710', '720', '730', '701', '702', '711', '712', '721', '722'];
@@ -1226,7 +1227,9 @@ class Class_Notice extends Storm_Model_Abstract {
       return [];
 
     $label = trim($prenom . ' ' . $nom) . (($fonction) ? ' (' . $fonction . ')': '');
-    return (new Class_Notice_FieldAuthor($codif_auteur))->setLabel($label);
+    return (new Class_Notice_FieldAuthor($codif_auteur))
+      ->setLabel($label)
+      ->setFonction($fonction);
   }
 
 
@@ -1628,21 +1631,7 @@ class Class_Notice extends Storm_Model_Abstract {
 
 
   public function getAvailableLibrariesFromFacet() {
-    $existing = array_filter(
-                             Class_Notice_Facette::parseFacettesFromNoticeField($this->getFacettes()),
-                             function($facet) {
-                               return $facet->isAvailability();
-                             });
-
-    $values = array_unique(
-                           array_filter(
-                                        array_map(function($facet)
-                                                  {
-                                                    return $facet->getValue();
-                                                  },
-                                                  $existing)));
-
-    if(!$values)
+    if (!$values = Class_Notice_Facette::facetsValuesFromRecordFilteredBy($this, 'isAvailability'))
       return [];
 
     return Class_Bib::findAllBy(['id_site' => $values]);
diff --git a/library/Class/Notice/Facette.php b/library/Class/Notice/Facette.php
index 7935c67195d..ab1a48e33d3 100644
--- a/library/Class/Notice/Facette.php
+++ b/library/Class/Notice/Facette.php
@@ -37,6 +37,24 @@ class Class_Notice_Facette {
   }
 
 
+  public static function facetsValuesFromRecordFilteredBy($record, $filter_name) {
+    $existing = array_filter(
+                             Class_Notice_Facette::parseFacettesFromNoticeField($record->getFacettes()),
+                             function($facet) use ($filter_name){
+                               return call_user_func([$facet, $filter_name]);
+                             });
+
+    $values = array_unique(
+                           array_filter(
+                                        array_map(function($facet)
+                                                  {
+                                                    return $facet->getValue();
+                                                  },
+                                                  $existing)));
+    return $values;
+  }
+
+
   public static function extractCodeRubrique($cle) {
     return (Class_CodifThesaurus::CODE_FACETTE == ($code = $cle[0]))
       ? Class_CodifThesaurus::getLoader()->getFacetGroup($cle)
diff --git a/library/Class/Systeme/ModulesAccueil.php b/library/Class/Systeme/ModulesAccueil.php
index f710a0d5baf..9f09d4e6630 100644
--- a/library/Class/Systeme/ModulesAccueil.php
+++ b/library/Class/Systeme/ModulesAccueil.php
@@ -136,7 +136,8 @@ class Class_Systeme_ModulesAccueil extends Class_Systeme_ModulesAbstract {
                  'Panier',
                  'DomainBrowser',
                  'PremierChapitre',
-                 'Library'];
+                 'Library',
+                 'Authors'];
 
     foreach($defaults as $default) {
       $name = 'Class_Systeme_ModulesAccueil_' . $default;
diff --git a/library/Class/Systeme/ModulesAccueil/Authors.php b/library/Class/Systeme/ModulesAccueil/Authors.php
new file mode 100644
index 00000000000..8d8742866b4
--- /dev/null
+++ b/library/Class/Systeme/ModulesAccueil/Authors.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Copyright (c) 2012, 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_Systeme_ModulesAccueil_Authors extends Class_Systeme_ModulesAccueil_Null {
+  const
+    CODE = 'AUTHORS',
+    AUTHORS_SELECTION_MODE_ALL = 'all',
+    AUTHORS_SELECTION_MODE_RESPONSIBILITIES = 'responsibilities',
+    AUTHORS_SELECTION_MODE_MAIN = 'main';
+
+
+  protected
+    $_group = Class_Systeme_ModulesAccueil::GROUP_RECH,
+    $_isPhone = true;
+
+
+  public function __construct() {
+    $this->_libelle = $this->_('Boite auteurs');
+    $this->_form = 'ZendAfi_Form_Configuration_Widget_Authors';
+    $this->_defaultValues = ['titre' => $this->_('Sélection d\'auteurs'),
+                             'op_largeur_img' => 260,
+                             'authors_count' => 10,
+                             'authors_selection_mode' => static::AUTHORS_SELECTION_MODE_ALL];
+  }
+
+
+  public function getAuthorsSelectionModeOptions() {
+    return [
+            static::AUTHORS_SELECTION_MODE_ALL => $this->_('Tous les auteurs'),
+            static::AUTHORS_SELECTION_MODE_MAIN => $this->_('Auteurs principaux'),
+            static::AUTHORS_SELECTION_MODE_RESPONSIBILITIES => $this->_('Par responsabilité')
+    ];
+  }
+
+
+  public function getDefaultAuthorsSelectionMode() {
+    return $this->_defaultValues['authors_selection_mode'];
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/Form/Configuration/Widget/Authors.php b/library/ZendAfi/Form/Configuration/Widget/Authors.php
new file mode 100644
index 00000000000..f664f2ce4ef
--- /dev/null
+++ b/library/ZendAfi/Form/Configuration/Widget/Authors.php
@@ -0,0 +1,80 @@
+<?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_Form_Configuration_Widget_Authors extends ZendAfi_Form_Configuration_Widget_Base {
+  public function init() {
+    parent::init();
+
+    Class_ScriptLoader::getInstance()
+      ->addJQueryReady('radioToggleVisibilityForElement("input[name=\'authors_selection_mode\']",
+                                                        $("#responsibilities").closest("tr"),
+                                                        ["responsibilities"]);');
+
+    $authors_module = new Class_Systeme_ModulesAccueil_Authors();
+
+    $this
+    ->addElement('domainePanier',
+                 'data_source')
+    ->addElement('number',
+                 'authors_count',
+                 ['label' => $this->_('Nombre maximum d\'auteurs'),
+                  'min' => 1,
+                  'max' => 200])
+    ->addElement('slider',
+                 'op_largeur_img',
+                 ['label' => $this->_('Largeur des colonnes'),
+                  'min' => 100,
+                  'max' => 2000,
+                  'step' => 1])
+    ->addElement('radio',
+                 'authors_selection_mode',
+                 ['label' => $this->_('Auteurs sélectionnés'),
+                  'multiOptions' => $authors_module->getAuthorsSelectionModeOptions(),
+                  'value' => $authors_module->getDefaultAuthorsSelectionMode()])
+    ->addElement('listeSuggestion',
+                 'responsibilities',
+                 ['label' => $this->_('Responsabilité auteur'),
+                  'rubrique' => 'responsibility'])
+
+    ->addToSelectionGroup(['data_source'])
+
+    ->addToDisplaySettingsGroup(['authors_selection_mode',
+                                 'responsibilities',
+                                 'authors_count'])
+
+    ->addToStyleGroup(['op_largeur_img']);
+  }
+
+
+   public function populate(array $datas) {
+    $this->customPopulate($datas);
+    return parent::populate($datas);
+  }
+
+
+  public function customPopulate($datas) {
+    $this
+      ->getElement('data_source')
+      ->setOptions(['IdItems' => isset($datas['id_panier']) ? $datas['id_panier'] : '',
+                    'IdCategories' => isset($datas['id_catalogue']) ? $datas['id_catalogue'] : '']);
+    return $this;
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/Accueil/Authors.php b/library/ZendAfi/View/Helper/Accueil/Authors.php
new file mode 100644
index 00000000000..4a5fb2e0b6d
--- /dev/null
+++ b/library/ZendAfi/View/Helper/Accueil/Authors.php
@@ -0,0 +1,203 @@
+<?php
+/**
+ * Copyright (c) 2012, 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_View_Helper_Accueil_Authors extends ZendAfi_View_Helper_Accueil_Base {
+  public function getHTML() {
+    $this->titre = $this->preferences['titre'];
+    $this->contenu = $this->_renderContent();
+
+    return $this->getHtmlArray();
+  }
+
+
+  public function performAction($action) {
+    if ($action === 'refresh')
+      $this->refreshAuthorsWithoutThumbnail();
+  }
+
+
+  public function refreshAuthorsWithoutThumbnail() {
+    $authors = array_filter($this->_findAuthorsFromPreferences(),
+                            function($author)
+                            {
+                              return !$author->isThumbnailValid();
+                            });
+    array_map(function($author)
+              {
+                (new Class_CodifAuteur_Description($author))->fetchBiography();
+              },
+              $authors);
+    return $this;
+  }
+
+
+  protected function _extendedActions() {
+    if (!Class_Users::isCurrentUserCanAccesBackend())
+      return null;
+
+    return [
+            function()
+            {
+              return $this->view->tagAnchor($this->view->url(['module' => 'admin',
+                                                              'controller' => 'widget',
+                                                              'action' => 'widget-action',
+                                                              'named' => 'refresh',
+                                                              'id_module' => $this->id_module,
+                                                              'id_profil' => Class_Profil::getCurrentProfil()->getId()]),
+                                            Class_Admin_Skin::current()
+                                            ->renderActionIconOn('images',
+                                                                 $this->view),
+                                            [
+                                             'title' => $this->view->_('Recharger les vignettes de la boite: %s',
+                                                                       htmlspecialchars($this->preferences['titre']))
+                                            ]);
+            }
+    ];
+  }
+
+
+  protected function _findAuthorsFromPreferences() {
+    $records = Class_Notice::getNoticesFromPreferences($this->preferences);
+    return $this->_getAuthorsFromRecords($records);
+  }
+
+
+  protected function _renderContent() {
+    $authors = array_filter($this->_findAuthorsFromPreferences(),
+                            function($author)
+                            {
+                              return $author->isThumbnailValid();
+                            });
+
+    return $this->_tag('div',
+                       implode('', array_map([$this, '_renderAuthor'],
+                                             $authors)),
+                       ['class' => 'authors_wall',
+                        'style' => 'column-width:' . $this->preferences['op_largeur_img'] . 'px']);
+  }
+
+
+  protected function _getAuthorsFromRecords($records) {
+    $authors_ids = $this->_getAuthorsIdsFromRecords($records);
+
+    return $authors_ids
+      ? Class_CodifAuteur::findAllBy(['id_auteur' => array_slice($authors_ids,
+                                                                 0,
+                                                                 $this->preferences['authors_count'])])
+      : [];
+  }
+
+
+  protected function _getAuthorsIdsFromRecords($records) {
+    if ($this->preferences['authors_selection_mode'] === Class_Systeme_ModulesAccueil_Authors::AUTHORS_SELECTION_MODE_MAIN)
+      return $this->_getMainAuthorsFromRecords($records);
+
+    if ($this->preferences['authors_selection_mode'] === Class_Systeme_ModulesAccueil_Authors::AUTHORS_SELECTION_MODE_RESPONSIBILITIES) {
+      return  $this->_getAuthorsByResponsibilitiesFromRecords($records);
+    }
+
+    return  $this->_getAllAuthorsFromRecords($records);
+  }
+
+
+  protected function _getAuthorsByResponsibilitiesFromRecords($records) {
+    $responsibilities_labels = $this->_getResponsibilitiesPreferenceLabels();
+
+    $authors_ids = [];
+    foreach($records as $record) {
+      $authors_ids = array_merge($authors_ids,
+                                 $this->_getAuthorsByResponsibilities($record,
+                                                                      $responsibilities_labels));
+    }
+
+    return array_filter(array_unique($authors_ids));
+  }
+
+
+  protected function _getResponsibilitiesPreferenceLabels() {
+    $responsibilities_ids = array_filter(explode(';',
+                                                 $this->preferences['responsibilities']));
+    return array_filter(
+                        array_map(function($responsibility)
+                                  {
+                                    return $responsibility->getLibelle();
+                                  },
+                                  $responsibilities_ids
+                                  ? Class_CodifAuteurFonction::findAllBy(['id_fonction' => $responsibilities_ids])
+                                  : []));
+  }
+
+
+  protected function _getAuthorsByResponsibilities($record, $responsibilities_labels) {
+    $authors = array_filter($record->getAuteursUnimarc(false, true),
+                            function($author) use ($responsibilities_labels)
+                            {
+
+                              return in_array($author->getFonction(), $responsibilities_labels);
+                            });
+
+    return array_map(function($author)
+                     {
+                       return $author->getId();
+                     },
+                     $authors);
+  }
+
+
+  protected function _getMainAuthorsFromRecords($records) {
+    $authors_ids = array_map(function($record)
+                             {
+                               return current(Class_Notice_Facette::facetsValuesFromRecordFilteredBy($record, 'isAuthor'));
+                             },
+                             $records);
+
+    return array_filter(array_unique($authors_ids));
+  }
+
+
+  protected function _getAllAuthorsFromRecords($records) {
+    $authors_ids = [];
+    foreach($records as $record) {
+      $authors_ids = array_merge($authors_ids,
+                                 Class_Notice_Facette::facetsValuesFromRecordFilteredBy($record, 'isAuthor'));
+    }
+
+    return array_filter(array_unique($authors_ids));
+  }
+
+
+  protected function _renderAuthor($author) {
+    return $this->_tag('div',
+                       $this->_tag('a',
+                                   $this->_tag('img',
+                                               null,
+                                               ['src' => $author->getThumbnailUrl(),
+                                                'width' => $this->preferences['op_largeur_img'],
+                                                'alt' => $author->getLibelle() . '. ' . $this->_('Source: Wikipedia')]),
+                                   ['href' => $this->view->url(['controller' => 'author',
+                                                                'action' => 'view',
+                                                                'id' => $author->getId()]),
+                                    'title' => $this->_('En savoir plus sur %s', $author->getLibelle())]),
+                       ['class' => 'author']);
+  }
+}
+
+?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/Accueil/Base.php b/library/ZendAfi/View/Helper/Accueil/Base.php
index 26a27cf4dbe..8d8c9e30d96 100644
--- a/library/ZendAfi/View/Helper/Accueil/Base.php
+++ b/library/ZendAfi/View/Helper/Accueil/Base.php
@@ -74,6 +74,11 @@ class ZendAfi_View_Helper_Accueil_Base extends ZendAfi_View_Helper_ModuleAbstrac
   }
 
 
+  public function performAction($action) {
+    //@see Admin_WidgetController::widgetActionAction()
+  }
+
+
   public function setIdMenu($id_menu) {
     $this->_id_menu = $id_menu;
     return $this;
diff --git a/library/ZendAfi/View/Helper/Accueil/Kiosque.php b/library/ZendAfi/View/Helper/Accueil/Kiosque.php
index db4fe904268..802d8d8c5ff 100644
--- a/library/ZendAfi/View/Helper/Accueil/Kiosque.php
+++ b/library/ZendAfi/View/Helper/Accueil/Kiosque.php
@@ -89,13 +89,13 @@ class ZendAfi_View_Helper_Accueil_Kiosque extends ZendAfi_View_Helper_Accueil_Ba
       return '';
 
     return  $this->view->tagAnchor($this->view->url(['module' => 'admin',
-                                                           'controller' => 'catalogue',
-                                                           'action' => 'edit',
-                                                           'id_catalogue' => $this->preferences['id_catalogue']]),
-                                         Class_Admin_Skin::current()
-                                         ->renderActionIconOn('edit', $this->view,
-                                                              ['title' => $this->view->_('Modifier le domaine : %s', htmlspecialchars($catalogue->getLibelle()))]),
-                                         ['data-popup' => 'true']);
+                                                     'controller' => 'catalogue',
+                                                     'action' => 'edit',
+                                                     'id_catalogue' => $this->preferences['id_catalogue']]),
+                                   Class_Admin_Skin::current()
+                                   ->renderActionIconOn('edit', $this->view,
+                                                        ['title' => $this->view->_('Modifier le domaine : %s', htmlspecialchars($catalogue->getLibelle()))]),
+                                   ['data-popup' => 'true']);
 
   }
 
@@ -108,10 +108,10 @@ class ZendAfi_View_Helper_Accueil_Kiosque extends ZendAfi_View_Helper_Accueil_Ba
       return null;
 
     return $this->view->tagAnchor($this->view->url(['module' => 'admin',
-                                                         'controller' => 'catalogue',
-                                                         'action' => 'add',
-                                                         'id_catalogue' => $domaine_parent->getId(),
-                                                         'id_module' => $this->id_module]),
+                                                    'controller' => 'catalogue',
+                                                    'action' => 'add',
+                                                    'id_catalogue' => $domaine_parent->getId(),
+                                                    'id_module' => $this->id_module]),
                                        Class_Admin_Skin::current()
                                          ->renderActionIconOn('add', $this->view, ['title' => $this->view->_('Afficher un nouveau domaine')]),
                                        ['data-popup' => 'true']);
diff --git a/library/ZendAfi/View/Helper/Admin/TagListeSuggestion.php b/library/ZendAfi/View/Helper/Admin/TagListeSuggestion.php
index 670babfa5c7..c506440f4c3 100644
--- a/library/ZendAfi/View/Helper/Admin/TagListeSuggestion.php
+++ b/library/ZendAfi/View/Helper/Admin/TagListeSuggestion.php
@@ -149,6 +149,7 @@ class ZendAfi_View_Helper_Admin_TagListeSuggestion
 
     $map = [
             'auteur'    => ['Class_CodifAuteur', [1 => $this->_('commence par')]],
+            'responsibility' => ['Class_CodifAuteurFonction', [1 => $this->_('commence par')]],
             'matiere'   => ['Class_CodifMatiere'],
             'interet'   => ['Class_CodifCentreInteret'],
             'dewey'     => ['Class_CodifDewey', $dewey_pcdm4_options],
diff --git a/library/ZendAfi/View/Helper/RenderAuthorMetadata.php b/library/ZendAfi/View/Helper/RenderAuthorMetadata.php
index 7dc65e4e8c9..70703e887dc 100644
--- a/library/ZendAfi/View/Helper/RenderAuthorMetadata.php
+++ b/library/ZendAfi/View/Helper/RenderAuthorMetadata.php
@@ -28,17 +28,27 @@ class ZendAfi_View_Helper_renderAuthorMetadata extends ZendAfi_View_Helper_BaseH
     if ($id = $attributes['ark'])
       $attributes['ark'] = $this->_tag('a',
                                        $id,
-                                       ['href' => 'https://data.bnf.fr/fr/atelier/' . $id]);
+                                       ['href' => 'https://data.bnf.fr/' . $id,
+                                        'target' => '_blank']);
 
     if ($id = $attributes['wikidata_id'])
       $attributes['wikidata_id'] = $this->_tag('a',
                                                $id,
-                                               ['href' => 'https://www.wikidata.org/wiki/' . $id]);
+                                               ['href' => 'https://www.wikidata.org/wiki/' . $id,
+                                                'target' => '_blank']);
 
     if ($id = $attributes['youtube_channel_id'])
       $attributes['youtube_channel_id'] = $this->_tag('a',
                                                       $id,
-                                                      ['href' => Class_WebService_Youtube::CHANNEL_URL . $id]);
+                                                      ['href' => Class_WebService_Youtube::CHANNEL_URL . $id,
+                                                       'target' => '_blank']);
+
+
+    if ($thumbnail_url = $attributes['thumbnail_url'])
+      $attributes['thumbnail_url'] = $this->_tag('a',
+                                                 $thumbnail_url,
+                                                 ['href' => $thumbnail_url,
+                                                  'target' => '_blank']);
 
     return
       $this->_tag('h2', $this->_('Auteur : %s',
diff --git a/public/opac/css/global.css b/public/opac/css/global.css
index 0175dae05a3..190e01a0128 100644
--- a/public/opac/css/global.css
+++ b/public/opac/css/global.css
@@ -3718,18 +3718,21 @@ a[href*="bookmarked-searches/notify"] img {
     overflow: hidden;
 }
 
+
 .simple_wall > a > img {
     width: 100%;
 }
 
 .simple_wall > a > img,
-.simple_wall > div {
+.simple_wall > div,
+.authors_wall div {
     transition: opacity 0.3s;
 }
 
 
 .simple_wall:hover > a:not(:hover),
-.simple_wall:hover > div:not(:hover) {
+.simple_wall:hover > div:not(:hover),
+.authors_wall:hover div:not(:hover){
     opacity: 0.4;
 }
 
diff --git a/public/opac/js/widget_templates/authors.jpg b/public/opac/js/widget_templates/authors.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..c7dc96512b093e9d3b838f312da344c51712f4c5
GIT binary patch
literal 32175
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

literal 0
HcmV?d00001

diff --git a/public/opac/js/widget_templates/widget_templates.json b/public/opac/js/widget_templates/widget_templates.json
index a939603c921..b24428962ab 100755
--- a/public/opac/js/widget_templates/widget_templates.json
+++ b/public/opac/js/widget_templates/widget_templates.json
@@ -225,7 +225,14 @@
           }
         },
 
-          {
+	{
+          "title": "Auteurs",
+          "icon": "authors.jpg",
+	  "type": "AUTHORS",
+          "configuration": {}
+	},
+	
+        {
           "title": "Nuage de tags",
           "icon": "nuage_tags.jpg",
 	  "type": "TAGS",
diff --git a/tests/db/UpgradeDBTest.php b/tests/db/UpgradeDBTest.php
index fb412af4b8d..6fe50e6c25d 100644
--- a/tests/db/UpgradeDBTest.php
+++ b/tests/db/UpgradeDBTest.php
@@ -2739,4 +2739,20 @@ class UpgradeDB_375_Test extends UpgradeDBTestCase {
     $this->assertEquals('Hello<br><br>You have a new friend',
                         $this->query('select valeur from bib_admin_var where clef="NOTIFICATION_TEMPLATE_NEW_USER"')->fetch()['valeur']);
   }
-}
\ No newline at end of file
+}
+
+
+
+
+class UpgradeDB_376_Test extends UpgradeDBTestCase {
+  public function prepare() {
+    $this
+      ->silentQuery('ALTER TABLE codif_auteur DROP COLUMN thumbnail_url');
+  }
+
+
+  /** @test */
+  public function tableCodifAuteurShouldHaveColumnThumbnailUrlVarChar255() {
+    $this->assertFieldType('codif_auteur', 'thumbnail_url', 'varchar(255)');
+  }
+}
diff --git a/tests/scenarios/AuthorPage/AuthorPageTest.php b/tests/scenarios/AuthorPage/AuthorPageTest.php
index 7c13953da0e..327a3fddd6f 100644
--- a/tests/scenarios/AuthorPage/AuthorPageTest.php
+++ b/tests/scenarios/AuthorPage/AuthorPageTest.php
@@ -56,6 +56,7 @@ abstract class AuthorPageTestCase extends AbstractControllerTestCase {
                     'facettes' => 'A2408  A3',
                     'url_vignette' => 'paris.jpg']);
 
+
     $this->fixture('Class_CodifAuteur',
                    ['id' => 2408,
                     'libelle' => 'Victor Hugo']);
@@ -190,17 +191,25 @@ class AuthorPageViewByIdTest extends AuthorPageTestCase {
     $this->assertEquals('UC1l7wYrva1qCH-wgqcHaaRg', Class_CodifAuteur::find(2408)->getYoutubeChannelId());
   }
 
-    /** @test */
+  /** @test */
   public function authorISNIShouldBe0000000078391751() {
     $this->assertEquals('0000 0000 7839 1751', Class_CodifAuteur::find(2408)->getIsni());
   }
 
-    /** @test */
+
+  /** @test */
   public function authorARKShouldBecb13971020f() {
     $this->assertEquals('ark:/12148/cb13971020f', Class_CodifAuteur::find(2408)->getArk());
   }
 
 
+  /** @test */
+  public function authorThumbnailUrlShouldBeHugoThumbDotJpg() {
+    $this->assertEquals('http://images.fr/hugo_thumb.jpg',
+                        Class_CodifAuteur::find(2408)->getThumbnailUrl());
+  }
+
+
   /** @test */
   public function pageTitleShouldBeVictorHugo() {
     $this->assertXPath('//title[text()="Auteur - Victor Hugo"]', $this->_response->getBody());
diff --git a/tests/scenarios/AuthorPage/AuthorWidgetTest.php b/tests/scenarios/AuthorPage/AuthorWidgetTest.php
new file mode 100644
index 00000000000..d271480cad6
--- /dev/null
+++ b/tests/scenarios/AuthorPage/AuthorWidgetTest.php
@@ -0,0 +1,501 @@
+<?php
+/**
+ * Copyright (c) 2012-2019, 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
+ */
+
+
+abstract class AuthorWidgetOnPageTestCase extends Admin_AbstractControllerTestCase {
+    protected
+    $_storm_default_to_volatile = true;
+
+  public function setUp() {
+    parent::setUp();
+
+    Class_AdminVar::set('AUTHOR_PAGE', 1);
+
+    $cfg_accueil = ['modules' => ['1' => ['division' => '2',
+                                          'type_module' => 'AUTHORS',
+                                          'preferences' => ['titre' => 'Mes auteurs',
+                                                            'id_panier' => 3]]]];
+
+    $this->fixture('Class_Profil',
+                   ['id' => 2,
+                    'libelle' => 'auteurs',
+                    'cfg_accueil' => $cfg_accueil])
+         ->beCurrentProfil();
+
+
+    $this->fixture('Class_Notice',
+                   ['id' => 8,
+                    'type_doc' => Class_TypeDoc::LIVRE,
+                    'clef_alpha'=>'GAVROCHE_HUGO',
+                    'titre_principal' => 'Gavroche',
+                    'facettes' => 'A2408 A3 A666 G4 M6',
+                    'url_vignette' => 'gavroche.jpg']);
+
+    $this->fixture('Class_Notice',
+                   ['id' => 9,
+                    'type_doc' => Class_TypeDoc::LIVRE,
+                    'clef_alpha'=>'MISERABLES_HUGO',
+                    'titre_principal' => 'Les Misérables',
+                    'facettes' => 'A2408 M6 A4',
+                    'unimarc' => file_get_contents(__DIR__ . '/les_miserables.marc'),
+                    'url_vignette' => 'miserables.jpg',
+                    'url_image' => 'miserables.jpg']);
+
+    $this->fixture('Class_Notice',
+                   ['id' => 10,
+                    'type_doc' => Class_TypeDoc::DVD,
+                    'clef_alpha'=>'DAMEPARIS_HUGO',
+                    'titre_principal' => 'Notre Dame de Paris',
+                    'unimarc' => file_get_contents(__DIR__ . '/notre_dame.marc'),
+                    'facettes' => 'A2408  A3',
+                    'url_vignette' => 'paris.jpg']);
+
+    $this->fixture('Class_CodifAuteur',
+                   ['id' => 2408,
+                    'libelle' => 'Victor Hugo',
+                    'thumbnail_url' => 'http://wp/hugo.jpg']);
+
+    $this->fixture('Class_CodifAuteur',
+                   ['id' => 3,
+                    'libelle' => 'Robert Hossein',
+                    'thumbnail_url' => 'http://wp/hossein.jpg']);
+
+    $this->fixture('Class_CodifAuteur',
+                   ['id' => 4,
+                    'libelle' => 'Marcus %s \Mill',
+                   'thumbnail_url' => 'http://wp&f=Defaut.svg']);
+
+    $this->fixture('Class_CodifAuteur',
+                   ['id' => 5,
+                    'libelle' => 'Delannoy Jean',
+                    'thumbnail_url' => 'http://wp/delannoy.jpg']);
+
+    $this->fixture('Class_CodifAuteurFonction',
+                   ['id' => 635,
+                    'libelle' => 'Programmeur informatique']);
+
+    $this->fixture('Class_CodifAuteurFonction',
+                   ['id' => '370',
+                    'libelle' => 'Réalisateur']);
+  }
+}
+
+
+
+
+class AuthorWidgetActionRefreshThumbnailsTest extends AuthorWidgetOnPageTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $mock_sql = $this->mock()
+                     ->whenCalled('fetchAll')
+                     ->answers([[9, 'A2408 M6 A4']]);
+    Zend_Registry::set('sql', $mock_sql);
+    Class_CosmoVar::newInstanceWithId('url_services')->setValeur('http://cache.org');
+    Class_WebService_AllServices::setHttpClient($http_client = $this->mock());
+
+    $http_client
+      ->whenCalled('open_url')
+      ->answers(json_encode(['statut_recherche' => 2,
+                             'erreur' => '',
+                             'vignette' => 'http://wp/marcus.jpg']));
+
+    $this->onLoaderOfModel('Class_Notice')
+         ->whenCalled('getNoticesFromPreferences')
+         ->answers(Class_Notice::findAll());
+
+    $this->dispatch('/admin/widget/widget-action/named/refresh/id_module/1/id_profil/2');
+  }
+
+
+  /** @test */
+  public function withIdModuleOneIdProfilTwoShouldSetThumbnailForMarcusMiller() {
+    $this->assertEquals('http://wp/marcus.jpg',
+                        Class_CodifAuteur::find(4)->getThumbnailUrl());
+  }
+
+
+  /** @test */
+  public function answerShouldRedirectToReferrer() {
+    $this->assertRedirect();
+  }
+}
+
+
+
+
+class AuthorWidgetActionRefreshThumbnailsWithWrongParamsTest extends AuthorWidgetOnPageTestCase {
+  public function errors() {
+    return [
+            ['id_module/1/id_profil/66655',
+             [404, 'Profil inexistant']],
+
+            ['id_module/134245/id_profil/2',
+             [404, 'Boite inexistante']],
+    ];
+  }
+
+
+  /**
+   * @dataProvider errors
+   * @test
+   */
+  public function withWrongIdProfilShouldAnswer404($url, $expected) {
+    try {
+      $this->dispatch('/admin/widget/widget-action/named/refresh/' . $url);
+    }  catch(Zend_Controller_Action_Exception $e) {
+      $this->assertEquals($expected,
+                          [$e->getCode(), $e->getMessage()]);
+      return;
+    }
+    $this->fail('should raise error 404 not found');
+  }
+}
+
+
+
+
+class AuthorWidgetOnPageTest extends AuthorWidgetOnPageTestCase {
+  public function setUp() {
+    parent::setUp();
+
+
+    $this->onLoaderOfModel('Class_Notice')
+         ->whenCalled('getNoticesFromPreferences')
+         ->willDo(function($preferences)
+                  {
+                    $this->assertEquals(3, $preferences['id_panier']);
+                    $this->assertEquals(10, $preferences['authors_count']);
+                    $this->assertEquals(Class_Systeme_ModulesAccueil_Authors::AUTHORS_SELECTION_MODE_ALL,
+                                        $preferences['authors_selection_mode']);
+                    return Class_Notice::findAll();
+                  });
+
+    $this->dispatch('/');
+  }
+
+
+  /** @test */
+  public function pageShouldContainsWidgetAuthorWithH1MesAuteurs() {
+    $this->assertXPathContentContains('//div[@class="boite authors"]//div[@class="titre"]//h1',
+                                      'Mes auteurs');
+  }
+
+
+  /** @test */
+  public function authorsWidgetShouldContainsLinkWithImageHosseinDotJpg() {
+    $this->assertXPath('//div[@class="boite authors"]//div[@class="author"]//a[contains(@href, "author/view/id/3")][@title="En savoir plus sur Robert Hossein"]//img[@src="http://wp/hossein.jpg"]');
+  }
+
+
+  /** @test */
+  public function numberOfAuthorsShouldBeTwo() {
+    $this->assertXPathCount('//div[@class="boite authors"]//div[@class="author"]',
+                            2);
+  }
+
+
+  /** @test */
+  public function widgetConfigurationShouldContainsButtonToRefreshThumbnails() {
+    $this->assertXPath('//div[@class="configuration_module"]//a[contains(@href, "/admin/widget/widget-action/named/refresh/id_module/1/id_profil/2")]');
+  }
+
+
+  /** @test */
+  public function pageShouldBeHTML5Valid() {
+    $this->assertHTML5();
+  }
+
+
+  /** @test */
+  public function pageShouldBeAccessible() {
+    $this->assertAccessible();
+  }
+}
+
+
+
+
+class AuthorWidgetOnPageWithMainAuthorSelectionModeTest extends AuthorWidgetOnPageTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    Class_Profil::find(2)
+      ->setCfgAccueil(['modules' => ['1' => ['division' => '2',
+                                             'type_module' => 'AUTHORS',
+                                             'preferences' => ['titre' => 'Une sélection',
+                                                               'op_largeur_img' => '50',
+                                                               'authors_selection_mode' => Class_Systeme_ModulesAccueil_Authors::AUTHORS_SELECTION_MODE_MAIN,
+                                                               'id_catalogue' => 5]]]]);
+
+
+    $this->onLoaderOfModel('Class_Notice')
+         ->whenCalled('getNoticesFromPreferences')
+         ->willDo(function($preferences)
+                  {
+                    $this->assertEquals(5, $preferences['id_catalogue']);
+                    $this->assertEquals(Class_Systeme_ModulesAccueil_Authors::AUTHORS_SELECTION_MODE_MAIN,
+                                        $preferences['authors_selection_mode']);
+                    return Class_Notice::findAll();
+                  });
+
+    $this->dispatch('/');
+  }
+
+
+  /** @test */
+  public function numberOfAuthorsShouldBeOne() {
+    $this->assertXPathCount('//div[@class="boite authors"]//div[@class="author"]',
+                            1);
+  }
+
+
+  /** @test */
+  public function authorsWidgetShouldContainsLinkWithImageHugoDotJpg() {
+    $this->assertXPath('//div[@class="boite authors"]//div[@class="author"]//a[contains(@href, "author/view/id/2408")][@title="En savoir plus sur Victor Hugo"]//img[@src="http://wp/hugo.jpg"][@width="50"]');
+  }
+
+
+  /** @test */
+  public function divAuthorsWallShouldHaveStyleColumnWidth50px() {
+    $this->assertXPath('//div[@class="authors_wall"][@style="column-width:50px"]');
+  }
+}
+
+
+
+
+class AuthorWidgetOnPageFilteredByResponsibilityTest extends AuthorWidgetOnPageTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    Class_Profil::find(2)
+      ->setCfgAccueil(['modules' => ['1' => ['division' => '2',
+                                             'type_module' => 'AUTHORS',
+                                             'preferences' => ['titre' => 'Une sélection',
+                                                               'op_largeur_img' => '50',
+                                                               'authors_selection_mode' => Class_Systeme_ModulesAccueil_Authors::AUTHORS_SELECTION_MODE_RESPONSIBILITIES,
+                                                               'responsibilities' => '230;370;',
+                                                               'id_catalogue' => 5]]]]);
+
+
+    $this->onLoaderOfModel('Class_Notice')
+         ->whenCalled('getNoticesFromPreferences')
+         ->answers(Class_Notice::findAll());
+
+    $this->onLoaderOfModel('Class_CodifAuteur')
+         ->whenCalled('findByLastNameFirstName')
+         ->with('Delannoy', 'Jean')
+         ->answers(Class_CodifAuteur::find(5));
+
+    $this->dispatch('/');
+  }
+
+
+  /** @test */
+  public function numberOfAuthorsShouldBeOne() {
+    $this->assertXPathCount('//div[@class="boite authors"]//div[@class="author"]',
+                            1);
+  }
+
+
+  /** @test */
+  public function authorsWidgetShouldContainsLinkWithImageDelannoyJpg() {
+    $this->assertXPath('//a[contains(@href, "author/view/id/5")][@title="En savoir plus sur Delannoy Jean"]//img[@src="http://wp/delannoy.jpg"]');
+  }
+}
+
+
+
+
+class AuthorWidgetOnPageLimitOneTest extends AuthorWidgetOnPageTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    Class_Profil::find(2)
+      ->setCfgAccueil(['modules' => ['1' => ['division' => '2',
+                                             'type_module' => 'AUTHORS',
+                                             'preferences' => ['titre' => 'Une sélection',
+                                                               'authors_count' => 1,
+                                                               'id_catalogue' => 5]]]]);
+
+
+    $this->onLoaderOfModel('Class_Notice')
+         ->whenCalled('getNoticesFromPreferences')
+         ->willDo(function($preferences)
+                  {
+                    $this->assertEquals(1, $preferences['authors_count']);
+                    return Class_Notice::findAll();
+                  });
+
+    $this->dispatch('/');
+  }
+
+
+  /** @test */
+  public function numberOfAuthorsShouldBeOne() {
+    $this->assertXPathCount('//div[@class="boite authors"]//div[@class="author"]',
+                            1);
+  }
+
+
+  /** @test */
+  public function authorsWidgetShouldContainsLinkWithImageHugoDotJpg() {
+   $this->assertXPath('//div[@class="boite authors"]//div[@class="author"]//a[contains(@href, "author/view/id/2408")][@title="En savoir plus sur Victor Hugo"]//img[@src="http://wp/hugo.jpg"]');
+  }
+}
+
+
+
+
+class AuthorWidgetConfigurationTest extends AuthorWidgetOnPageTestCase {
+  public function setUp() {
+    parent::setUp();
+    $this->dispatch('/admin/widget/edit-widget/id/1/id_profil/2');
+  }
+
+
+  /** @test */
+  public function formShouldContainsInputForTitre() {
+    $this->assertXPath('//input[@name="titre"][@value="Mes auteurs"]',
+                       $this->_response->getBody());
+  }
+
+
+  /** @test **/
+  public function formShouldContainsHiddenInputWithIdCatalogue() {
+    $this->assertXPath('//input[@type="hidden"][@id="id_catalogue"]');
+  }
+
+
+  /** @test **/
+  public function formShouldContainsHiddenInputWithIdPanierValueThree() {
+    $this->assertXPath('//input[@type="hidden"][@id="id_panier"][@value="3"]');
+  }
+
+
+  /** @test **/
+  public function formShouldContainsInputAuthorsCountValueTen() {
+    $this->assertXPath('//input[@type="number"][@name="authors_count"][@value="10"][@min="1"][@max="200"]');
+  }
+
+
+  /** @test **/
+  public function formShouldContainsInputSliderForOpLargeurImg() {
+    $this->assertXPath('//input[@name="op_largeur_img"]');
+    $this->assertXPathContentContains('//script', '$("#op_largeur_img-slider").slider');
+  }
+
+
+  /** @test */
+  public function formShouldContainsRadioButtonForAuthorsSelectionModeMain() {
+    $this->assertXPath('//input[@type="radio"][@name="authors_selection_mode"][@value="main"][not(@checked)]');
+  }
+
+
+  /** @test */
+  public function formShouldContainsCheckedRadioButtonForAuthorsSelectionModeAll() {
+    $this->assertXPath('//input[@type="radio"][@name="authors_selection_mode"][@value="all"][@checked]');
+  }
+}
+
+
+
+
+class AuthorWidgetConfigurationWithDomainTest extends AuthorWidgetOnPageTestCase {
+  public function setUp() {
+    parent::setUp();
+    Class_Profil::find(2)
+      ->setCfgAccueil(['modules' => ['1' => ['division' => '2',
+                                             'type_module' => 'AUTHORS',
+                                             'preferences' => ['titre' => 'Une sélection',
+                                                               'id_catalogue' => 5]]]])
+      ->save();
+
+    $this->dispatch('/admin/widget/edit-widget/id/1/id_profil/2');
+  }
+
+
+  /** @test */
+  public function formShouldContainsInputForTitreWithVlueUneSelection() {
+    $this->assertXPath('//input[@name="titre"][@value="Une sélection"]');
+  }
+
+
+  /** @test **/
+  public function formShouldContainsHiddenInputWithIdCategorieValueFive() {
+    $this->assertXPath('//input[@type="hidden"][@id="id_catalogue"][@value="5"]');
+  }
+}
+
+
+
+
+class AuthorWidgetConfigurationPostTest extends AuthorWidgetOnPageTestCase {
+  protected $_saved_settings;
+
+  public function setUp() {
+    parent::setUp();
+    $this->postDispatch('/admin/widget/edit-widget/id/1/id_profil/2',
+                        ['id_panier' => '5',
+                         'titre' => 'Des gens']);
+    Class_Profil::clearCache();
+    $this->_saved_settings = Class_Profil::find(2)
+      ->getCfgAccueilAsArray()['modules'][1];
+  }
+
+
+  /** @test **/
+  public function shouldRedirect() {
+    $this->assertRedirect();
+  }
+
+
+  /** @test */
+  public function titleShouldBeDesGens() {
+    $this->assertEquals('Des gens', $this->_saved_settings['preferences']['titre']);
+  }
+
+
+  /** @test */
+  public function idPanierShouldBeFive() {
+    $this->assertEquals('5', $this->_saved_settings['preferences']['id_panier']);
+  }
+}
+
+
+
+
+class AuthorWidgetResponsibilitiesInputSuggestTest extends AuthorWidgetOnPageTestCase {
+  /** @test */
+  public function onSearchTermProShouldRetunProgrammeurInformatique() {
+    $this->onLoaderOfModel('Class_CodifAuteurFonction')
+         ->whenCalled('findAllBy')
+         ->with(['where' => 'libelle like "Pro%"',
+                 'order' => 'libelle'])
+         ->answers([Class_CodifAuteurFonction::find(635)]);
+
+    $this->dispatch('/admin/ajax/listesuggestion?type_autorite=responsibility&id_champ=responsibilities&mode=1&valeur=Pro');
+
+    $this->assertEquals('<div class="tag_liste" clef="635" onclick="selectSuggest(\'responsibilities\',this)">Programmeur informatique</div>',
+                        $this->_response->getBody());
+  }
+}
diff --git a/tests/scenarios/AuthorPage/notre_dame.marc b/tests/scenarios/AuthorPage/notre_dame.marc
new file mode 100644
index 00000000000..aab37b06f3e
--- /dev/null
+++ b/tests/scenarios/AuthorPage/notre_dame.marc
@@ -0,0 +1 @@
+01365nam0 2200253   450 001000700000100001300007200002400020210006200044215009600106300002600202330029900228700003800527702018000565702004000745702005500785702002900840702003300869702002900902702002600931702002600957702002900983702008201012801001701094256387  a201105051 aNotre-Dame de Paris  a[Issy-les-Moulineaux]cStudioCanal vidéo éd.dcop. 2005  a1 DVD vidéo monoface double couche zone 2, 1h58 min.c. 2.35, 16/9 comp. 4/3, coul. (PAL),  aPays : France (1956).  aDans le Paris médiéval, la belle danseuse Esméralda déchaine les passions. Au milieu des mendiants et des truands de la cour des Miracles, le drame se noue peu à peu entre Phoebus, le capitaine des gardes dont elle est amoureuse, le monstrueux Quasimodo et l'inquiétant alchimiste Frollo. 1aDelannoybJean40006Réalisateur 1aHugobVictorf1802-188531190796640106Adaptateur8Hugo, Victor-Marie (1802-1885)8Hugo, Vittor (1802-1885)8Hugo, Vittorio (1802-1885)8Yu guo (1802-1885)8Yuguo (1802-1885) 1aAurenchebJean40006Dialogues avec 1aPrévertbJacques3OPS117832940006Dialogues avec 1aAuricbGeorges40006230 1aLollobrigidabGina48006005 1aQuinnbAnthony48006005 1aDanetbJean48006005 1aCunybAlain48006005 1aHirschbRobert48006005 1aClaybPhilippef1927-2007311935067480060058Mathevet, Philippe (1927-2007) 2aFrc20150404
\ No newline at end of file
-- 
GitLab