Commit ba0632e2 authored by Laurent's avatar Laurent

Merge branch 'dev#95222_pairing_boite_auteur' into 'master'

Add authors widget

See merge request !3188
parents 0689468b 4e411e72
Pipeline #7955 passed with stage
in 37 minutes and 59 seconds
'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
- ticket #95222 : Ajout de la boite Auteurs
\ No newline at end of file
......@@ -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(),
......
......@@ -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
<?php
$adapter = Zend_Db_Table_Abstract::getDefaultAdapter();
try {
$adapter->query('alter table codif_auteur add column thumbnail_url varchar(255)');
} catch(Exception $e) {}
......@@ -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
......@@ -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 '';
......
......@@ -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
......@@ -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]);
......
......@@ -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)
......
......@@ -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;
......
<?PHP
<?php
/**
* Copyright (c) 2012, Agence Française Informatique (AFI). All rights reserved.
*
......@@ -16,47 +16,42 @@
*
* 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
*/
////////////////////////////////////////////////////////////////////////////////////////
// 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;
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];
}
}
?>
\ No newline at end of file
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
<?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
<?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