Commit e3a4eb33 authored by Sebastien ANDRE's avatar Sebastien ANDRE Committed by efalcy
Browse files

dev#154000 add zotero label on type doc

parent 339ce058
Pipeline #17035 passed with stage
in 33 minutes and 46 seconds
'154000' =>
['Label' => $this->_('Zotero : Configuration et affichage des types de documents'),
'Desc' => '',
'Image' => '',
'Video' => '',
'Category' => '',
'Right' => function($feature_description, $user) {return true;},
'Wiki' => 'https://wiki.bokeh-library-portal.org/index.php?title=Zotero',
'Test' => '',
'Date' => '2022-04-01'],
\ No newline at end of file
- fonctionnalité #154000 : Zotero : Possibilité de configurer les types de documents pour Zotero
\ No newline at end of file
......@@ -6,9 +6,8 @@ Class_ScriptLoader::getInstance()
$description = (new Class_TableDescription('type_docs'))
->addColumn($this->_('Libellé'), 'label')
->addColumn($this->_('Famille'), 'libelle_famille')
->addColumn($this->_('Libellé Zotero'), 'display_label_zotero')
->addRowAction(function($model) { return $this->renderPluginsActions($model); });
echo $this->renderTable($description,
$this->type_docs);
?>
<?php
$adapter = Zend_Db_Table_Abstract::getDefaultAdapter();
try {
$adapter->query('alter table codif_type_doc add column label_zotero varchar(255) default ""');
} catch(Exception $e) {}
......@@ -19,9 +19,56 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class CodifTypeDocLoader extends Storm_Model_Loader{
use Trait_StaticFileSystem, Trait_SimpleWebClient;
protected $_libelles = [Class_CodifTypeDoc::INCONNU => 'Non identifié',
Class_CodifTypeDoc::LIVRE => 'Livre',
Class_CodifTypeDoc::PERIODIQUE => 'Périodique' ,
Class_CodifTypeDoc::SONORE => 'Sonore',
Class_CodifTypeDoc::VIDEO => 'Vidéo',
Class_CodifTypeDoc::LOGICIEL => 'Logiciel'],
$_zotero_schema;
public function getFamillesLibelles():array {
return $this->_libelles;
}
public function getZoteroSchema (): ?string {
if ($this->_zotero_schema)
return $this->_zotero_schema;
try {
$schema = (static::getWebClient())
->open_url('https://api.zotero.org/schema',
['headers' =>'Accept-Encoding: utf-8']);
}
catch (Exception $e){
return $this->_zotero_schema = $this->getFileSystem()
->file_get_contents(ROOT_PATH.'/public/admin/zotero_schema');
}
return $this->_zotero_schema = $schema;
}
public function getZoteroItemTypes():array {
$schema = json_decode($this->getZoteroSchema(), true);
$lang = (Class_AdminVar::getDefaultLanguage() == 'fr') ? 'fr-FR': 'en-GB';
if (! $item_types ??= ($schema['locales'][$lang]['itemTypes']))
return [];
asort($item_types);
return $item_types;
}
}
class Class_CodifTypeDoc extends Storm_Model_Abstract {
use Trait_Translator;
const CODE_FACETTE = 'T';
const INCONNU = 0;
const LIVRE = 1;
const PERIODIQUE = 2;
......@@ -29,44 +76,30 @@ class Class_CodifTypeDoc extends Storm_Model_Abstract {
const VIDEO = 4;
const LOGICIEL = 5;
const CODE_FACETTE = 'T';
protected $_loader_class = CodifTypeDocLoader::class;
protected $_table_name = 'codif_type_doc';
protected $_table_primary = 'type_doc_id';
protected $_default_attribute_values = ['bibliotheques' => '',
'annexes' => '',
'sections' => '',
'label_zotero' => '',
'famille_id' => ''];
protected $_default_label_zotero = [];
protected $_fixed_id = true;
protected static $_libelles = [self::INCONNU => 'Non identifié',
self::LIVRE => 'Livre',
self::PERIODIQUE => 'Périodique' ,
self::SONORE => 'Sonore',
self::VIDEO => 'Vidéo',
self::LOGICIEL => 'Logiciel'];
public function getLibelle() {
return $this->_(static::$_libelles[$this->getFamilleId()]);
return $this->getLoader()->getFamillesLibelles()[$this->getFamilleId()];
}
public function setFamilleId($id) {
if (!isset(static::$_libelles[$id]))
if (!isset($this->getLoader()->getFamillesLibelles()[$id]))
$id = 0;
return parent::_set('famille_id', $id);
}
public static function getFamillesLibelles() {
return static::$_libelles;
}
public function afterSave() {
$this->setId($this->getTypeDocId());
}
......@@ -77,6 +110,27 @@ class Class_CodifTypeDoc extends Storm_Model_Abstract {
}
public function getLabelZotero(){
if ($this->_get('label_zotero'))
return $this->_get('label_zotero');
if ($this->isUnknown())
return '';
if ($this->isPeriodique())
return 'journalArticle';
if ($this->isVideo())
return 'film';
if ($this->isSonore())
return 'audioRecording';
return 'book';
}
public function getDisplayLabelZotero() :string {
return ($this->getLoader()->getZoteroItemTypes())[$this->getLabelZotero()]?? '';
}
public function isSonore() {
return static::SONORE == $this->getFamilleId();
}
......
......@@ -62,6 +62,7 @@ class Class_Notice_MetaData {
->addMeta('dc.publisher', $this->_record->getFirstEditeur())
->addMeta('dc.date', (new Class_Notice_PublicationDate($this->_record))->getPublicationDate());
foreach($this->_record->getMatieresLabels() as $matiere)
$script_loader->addMeta('dc.subject', $matiere);
......@@ -93,6 +94,7 @@ class Class_Notice_MetaData {
return $this;
}
protected function _addTome($script_loader) {
$script_loader->addMeta('Z.volume',
$this->_record->getTomeAlpha());
......@@ -100,11 +102,28 @@ class Class_Notice_MetaData {
}
protected function _addType($script_loader) {
protected function _addDefaultType($script_loader) {
$script_loader->addMeta('og:type', 'website');
return $this;
}
protected function _addDefaultZoteroType($script_loader) {
if ((!$type_doc = Class_TypeDoc::find($this->_record->getTypeDoc()))
|| !($label_zotero = $type_doc->getLabelZotero()))
return $this;
$script_loader->addMeta('Z.itemType', $label_zotero);
return $this;
}
protected function _addType($script_loader){
$this->_addDefaultType($script_loader);
$this->_addDefaultZoteroType($script_loader);
return $this;
}
protected function _addIdentifier($script_loader) {
return $this;
......@@ -120,8 +139,8 @@ class Class_Notice_MetaData {
class Class_Notice_MetaData_Book extends Class_Notice_MetaData {
protected function _addType($script_loader) {
$script_loader->addMeta('og:type', 'book');
protected function _addDefaultType($script_loader) {
$script_loader->addMeta('og:type', 'book');
return $this;
}
......@@ -142,10 +161,9 @@ class Class_Notice_MetaData_Book extends Class_Notice_MetaData {
class Class_Notice_MetaData_JournalArticle extends Class_Notice_MetaData {
protected function _addType($script_loader) {
protected function _addDefaultType($script_loader) {
$script_loader
->addMeta('og:type', 'article')
->addMeta('Z.itemType', 'journalArticle');
->addMeta('og:type', 'article');
return $this;
}
......@@ -177,8 +195,8 @@ class Class_Notice_MetaData_JournalArticle extends Class_Notice_MetaData {
class Class_Notice_MetaData_VideoMovie extends Class_Notice_MetaData {
protected function _addType($script_loader) {
$script_loader->addMeta('og:type', 'video.movie');
protected function _addDefaultType($script_loader) {
$script_loader->addMeta('og:type', 'video.movie');
return $this;
}
......@@ -195,7 +213,7 @@ class Class_Notice_MetaData_VideoMovie extends Class_Notice_MetaData {
protected function _addIdentifier($script_loader) {
$script_loader->addMeta('dc.identifier', $this->_record->getEan());
$script_loader->addMeta('dc.identifier', $this->_record->getEan());
return $this;
}
......@@ -221,8 +239,8 @@ class Class_Notice_MetaData_MusicAlbum extends Class_Notice_MetaData {
}
protected function _addType($script_loader) {
$script_loader->addMeta('og:type', 'music.album');
protected function _addDefaultType($script_loader) {
$script_loader->addMeta('og:type', 'music.album');
return $this;
}
}
......@@ -459,6 +459,16 @@ class Class_TypeDoc extends Storm_Model_Abstract {
}
public function getDisplayLabelZotero() {
return $this->getCodifTypeDoc()->getDisplayLabelZotero();
}
public function getLabelZotero() {
return $this->getCodifTypeDoc()->getLabelZotero();
}
public function getFamilleId() {
return $this->getCodifTypeDoc()->getFamilleId();
}
......@@ -505,10 +515,17 @@ class Class_TypeDoc extends Storm_Model_Abstract {
}
public function setLabelZotero($label) : self {
$this->getCodifTypeDoc()->setLabelZotero($label);
return $this;
}
public function toArray() {
return ['id'=> $this->getId(),
'famille_id' => $this->getFamilleId(),
'label' => $this->getLabel()];
'label' => $this->getLabel(),
'label_zotero' => $this->getLabelZotero()];
}
......
......@@ -63,12 +63,15 @@ class ZendAfi_Form_TypeDocs_Edit extends ZendAfi_Form {
->setAttrib('id', 'typedoc_edit')
->setAttrib('class', 'zend_form')
->addElement('text', 'label', ['label' => $this->_('Libellé')])
->addElement('select', 'famille_id', ['label' => $this->_('Famille du document'),
'multiOptions' => Class_CodifTypeDoc::getFamillesLibelles(),
'required' => true ]
)
->addDisplayGroup(['label', 'famille_id'], 'edit', ['legend' => 'Définition']);
->addElement('select', 'famille_id',
['label' => $this->_('Famille du document'),
'multiOptions' => Class_CodifTypeDoc::getFamillesLibelles(),
'required' => true ])
->addElement('select', 'label_zotero',
['label' => $this->_('Libellé Zotero'),
'multiOptions' => Class_CodifTypeDoc::getZoteroItemTypes()])
->addDisplayGroup(['label', 'famille_id', 'label_zotero'], 'edit', ['legend' => 'Définition']);
}
}
?>
\ No newline at end of file
?>
This diff is collapsed.
......@@ -62,7 +62,7 @@ class TypeDocsControllerIndexTest extends AbstractTypeDocsControllerTestCase {
/** @test */
public function actionColumnShouldHaveSorterFalse() {
$this->assertXPath('//thead//th[3][@class="actions"][@data-sorter="false"]', $this->_response->getBody());
$this->assertXPath('//thead//th[4][@class="actions"][@data-sorter="false"]', $this->_response->getBody());
}
......@@ -310,4 +310,4 @@ class TypeDocsControllerResetThumbnailsTest extends AbstractTypeDocsControllerTe
$this->assertFlashMessengerContentContains('Type de document inconnu');
}
}
?>
\ No newline at end of file
?>
......@@ -4371,3 +4371,17 @@ class UpgradeDB_427_Test extends UpgradeDBTestCase {
$this->assertEquals('PRI', $columns['Key']);
}
}
class UpgradeDB_428_Test extends UpgradeDBTestCase {
public function prepare() {
$this->silentQuery('alter table codif_type_doc drop column label_zotero');
}
/** @test */
public function codifTypeDocShouldHaveColumnLabelZotero() {
$this->assertFieldType('codif_type_doc', 'label_zotero', 'varchar(255)');
}
}
<?php
/**
* Copyright (c) 2012-2022, 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 ZoteroAdminTestCase extends Admin_AbstractControllerTestCase {
public function setUp() {
parent::setUp();
Class_CodifTypeDoc::setWebClient($this->mock()
->whenCalled('open_url')
->with('https://api.zotero.org/schema',
['headers' =>'Accept-Encoding: utf-8'])
->answers(file_get_contents(__DIR__ . '/schema.json')));
$this->fixture(Class_CodifTypeDoc::class,
['id'=> 10,
'famille_id'=> '3',
'label_zotero' => 'magazineArticle']);
}
}
class ZoteroAdminIndexTest extends ZoteroAdminTestCase {
public function setUp() {
parent::setUp();
$this->dispatch('/admin/type-docs/index');
}
/** @test */
public function tableShouldContainsLibelleZotero() {
$this->assertXPathContentContains('//table//th', 'Libellé Zotero');
}
/** @test */
public function tableTDShouldContainsMagazineArticle() {
$this->assertXPathContentContains('//table//td', 'Article magazine');
}
}
class ZoteroAdminEditTest extends ZoteroAdminTestCase {
public function setUp() {
parent::setUp();
}
/** @test */
public function pageShouldContainsLabelLibelleZotero() {
$this->dispatch('/admin/type-docs/edit/id/10');
$this->assertXPathContentContains('//td/label', 'Libellé Zotero');
}
/** @test */
public function errorPageOnGetSchemaShouldFallbackOnLocalFile() {
Class_CodifTypeDoc::setWebClient($this->mock()
->whenCalled('open_url')
->with('https://api.zotero.org/schema',
['headers' =>'Accept-Encoding: utf-8'])
->willDo(function() {throw new Zend_Http_Client_Adapter_Exception('Unable to connect');}));
$this->dispatch('/admin/type-docs/edit/id/10');
$this->assertXPathContentContains('//td/select[@name="label_zotero"]//option[@value="magazineArticle"][@selected="selected"]', 'Article de magazine');
}
/** @test */
public function pageShouldContainsInputValueInEnglishIfOtherDefaultLanguage() {
Class_AdminVar::set('DEFAULT_LANGUAGE','en');
Class_CodifTypeDoc::setWebClient($this->mock()
->whenCalled('open_url')
->with('https://api.zotero.org/schema',
['headers' =>'Accept-Encoding: utf-8'])
->willDo(function() {throw new Zend_Http_Client_Adapter_Exception('Unable to connect');}));
$this->dispatch('/admin/type-docs/edit/id/10');
$this->assertXPathContentContains('//td/select[@name="label_zotero"]//option[@value="magazineArticle"][@selected="selected"]', 'Magazine Article');
}
/** @test */
public function pageShouldContainsInputValueLabelZotero() {
$this->dispatch('/admin/type-docs/edit/id/10');
$this->assertXPathContentContains('//td/select[@name="label_zotero"]//option[@value="magazineArticle"][@selected="selected"]', 'Article magazine');
}
}
class ZoteroAdminPostEditTest extends ZoteroAdminTestCase {
public function setUp() {
parent::setUp();
$this->postDispatch('/admin/type-docs/edit/id/10',
['label_zotero' => 'artwork',
'libelle_famille' => Class_CodifTypeDoc::SONORE,
'libelle' => 'Musique']);
}
/** @test */
public function labelZoteroShouldBeArtwork() {
$this->assertEquals('artwork', Class_TypeDoc::find(10)->getLabelZotero());
}
}
......@@ -24,7 +24,6 @@ abstract class ZoteroTestCase extends AbstractControllerTestCase {
protected $_storm_default_to_volatile = true;
/** @afterClass */
public static function resetUniqueResponse() {
static::$_unique_response = null;
......@@ -205,7 +204,7 @@ class ZoteroVideoTest extends ZoteroTestCase {
'ean' => '979-10-360-0022-5',
'unimarc' => file_get_contents(ROOT_PATH . 'tests/fixtures/dvd_potter.uni')
]);
Class_TypeDoc::find(Class_TypeDoc::DVD)->setLabelZotero('zoteroVideo')->save();
$this->uniqueDispatch('/recherche/viewnotice/id/3');
}
......@@ -213,6 +212,7 @@ class ZoteroVideoTest extends ZoteroTestCase {
public function expectedMetasDatas() {
return [
['og:type', 'video.movie'],
['Z.itemType', 'zoteroVideo'],
['dc.identifier', '979-10-360-0022-5'],
['dc.creator', 'Columbus, Chris'],
['bib.contributors', 'Columbus, Chris'],
......@@ -238,6 +238,28 @@ class ZoteroVideoTest extends ZoteroTestCase {
class ZoteroSonoreTest extends ZoteroTestCase {
public function setUp() {
parent::setUp();
$this->fixture(Class_Notice::class,
['id' => 4,
'type_doc' => Class_TypeDoc::DISQUE
]);
$this->uniqueDispatch('/recherche/viewnotice/id/4');
}
public function expectedMetasDatas() {
return [
['og:type', 'music.album'],
];
}
}
class ZoteroLabelSonoreTest extends ZoteroTestCase {
public function setUp() {
parent::setUp();
......@@ -246,6 +268,7 @@ class ZoteroSonoreTest extends ZoteroTestCase {
'type_doc' => Class_TypeDoc::DISQUE
]);
Class_TypeDoc::find(Class_TypeDoc::DISQUE)->setLabelZotero('hearing')->save();
$this->uniqueDispatch('/recherche/viewnotice/id/4');
}
......@@ -253,6 +276,7 @@ class ZoteroSonoreTest extends ZoteroTestCase {
public function expectedMetasDatas() {
return [
['og:type', 'music.album'],
['Z.itemType', 'hearing'],
];
}
}
......
{
"version": 15,
"itemTypes": [
{
"itemType": "annotation",
"fields": [],
"creatorTypes": []
},
{
"itemType": "artwork",
"fields": [
{
"field": "title"
}
]
},
{
"itemType": "magazineArticle",
"fields": [
{
"field": "title"
}
]
}
],
"locales": {
"fr-FR": {
"itemTypes": {
"annotation": "Annotation",
"artwork": "Illustration",
"attachment": "Pièce jointe",
"audioRecording": "Enregistrement audio",
"bill": "Projet/proposition de loi",
"blogPost": "Billet de blog",
"book": "Livre",
"bookSection": "Chapitre de livre",
"case": "Affaire",
"computerProgram": "Logiciel",
"conferencePaper": "Article de colloque",
"dictionaryEntry": "Entrée de dictionnaire",
"document": "Document",
"email": "Courriel",
"encyclopediaArticle": "Article d'encyclopédie",
"film": "Film",
"forumPost": "Message de forum",
"hearing": "Audience",
"instantMessage": "Message instantané",