From d8d395978973f91db0d4a9720006c9edb6e010cf Mon Sep 17 00:00:00 2001 From: Mario Trojan <mario.trojan@uni-tuebingen.de> Date: Wed, 15 Jan 2020 16:12:33 +0100 Subject: [PATCH] Metadata Vocabularies for Google Scholar. (#1529) - Resolves VUFIND-951. --- config/vufind/metadata.ini | 14 ++ module/VuFind/config/module.config.php | 2 + .../MetadataVocabulary/AbstractBase.php | 114 +++++++++++++++++ .../src/VuFind/MetadataVocabulary/BEPress.php | 61 +++++++++ .../VuFind/MetadataVocabulary/DublinCore.php | 59 +++++++++ .../src/VuFind/MetadataVocabulary/Eprints.php | 81 ++++++++++++ .../MetadataVocabulary/HighwirePress.php | 88 +++++++++++++ .../MetadataVocabularyInterface.php | 53 ++++++++ .../src/VuFind/MetadataVocabulary/PRISM.php | 55 ++++++++ .../MetadataVocabulary/PluginFactory.php | 48 +++++++ .../MetadataVocabulary/PluginManager.php | 67 ++++++++++ .../src/VuFind/View/Helper/Root/Metadata.php | 121 ++++++++++++++++++ .../View/Helper/Root/MetadataFactory.php | 68 ++++++++++ .../RecordDriver/DefaultRecord/core.phtml | 1 + themes/root/theme.config.php | 2 + 15 files changed, 834 insertions(+) create mode 100644 config/vufind/metadata.ini create mode 100644 module/VuFind/src/VuFind/MetadataVocabulary/AbstractBase.php create mode 100644 module/VuFind/src/VuFind/MetadataVocabulary/BEPress.php create mode 100644 module/VuFind/src/VuFind/MetadataVocabulary/DublinCore.php create mode 100644 module/VuFind/src/VuFind/MetadataVocabulary/Eprints.php create mode 100644 module/VuFind/src/VuFind/MetadataVocabulary/HighwirePress.php create mode 100644 module/VuFind/src/VuFind/MetadataVocabulary/MetadataVocabularyInterface.php create mode 100644 module/VuFind/src/VuFind/MetadataVocabulary/PRISM.php create mode 100644 module/VuFind/src/VuFind/MetadataVocabulary/PluginFactory.php create mode 100644 module/VuFind/src/VuFind/MetadataVocabulary/PluginManager.php create mode 100644 module/VuFind/src/VuFind/View/Helper/Root/Metadata.php create mode 100644 module/VuFind/src/VuFind/View/Helper/Root/MetadataFactory.php diff --git a/config/vufind/metadata.ini b/config/vufind/metadata.ini new file mode 100644 index 00000000000..df8d4cec422 --- /dev/null +++ b/config/vufind/metadata.ini @@ -0,0 +1,14 @@ +; This file controls the export of HTML meta headers on the Record page. +; +; The amount of exported metadata depends on field availability +; as well as the implementation of the chosen RecordDriver. +; (e.g. \VuFind\RecordDriver\DefaultRecord implements getContainerTitle(), +; but in case of SolrMarc the referenced "container_title" field +; is not indexed by default). +; +[Vocabularies] +;VuFind\RecordDriver\SolrMarc[] = BEPress +;VuFind\RecordDriver\SolrMarc[] = DublinCore +;VuFind\RecordDriver\SolrMarc[] = Eprints +;VuFind\RecordDriver\SolrMarc[] = HighwirePress ; recommended for Google Scholar +;VuFind\RecordDriver\SolrMarc[] = PRISM diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php index b0e499d1418..cd3d16423ee 100644 --- a/module/VuFind/config/module.config.php +++ b/module/VuFind/config/module.config.php @@ -391,6 +391,7 @@ $config = [ 'VuFind\ILS\HoldSettings' => 'VuFind\ILS\HoldSettingsFactory', 'VuFind\Log\Logger' => 'VuFind\Log\LoggerFactory', 'VuFind\Mailer\Mailer' => 'VuFind\Mailer\Factory', + 'VuFind\MetadataVocabulary\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory', 'VuFind\Net\IpAddressUtils' => 'Zend\ServiceManager\Factory\InvokableFactory', 'VuFind\OAI\Server' => 'VuFind\OAI\ServerFactory', 'VuFind\OAI\Server\Auth' => 'VuFind\OAI\ServerFactory', @@ -567,6 +568,7 @@ $config = [ 'hierarchy_treedatasource' => [ /* see VuFind\Hierarchy\TreeDataSource\PluginManager for defaults */ ], 'hierarchy_treerenderer' => [ /* see VuFind\Hierarchy\TreeRenderer\PluginManager for defaults */ ], 'ils_driver' => [ /* See VuFind\ILS\Driver\PluginManager for defaults */ ], + 'metadatavocabulary' => [ /* See VuFind\MetadataVocabulary\PluginManager for defaults */], 'recommend' => [ /* See VuFind\Recommend\PluginManager for defaults */ ], 'record_fallbackloader' => [ /* See VuFind\Record\FallbackLoader\PluginManager for defaults */ ], 'recorddriver' => [ /* See VuFind\RecordDriver\PluginManager for defaults */ ], diff --git a/module/VuFind/src/VuFind/MetadataVocabulary/AbstractBase.php b/module/VuFind/src/VuFind/MetadataVocabulary/AbstractBase.php new file mode 100644 index 00000000000..796039a346b --- /dev/null +++ b/module/VuFind/src/VuFind/MetadataVocabulary/AbstractBase.php @@ -0,0 +1,114 @@ +<?php +/** + * Metadata vocabulary base class + * (provides results from available RecordDriver methods in a standardized form) + * + * PHP version 7 + * + * Copyright (C) University of Tübingen 2019. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +namespace VuFind\MetadataVocabulary; + +/** + * Metadata vocabulary base class + * (provides results from available RecordDriver methods in a standardized form) + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +abstract class AbstractBase implements MetadataVocabularyInterface +{ + /** + * This varriable can be overwritten by child classes + * to define which custom field is filled by which generic fields. + * + * @var array + */ + protected $vocabFieldToGenericFieldsMap = []; + + /** + * Generate standardized data from available RecordDriver methods + * + * @param \VuFind\RecordDriver\AbstractBase $driver Record driver + * + * @return array + */ + protected function getGenericData(\VuFind\RecordDriver\AbstractBase $driver) + { + return [ + 'author' => array_unique( + array_merge( + $driver->tryMethod('getPrimaryAuthors'), + $driver->tryMethod('getSecondaryAuthors'), + $driver->tryMethod('getCorporateAuthors') + ) + ), + 'container_title' => $driver->tryMethod('getContainerTitle'), + 'date' => $driver->tryMethod('getPublicationDates'), + 'doi' => $driver->tryMethod('getCleanDOI'), + 'endpage' => $driver->tryMethod('getContainerEndPage'), + 'isbn' => $driver->tryMethod('getCleanISBN'), + 'issn' => $driver->tryMethod('getCleanISSN'), + 'issue' => $driver->tryMethod('getContainerIssue'), + 'language' => $driver->tryMethod('getLanguages'), + 'publisher' => $driver->tryMethod('getPublishers'), + 'startpage' => $driver->tryMethod('getContainerStartPage'), + 'title' => $driver->tryMethod('getTitle'), + 'volume' => $driver->tryMethod('getContainerVolume'), + ]; + } + + /** + * Perform mapping from generic data to vocabulary data + * + * @param \VuFind\RecordDriver\AbstractBase $driver Record driver + * + * @return array + */ + public function getMappedData(\VuFind\RecordDriver\AbstractBase $driver) + { + $genericData = $this->getGenericData($driver); + $mappedData = []; + + foreach ($this->vocabFieldToGenericFieldsMap as $vocabField => $genFields) { + foreach ((array)$genFields as $genericField) { + $genericValues = $genericData[$genericField] ?? []; + if ($genericValues) { + if (!is_array($genericValues)) { + $genericValues = [$genericValues]; + } + foreach ($genericValues as $genericValue) { + if (!isset($mappedData[$vocabField])) { + $mappedData[$vocabField] = []; + } + $mappedData[$vocabField][] = $genericValue; + } + } + } + } + + return $mappedData; + } +} diff --git a/module/VuFind/src/VuFind/MetadataVocabulary/BEPress.php b/module/VuFind/src/VuFind/MetadataVocabulary/BEPress.php new file mode 100644 index 00000000000..0a467a596b4 --- /dev/null +++ b/module/VuFind/src/VuFind/MetadataVocabulary/BEPress.php @@ -0,0 +1,61 @@ +<?php +/** + * Metadata vocabulary implementation for BEPress + * + * PHP version 7 + * + * Copyright (C) University of Tübingen 2019. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +namespace VuFind\MetadataVocabulary; + +/** + * Metadata vocabulary implementation for BEPress + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class BEPress extends AbstractBase +{ + /** + * Mapping from BEPress to VuFind fields; see http:// + * div.div1.com.au/div-thoughts/div-commentaries/66-div-commentary-metadata + * + * @var array + */ + protected $vocabFieldToGenericFieldsMap = [ + 'bepress_citation_author' => 'author', + 'bepress_citation_date' => 'date', + 'bepress_citation_doi' => 'doi', + 'bepress_citation_firstpage' => 'startpage', + 'bepress_citation_isbn' => 'isbn', + 'bepress_citation_issn' => 'issn', + 'bepress_citation_issue' => 'issue', + 'bepress_citation_journal_title' => 'container_title', + 'bepress_citation_lastpage' => 'endpage', + 'bepress_citation_publisher' => 'publisher', + 'bepress_citation_title' => 'title', + 'bepress_citation_volume' => 'volume', + ]; +} diff --git a/module/VuFind/src/VuFind/MetadataVocabulary/DublinCore.php b/module/VuFind/src/VuFind/MetadataVocabulary/DublinCore.php new file mode 100644 index 00000000000..ee03d4c397c --- /dev/null +++ b/module/VuFind/src/VuFind/MetadataVocabulary/DublinCore.php @@ -0,0 +1,59 @@ +<?php +/** + * Metadata vocabulary implementation for Dublin Core + * + * PHP version 7 + * + * Copyright (C) University of Tübingen 2019. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +namespace VuFind\MetadataVocabulary; + +/** + * Metadata vocabulary implementation for Dublin Core + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class DublinCore extends AbstractBase +{ + /** + * Mapping from Dublin Core to VuFind fields + * + * @var array + */ + protected $vocabFieldToGenericFieldsMap = [ + 'DC.citation.epage' => 'endpage', + 'DC.citation.issue' => 'issue', + 'DC.citation.spage' => 'startpage', + 'DC.citation.volume' => 'volume', + 'DC.creator' => 'author', + 'DC.identifier' => ['doi', 'isbn', 'issn'], + 'DC.issued' => 'date', + 'DC.language' => 'language', + 'DC.publisher' => 'publisher', + 'DC.relation.ispartof' => 'container_title', + 'DC.title' => 'title', + ]; +} diff --git a/module/VuFind/src/VuFind/MetadataVocabulary/Eprints.php b/module/VuFind/src/VuFind/MetadataVocabulary/Eprints.php new file mode 100644 index 00000000000..8858bd1e777 --- /dev/null +++ b/module/VuFind/src/VuFind/MetadataVocabulary/Eprints.php @@ -0,0 +1,81 @@ +<?php +/** + * Metadata vocabulary implementation for Eprints + * + * PHP version 7 + * + * Copyright (C) University of Tübingen 2019. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +namespace VuFind\MetadataVocabulary; + +/** + * Metadata vocabulary implementation for Eprints + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class Eprints extends AbstractBase +{ + /** + * Mapping from Eprints to VuFind fields + * + * @var array + */ + protected $vocabFieldToGenericFieldsMap = [ + 'eprints.creators_name' => 'author', + 'eprints.date' => 'date', + 'eprints.issn' => 'issn', + 'eprints.number' => 'volume', + 'eprints.publication' => 'container_title', + 'eprints.publisher' => 'publisher', + 'eprints.title' => 'title', + ]; + + /** + * Special implementation to combine start / end page in eprints.pagerange + * + * @param \VuFind\RecordDriver\AbstractBase $driver Record driver + * + * @return array + */ + public function getMappedData(\VuFind\RecordDriver\AbstractBase $driver) + { + $mappedData = parent::getMappedData($driver); + + // special handling for pagerange + $startpage = $driver->tryMethod('getContainerStartPage'); + + if ($startpage) { + $pagerange = $startpage; + $endpage = $driver->tryMethod('getContainerEndPage'); + if ($endpage != '' && $endpage != $startpage) { + $pagerange = $startpage . '-' . $endpage; + } + $mappedData['eprints.pagerange'] = [$pagerange]; + } + + return $mappedData; + } +} diff --git a/module/VuFind/src/VuFind/MetadataVocabulary/HighwirePress.php b/module/VuFind/src/VuFind/MetadataVocabulary/HighwirePress.php new file mode 100644 index 00000000000..22bb4acc41d --- /dev/null +++ b/module/VuFind/src/VuFind/MetadataVocabulary/HighwirePress.php @@ -0,0 +1,88 @@ +<?php +/** + * Metadata vocabulary implementation for Highwire Press + * + * PHP version 7 + * + * Copyright (C) University of Tübingen 2019. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +namespace VuFind\MetadataVocabulary; + +/** + * Metadata vocabulary implementation for Highwire Press + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class HighwirePress extends AbstractBase +{ + /** + * Mapping from Highwire Press to VuFind fields; see + * https://jira.duraspace.org/secure/attachment/13020/Invisible_institutional.pdf + * + * @var array + */ + protected $vocabFieldToGenericFieldsMap = [ + 'citation_author' => 'author', + 'citation_date' => 'date', + 'citation_doi' => 'doi', + 'citation_firstpage' => 'startpage', + 'citation_isbn' => 'isbn', + 'citation_issn' => 'issn', + 'citation_issue' => 'issue', + 'citation_journal_title' => 'container_title', + 'citation_language' => 'language', + 'citation_lastpage' => 'endpage', + 'citation_publisher' => 'publisher', + 'citation_title' => 'title', + 'citation_volume' => 'volume', + ]; + + /** + * Special implementation for date formats + * + * @param \VuFind\RecordDriver\AbstractBase $driver Record driver + * + * @return array + */ + public function getMappedData(\VuFind\RecordDriver\AbstractBase $driver) + { + $mappedData = parent::getMappedData($driver); + + // special handling for dates + if (isset($mappedData['citation_date'])) { + foreach ($mappedData['citation_date'] as $key => $date) { + // If we only have a year, leave it as-is + // If we have a date, we need to convert to MM-DD-YYYY or MM/DD/YYYY + if (!preg_match('"^\d+$"', $date)) { + $mappedData['citation_date'][$key] + = date('m/d/Y', strtotime($date)); + } + } + } + + return $mappedData; + } +} diff --git a/module/VuFind/src/VuFind/MetadataVocabulary/MetadataVocabularyInterface.php b/module/VuFind/src/VuFind/MetadataVocabulary/MetadataVocabularyInterface.php new file mode 100644 index 00000000000..edb0d94c0d6 --- /dev/null +++ b/module/VuFind/src/VuFind/MetadataVocabulary/MetadataVocabularyInterface.php @@ -0,0 +1,53 @@ +<?php +/** + * Metadata vocabulary interface + * + * PHP version 7 + * + * Copyright (C) University of Tübingen 2019. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +namespace VuFind\MetadataVocabulary; + +/** + * Metadata vocabulary interface + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +interface MetadataVocabularyInterface +{ + /** + * Map data from RecordDriver to this vocabulary. + * + * Note that AbstractBase instead of DefaultRecord is used + * for higher flexibility. That's why all implementations must use + * "tryMethod" instead of calling the methods directly. + * + * @param \VuFind\RecordDriver\AbstractBase $driver Record driver + * + * @return array + */ + public function getMappedData(\VuFind\RecordDriver\AbstractBase $driver); +} diff --git a/module/VuFind/src/VuFind/MetadataVocabulary/PRISM.php b/module/VuFind/src/VuFind/MetadataVocabulary/PRISM.php new file mode 100644 index 00000000000..3c4a9bef6f0 --- /dev/null +++ b/module/VuFind/src/VuFind/MetadataVocabulary/PRISM.php @@ -0,0 +1,55 @@ +<?php +/** + * Metadata vocabulary implementation for PRISM + * + * PHP version 7 + * + * Copyright (C) University of Tübingen 2019. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +namespace VuFind\MetadataVocabulary; + +/** + * Metadata vocabulary implementation for PRISM + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class PRISM extends AbstractBase +{ + /** + * Mapping from Highwire Press to VuFind fields + * see https://www.idealliance.org/prism-metadata + * + * @var array + */ + protected $vocabFieldToGenericFieldsMap = ['prism.doi' => 'doi', + 'prism.endingPage' => 'endpage', + 'prism.isbn' => 'isbn', + 'prism.issn' => 'issn', + 'prism.startingPage' => 'startpage', + 'prism.title' => 'title', + 'prism.volume' => 'volume', + ]; +} diff --git a/module/VuFind/src/VuFind/MetadataVocabulary/PluginFactory.php b/module/VuFind/src/VuFind/MetadataVocabulary/PluginFactory.php new file mode 100644 index 00000000000..aacf5c59968 --- /dev/null +++ b/module/VuFind/src/VuFind/MetadataVocabulary/PluginFactory.php @@ -0,0 +1,48 @@ +<?php +/** + * Metadata vocabulary plugin factory + * + * PHP version 7 + * + * Copyright (C) University of Tübingen 2019. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +namespace VuFind\MetadataVocabulary; + +/** + * Metadata vocabulary plugin factory + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class PluginFactory extends \VuFind\ServiceManager\AbstractPluginFactory +{ + /** + * Constructor + */ + public function __construct() + { + $this->defaultNamespace = 'VuFind\MetadataVocabulary'; + } +} diff --git a/module/VuFind/src/VuFind/MetadataVocabulary/PluginManager.php b/module/VuFind/src/VuFind/MetadataVocabulary/PluginManager.php new file mode 100644 index 00000000000..6bb581a8460 --- /dev/null +++ b/module/VuFind/src/VuFind/MetadataVocabulary/PluginManager.php @@ -0,0 +1,67 @@ +<?php +/** + * Metadata vocabulary plugin manager + * + * PHP version 7 + * + * Copyright (C) University of Tübingen 2019. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +namespace VuFind\MetadataVocabulary; + +/** + * Metadata vocabulary plugin manager + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager +{ + /** + * Constructor + * + * Make sure plugins are properly initialized. + * + * @param mixed $configOrContainerInstance Configuration or container instance + * @param array $v3config If $configOrContainerInstance is a + * container, this value will be passed + * to the parent constructor. + */ + public function __construct($configOrContainerInstance = null, + array $v3config = [] + ) { + $this->addAbstractFactory(PluginFactory::class); + parent::__construct($configOrContainerInstance, $v3config); + } + + /** + * Return the base class or interface that plug-ins must conform to. + * + * @return class + */ + protected function getExpectedInterface() + { + return MetadataVocabularyInterface::class; + } +} diff --git a/module/VuFind/src/VuFind/View/Helper/Root/Metadata.php b/module/VuFind/src/VuFind/View/Helper/Root/Metadata.php new file mode 100644 index 00000000000..5aadeb2a6aa --- /dev/null +++ b/module/VuFind/src/VuFind/View/Helper/Root/Metadata.php @@ -0,0 +1,121 @@ +<?php +/** + * Metadata view helper + * + * PHP version 7 + * + * Copyright (C) University of Tübingen 2019. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +namespace VuFind\View\Helper\Root; + +/** + * Metadata view helper + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class Metadata extends \Zend\View\Helper\AbstractHelper +{ + /** + * Metadata configuration entries + * + * @var \Zend\Config\Config + */ + protected $config; + + /** + * Zend meta helper, used to embed html tags in the generated page + * + * @var \Zend\View\Helper\HeadMeta + */ + protected $metaHelper; + + /** + * Plugin Manager for vocabularies + * + * @var \VuFind\MetadataVocabulary\PluginManager + */ + protected $pluginManager; + + /** + * Constructor + * + * @param \VuFind\MetadataVocabulary\PluginManager $pm Plugin manager + * @param \Zend\Config\Config $config Configuration + * @param \Zend\View\Helper\HeadMeta $metaHelper Head meta helper + */ + public function __construct(\VuFind\MetadataVocabulary\PluginManager $pm, + \Zend\Config\Config $config, + \Zend\View\Helper\HeadMeta $metaHelper + ) { + $this->pluginManager = $pm; + $this->config = $config; + $this->metaHelper = $metaHelper; + } + + /** + * Get all active vocabularies for the current record. + * + * @param \VuFind\RecordDriver\AbstractBase $driver Record driver + * + * @return array + */ + protected function getVocabularies(\VuFind\RecordDriver\AbstractBase $driver) + { + $recordDriverConfigs = isset($this->config->Vocabularies) + ? $this->config->Vocabularies->toArray() : []; + $retVal = []; + foreach ($recordDriverConfigs as $className => $vocabs) { + if ($driver instanceof $className) { + $retVal = array_merge($retVal, $vocabs); + } + } + return array_unique($retVal); + } + + /** + * Generate all metatags for RecordDriver and add to page + * + * Decide which Plugins to load for the given RecordDriver + * dependant on configuration. (only by class name, + * namespace will not be considered) + * + * @param \VuFind\RecordDriver\AbstractBase $driver Record driver + * + * @return void + */ + public function generateMetatags(\VuFind\RecordDriver\AbstractBase $driver) + { + foreach ($this->getVocabularies($driver) as $metatagType) { + $vocabulary = $this->pluginManager->get($metatagType); + $mappedFields = $vocabulary->getMappedData($driver); + foreach ($mappedFields as $field => $values) { + foreach ($values as $value) { + $this->metaHelper->appendName($field, $value); + } + } + } + } +} diff --git a/module/VuFind/src/VuFind/View/Helper/Root/MetadataFactory.php b/module/VuFind/src/VuFind/View/Helper/Root/MetadataFactory.php new file mode 100644 index 00000000000..6c2d2260a49 --- /dev/null +++ b/module/VuFind/src/VuFind/View/Helper/Root/MetadataFactory.php @@ -0,0 +1,68 @@ +<?php +/** + * Metadata helper factory + * + * PHP version 7 + * + * Copyright (C) University of Tübingen 2019. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +namespace VuFind\View\Helper\Root; + +use Interop\Container\ContainerInterface; +use Zend\ServiceManager\Factory\FactoryInterface; + +/** + * Metadata helper factory + * + * @category VuFind + * @package Metadata_Vocabularies + * @author Mario Trojan <mario.trojan@uni-tuebingen.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class MetadataFactory implements FactoryInterface +{ + /** + * Create an object + * + * @param ContainerInterface $container Service Manager + * @param type $requestedName Service being created + * @param null|array $options Extra options (optional) + * + * @return object + * + * @throws \Exception (options not allowed in this implementation) + */ + public function __invoke(ContainerInterface $container, $requestedName, + array $options = null + ) { + if (!empty($options)) { + throw new \Exception('Unexpected options sent to factory.'); + } + + return new Metadata( + $container->get(\VuFind\MetadataVocabulary\PluginManager::class), + $container->get(\VuFind\Config\PluginManager::class)->get('metadata'), + $container->get('ViewHelperManager')->get('HeadMeta') + ); + } +} diff --git a/themes/bootstrap3/templates/RecordDriver/DefaultRecord/core.phtml b/themes/bootstrap3/templates/RecordDriver/DefaultRecord/core.phtml index 2aed4297dd6..b115d2d0193 100644 --- a/themes/bootstrap3/templates/RecordDriver/DefaultRecord/core.phtml +++ b/themes/bootstrap3/templates/RecordDriver/DefaultRecord/core.phtml @@ -1,3 +1,4 @@ +<?php $this->metadata()->generateMetatags($this->driver);?> <div class="media" vocab="http://schema.org/" resource="#record" typeof="<?=$this->driver->getSchemaOrgFormats()?> Product"> <?php $QRCode = $this->record($this->driver)->getQRCode("core"); diff --git a/themes/root/theme.config.php b/themes/root/theme.config.php index f7c837606d6..1818208fc95 100644 --- a/themes/root/theme.config.php +++ b/themes/root/theme.config.php @@ -32,6 +32,7 @@ return [ 'VuFind\View\Helper\Root\KeepAlive' => 'VuFind\View\Helper\Root\KeepAliveFactory', 'VuFind\View\Helper\Root\Linkify' => 'Zend\ServiceManager\Factory\InvokableFactory', 'VuFind\View\Helper\Root\LocalizedNumber' => 'Zend\ServiceManager\Factory\InvokableFactory', + 'VuFind\View\Helper\Root\Metadata' => 'VuFind\View\Helper\Root\MetadataFactory', 'VuFind\View\Helper\Root\OpenUrl' => 'VuFind\View\Helper\Root\OpenUrlFactory', 'VuFind\View\Helper\Root\Overdrive' => 'VuFind\View\Helper\Root\OverdriveFactory', 'VuFind\View\Helper\Root\Permission' => 'VuFind\View\Helper\Root\PermissionFactory', @@ -98,6 +99,7 @@ return [ 'keepAlive' => 'VuFind\View\Helper\Root\KeepAlive', 'linkify' => 'VuFind\View\Helper\Root\Linkify', 'localizedNumber' => 'VuFind\View\Helper\Root\LocalizedNumber', + 'metadata' => 'VuFind\View\Helper\Root\Metadata', 'openUrl' => 'VuFind\View\Helper\Root\OpenUrl', 'overdrive' => 'VuFind\View\Helper\Root\Overdrive', 'permission' => 'VuFind\View\Helper\Root\Permission', -- GitLab