From 1eec255288b4ab72d510b6c117f09fac267b6eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6hr?= Date: Tue, 20 Jun 2023 13:25:17 +0200 Subject: [PATCH 01/14] Replace Zend with Laminas and remove custom PluginManager --- Module.php | 6 +- config/module.config.php | 11 +- .../RecordDriver/PluginFactory.php | 49 ------- .../RecordDriver/PluginManager.php | 128 ------------------ src/RecordDriver/RecordDriver/SolrMarc.php | 16 +-- .../View/Helper/RecordDriver/SolrDetails.php | 2 +- .../RecordDriver/SolrDetailsFactory.php | 2 +- 7 files changed, 20 insertions(+), 194 deletions(-) delete mode 100644 src/RecordDriver/RecordDriver/PluginFactory.php delete mode 100644 src/RecordDriver/RecordDriver/PluginManager.php diff --git a/Module.php b/Module.php index c8cde28..925c311 100644 --- a/Module.php +++ b/Module.php @@ -26,8 +26,8 @@ * @link https://github.com/dmj/vf2-proxy */ namespace RecordDriver; -use Zend\ModuleManager\ModuleManager, - Zend\Mvc\MvcEvent; +use Laminas\ModuleManager\ModuleManager, + Laminas\Mvc\MvcEvent; /** * Template for ZF2 module for storing local overrides. @@ -63,7 +63,7 @@ public function getAutoloaderConfig() # 'minSO' => __DIR__ . '/src/Beluga/Search/minSO.php' # ) # ), - 'Zend\Loader\StandardAutoloader' => array( + 'Laminas\Loader\StandardAutoloader' => array( 'namespaces' => array( __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__, ), diff --git a/config/module.config.php b/config/module.config.php index 663e28b..d3b4772 100644 --- a/config/module.config.php +++ b/config/module.config.php @@ -4,11 +4,14 @@ $config = [ 'service_manager' => [ 'allow_override' => true, - 'factories' => [ - 'RecordDriver\RecordDriver\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory', - ], 'aliases' => [ - 'VuFind\RecordDriver\PluginManager' => 'RecordDriver\RecordDriver\PluginManager', + 'solrmarc' => 'RecordDriver\RecordDriver\SolrMarc' + ], + 'delegators' => [ + 'RecordDriver\RecordDriver\SolrMarc' => 'VuFind\RecordDriver\IlsAwareDelegatorFactory' + ], + 'factories' => [ + 'RecordDriver\RecordDriver\SolrMarc' => 'RecordDriver\RecordDriver\SolrDefaultFactory' ], ], ]; diff --git a/src/RecordDriver/RecordDriver/PluginFactory.php b/src/RecordDriver/RecordDriver/PluginFactory.php deleted file mode 100644 index c3d59b9..0000000 --- a/src/RecordDriver/RecordDriver/PluginFactory.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org/wiki/development:plugins:record_drivers Wiki - */ -namespace RecordDriver\RecordDriver; - -/** - * Record driver plugin factory - * - * @category VuFind - * @package RecordDrivers - * @author Demian Katz - * @author Hajo Seng - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org/wiki/development:plugins:record_drivers Wiki - */ -class PluginFactory extends \VuFind\ServiceManager\AbstractPluginFactory -{ - /** - * Constructor - */ - public function __construct() - { - $this->defaultNamespace = 'RecordDriver\RecordDriver'; - } -} diff --git a/src/RecordDriver/RecordDriver/PluginManager.php b/src/RecordDriver/RecordDriver/PluginManager.php deleted file mode 100644 index 4a29ae0..0000000 --- a/src/RecordDriver/RecordDriver/PluginManager.php +++ /dev/null @@ -1,128 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org/wiki/development:plugins:record_drivers Wiki - */ -namespace RecordDriver\RecordDriver; - -/** - * Record driver plugin manager - * - * @category VuFind - * @package RecordDrivers - * @author Demian Katz - * @author Hajo Seng - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License - * @link https://vufind.org/wiki/development:plugins:record_drivers Wiki - */ -class PluginManager extends \VuFind\RecordDriver\PluginManager -{ - /** - * Default plugin aliases. - * - * @var array - */ - protected $aliases = [ - 'browzine' => 'VuFind\RecordDriver\BrowZine', - 'eds' => 'VuFind\RecordDriver\EDS', - 'eit' => 'VuFind\RecordDriver\EIT', - 'libguides' => 'VuFind\RecordDriver\LibGuides', - 'missing' => 'VuFind\RecordDriver\Missing', - 'pazpar2' => 'VuFind\RecordDriver\Pazpar2', - 'primo' => 'VuFind\RecordDriver\Primo', - 'solrauth' => 'VuFind\RecordDriver\SolrAuthMarc', // legacy name - 'solrauthdefault' => 'VuFind\RecordDriver\SolrAuthDefault', - 'solrauthmarc' => 'VuFind\RecordDriver\SolrAuthMarc', - 'solrdefault' => 'VuFind\RecordDriver\SolrDefault', - 'solrmarc' => 'RecordDriver\RecordDriver\SolrMarc', - 'solrmarcremote' => 'VuFind\RecordDriver\SolrMarcRemote', - 'solrreserves' => 'VuFind\RecordDriver\SolrReserves', - 'solrweb' => 'VuFind\RecordDriver\SolrWeb', - 'summon' => 'VuFind\RecordDriver\Summon', - 'worldcat' => 'VuFind\RecordDriver\WorldCat', - ]; - - /** - * Default delegator factories. - * - * @var string[][]|\Zend\ServiceManager\Factory\DelegatorFactoryInterface[][] - */ - protected $delegators = [ - 'RecordDriver\RecordDriver\SolrMarc' => - ['VuFind\RecordDriver\IlsAwareDelegatorFactory'], - 'VuFind\RecordDriver\SolrMarcRemote' => - ['VuFind\RecordDriver\IlsAwareDelegatorFactory'], - ]; - - /** - * Default plugin factories. - * - * @var array - */ - protected $factories = [ - 'RecordDriver\RecordDriver\SolrMarc' => - 'RecordDriver\RecordDriver\SolrDefaultFactory', - 'VuFind\RecordDriver\BrowZine' => - 'Zend\ServiceManager\Factory\InvokableFactory', - 'VuFind\RecordDriver\EDS' => 'VuFind\RecordDriver\NameBasedConfigFactory', - 'VuFind\RecordDriver\EIT' => 'VuFind\RecordDriver\NameBasedConfigFactory', - 'VuFind\RecordDriver\LibGuides' => - 'Zend\ServiceManager\Factory\InvokableFactory', - 'VuFind\RecordDriver\Missing' => 'VuFind\RecordDriver\AbstractBaseFactory', - 'VuFind\RecordDriver\Pazpar2' => - 'VuFind\RecordDriver\NameBasedConfigFactory', - 'VuFind\RecordDriver\Primo' => 'VuFind\RecordDriver\NameBasedConfigFactory', - 'VuFind\RecordDriver\SolrAuthDefault' => - 'VuFind\RecordDriver\SolrDefaultWithoutSearchServiceFactory', - 'VuFind\RecordDriver\SolrAuthMarc' => - 'VuFind\RecordDriver\SolrDefaultWithoutSearchServiceFactory', - 'VuFind\RecordDriver\SolrDefault' => - 'VuFind\RecordDriver\SolrDefaultFactory', - 'VuFind\RecordDriver\SolrMarcRemote' => - 'VuFind\RecordDriver\SolrDefaultFactory', - 'VuFind\RecordDriver\SolrReserves' => - 'VuFind\RecordDriver\SolrDefaultWithoutSearchServiceFactory', - 'VuFind\RecordDriver\SolrWeb' => 'VuFind\RecordDriver\SolrWebFactory', - 'VuFind\RecordDriver\Summon' => 'VuFind\RecordDriver\SummonFactory', - 'VuFind\RecordDriver\WorldCat' => - 'VuFind\RecordDriver\NameBasedConfigFactory', - ]; - - /** - * 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('RecordDriver\RecordDriver\PluginFactory'); - parent::__construct($configOrContainerInstance, $v3config); - } -} diff --git a/src/RecordDriver/RecordDriver/SolrMarc.php b/src/RecordDriver/RecordDriver/SolrMarc.php index c0231e8..76e410f 100644 --- a/src/RecordDriver/RecordDriver/SolrMarc.php +++ b/src/RecordDriver/RecordDriver/SolrMarc.php @@ -42,8 +42,8 @@ */ class SolrMarc extends SolrDefault { - use \VuFind\RecordDriver\IlsAwareTrait; - use \VuFind\RecordDriver\MarcReaderTrait; + use \VuFind\RecordDriver\Feature\IlsAwareTrait; + use \VuFind\RecordDriver\Feature\MarcReaderTrait; /** * Configuration (yaml) @@ -76,11 +76,11 @@ class SolrMarc extends SolrDefault /** * Constructor * - * @param \Zend\Config\Config $mainConfig VuFind main configuration (omit for + * @param \Laminas\Config\Config $mainConfig VuFind main configuration (omit for * built-in defaults) - * @param \Zend\Config\Config $recordConfig Record-specific configuration file + * @param \Laminas\Config\Config $recordConfig Record-specific configuration file * (omit to use $mainConfig as $recordConfig) - * @param \Zend\Config\Config $searchSettings Search-specific configuration file + * @param \Laminas\Config\Config $searchSettings Search-specific configuration file * @param string $marcYaml */ public function __construct($mainConfig = null, $recordConfig = null, @@ -249,7 +249,7 @@ public function getMarcData($dataName) } } } - foreach ($this->getMarcRecord()->getFields($field) as $index => $fieldObject) { + foreach ($this->getMarcReader()->getFields($field) as $index => $fieldObject) { $data = $indexData; if (!empty($subFieldSpecs['conditions'])) { foreach ($subFieldSpecs['conditions'] as $condition) { @@ -345,7 +345,7 @@ public function getMarcData($dataName) protected function getOriginalLetters() { $originalLetters = []; - if ($fields = $this->getMarcRecord()->getFields('880')) { + if ($fields = $this->getMarcReader()->getFields('880')) { foreach ($fields as $field) { $subfields = $field->getSubfields(); $letters = []; @@ -374,7 +374,7 @@ protected function getOriginalLetters() */ public function getBibliographicLevel() { - $leader = $this->getMarcRecord()->getLeader(); + $leader = $this->getMarcReader()->getLeader(); $biblioLevel = strtoupper($leader[7]); switch ($biblioLevel) { diff --git a/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php b/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php index 658fc0a..64fdcb5 100644 --- a/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php +++ b/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php @@ -27,7 +27,7 @@ */ namespace RecordDriver\View\Helper\RecordDriver; -use Zend\View\Helper\AbstractHelper; +use Laminas\View\Helper\AbstractHelper; use RecordDriver\RecordDriver\SolrMarc as RecordDriver; /** diff --git a/src/RecordDriver/View/Helper/RecordDriver/SolrDetailsFactory.php b/src/RecordDriver/View/Helper/RecordDriver/SolrDetailsFactory.php index 23093fb..a2a5b8e 100644 --- a/src/RecordDriver/View/Helper/RecordDriver/SolrDetailsFactory.php +++ b/src/RecordDriver/View/Helper/RecordDriver/SolrDetailsFactory.php @@ -28,7 +28,7 @@ namespace RecordDriver\View\Helper\RecordDriver; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\FactoryInterface; +use Laminas\ServiceManager\Factory\FactoryInterface; /** * SolrDetails helper factory. From 677a8d034dfdacd07985e3310823cbdd3b8c0f3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6hr?= Date: Wed, 21 Jun 2023 13:17:17 +0200 Subject: [PATCH 02/14] Remove unnecessary function --- .../Search/Factory/SolrDefaultBackendFactory.php | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/RecordDriver/Search/Factory/SolrDefaultBackendFactory.php b/src/RecordDriver/Search/Factory/SolrDefaultBackendFactory.php index 2418877..69d864d 100644 --- a/src/RecordDriver/Search/Factory/SolrDefaultBackendFactory.php +++ b/src/RecordDriver/Search/Factory/SolrDefaultBackendFactory.php @@ -52,20 +52,4 @@ public function __construct() { parent::__construct(); } - - /** - * Create the SOLR backend. - * - * @param Connector $connector Connector - * - * @return Backend - */ - protected function createBackend(Connector $connector) - { - $backend = AbstractSolrBackendFactory::createBackend($connector); - $manager = $this->serviceLocator->get('RecordDriver\RecordDriver\PluginManager'); - $factory = new RecordCollectionFactory([$manager, 'getSolrRecord']); - $backend->setRecordCollectionFactory($factory); - return $backend; - } } From 2736b280f220dea42f944de5e2e0e08a257441a0 Mon Sep 17 00:00:00 2001 From: vhost vufind 9 hcu Date: Tue, 11 Jul 2023 16:22:27 +0200 Subject: [PATCH 03/14] Update permissions --- .idea/.gitignore | 0 .idea/RecordDriver.iml | 0 .idea/google-java-format.xml | 0 .idea/modules.xml | 0 .idea/php.xml | 0 .idea/vcs.xml | 0 Module.php | 0 README.md | 0 composer.json | 0 config/module.config.php | 0 src/RecordDriver/RecordDriver/SolrMarc.php | 0 src/RecordDriver/Search/BackendRegistry.php | 0 src/RecordDriver/Search/Factory/Search2BackendFactory.php | 0 src/RecordDriver/Search/Factory/SolrDefaultBackendFactory.php | 0 src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php | 0 src/RecordDriver/View/Helper/RecordDriver/SolrDetailsFactory.php | 0 theme/mixin.config.php | 0 theme/templates/RecordDriver/SolrDefault/link-bkl.phtml | 0 theme/templates/RecordDriver/SolrDefault/link-class.phtml | 0 theme/templates/RecordDriver/SolrDefault/link-detail.phtml | 0 theme/templates/RecordDriver/SolrDefault/link-isn.phtml | 0 theme/templates/RecordDriver/SolrDefault/link-issnj.phtml | 0 theme/templates/RecordDriver/SolrDefault/link-person.phtml | 0 theme/templates/RecordDriver/SolrDefault/link-ppn.phtml | 0 theme/templates/RecordDriver/SolrDefault/link-rvk.phtml | 0 theme/templates/RecordDriver/SolrDefault/link-search.phtml | 0 theme/templates/RecordDriver/SolrDefault/link-subject.phtml | 0 theme/templates/RecordDriver/SolrDefault/link-zdb.phtml | 0 .../RecordDriver/SolrDefault/recorddriver-core-data.phtml | 0 .../RecordDriver/SolrDefault/recorddriver-core-title.phtml | 0 .../RecordDriver/SolrDefault/recorddriver-result-list.phtml | 0 theme/templates/RecordDriver/SolrDefault/template-rvk.phtml | 0 32 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .idea/.gitignore mode change 100644 => 100755 .idea/RecordDriver.iml mode change 100644 => 100755 .idea/google-java-format.xml mode change 100644 => 100755 .idea/modules.xml mode change 100644 => 100755 .idea/php.xml mode change 100644 => 100755 .idea/vcs.xml mode change 100644 => 100755 Module.php mode change 100644 => 100755 README.md mode change 100644 => 100755 composer.json mode change 100644 => 100755 config/module.config.php mode change 100644 => 100755 src/RecordDriver/RecordDriver/SolrMarc.php mode change 100644 => 100755 src/RecordDriver/Search/BackendRegistry.php mode change 100644 => 100755 src/RecordDriver/Search/Factory/Search2BackendFactory.php mode change 100644 => 100755 src/RecordDriver/Search/Factory/SolrDefaultBackendFactory.php mode change 100644 => 100755 src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php mode change 100644 => 100755 src/RecordDriver/View/Helper/RecordDriver/SolrDetailsFactory.php mode change 100644 => 100755 theme/mixin.config.php mode change 100644 => 100755 theme/templates/RecordDriver/SolrDefault/link-bkl.phtml mode change 100644 => 100755 theme/templates/RecordDriver/SolrDefault/link-class.phtml mode change 100644 => 100755 theme/templates/RecordDriver/SolrDefault/link-detail.phtml mode change 100644 => 100755 theme/templates/RecordDriver/SolrDefault/link-isn.phtml mode change 100644 => 100755 theme/templates/RecordDriver/SolrDefault/link-issnj.phtml mode change 100644 => 100755 theme/templates/RecordDriver/SolrDefault/link-person.phtml mode change 100644 => 100755 theme/templates/RecordDriver/SolrDefault/link-ppn.phtml mode change 100644 => 100755 theme/templates/RecordDriver/SolrDefault/link-rvk.phtml mode change 100644 => 100755 theme/templates/RecordDriver/SolrDefault/link-search.phtml mode change 100644 => 100755 theme/templates/RecordDriver/SolrDefault/link-subject.phtml mode change 100644 => 100755 theme/templates/RecordDriver/SolrDefault/link-zdb.phtml mode change 100644 => 100755 theme/templates/RecordDriver/SolrDefault/recorddriver-core-data.phtml mode change 100644 => 100755 theme/templates/RecordDriver/SolrDefault/recorddriver-core-title.phtml mode change 100644 => 100755 theme/templates/RecordDriver/SolrDefault/recorddriver-result-list.phtml mode change 100644 => 100755 theme/templates/RecordDriver/SolrDefault/template-rvk.phtml diff --git a/.idea/.gitignore b/.idea/.gitignore old mode 100644 new mode 100755 diff --git a/.idea/RecordDriver.iml b/.idea/RecordDriver.iml old mode 100644 new mode 100755 diff --git a/.idea/google-java-format.xml b/.idea/google-java-format.xml old mode 100644 new mode 100755 diff --git a/.idea/modules.xml b/.idea/modules.xml old mode 100644 new mode 100755 diff --git a/.idea/php.xml b/.idea/php.xml old mode 100644 new mode 100755 diff --git a/.idea/vcs.xml b/.idea/vcs.xml old mode 100644 new mode 100755 diff --git a/Module.php b/Module.php old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/composer.json b/composer.json old mode 100644 new mode 100755 diff --git a/config/module.config.php b/config/module.config.php old mode 100644 new mode 100755 diff --git a/src/RecordDriver/RecordDriver/SolrMarc.php b/src/RecordDriver/RecordDriver/SolrMarc.php old mode 100644 new mode 100755 diff --git a/src/RecordDriver/Search/BackendRegistry.php b/src/RecordDriver/Search/BackendRegistry.php old mode 100644 new mode 100755 diff --git a/src/RecordDriver/Search/Factory/Search2BackendFactory.php b/src/RecordDriver/Search/Factory/Search2BackendFactory.php old mode 100644 new mode 100755 diff --git a/src/RecordDriver/Search/Factory/SolrDefaultBackendFactory.php b/src/RecordDriver/Search/Factory/SolrDefaultBackendFactory.php old mode 100644 new mode 100755 diff --git a/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php b/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php old mode 100644 new mode 100755 diff --git a/src/RecordDriver/View/Helper/RecordDriver/SolrDetailsFactory.php b/src/RecordDriver/View/Helper/RecordDriver/SolrDetailsFactory.php old mode 100644 new mode 100755 diff --git a/theme/mixin.config.php b/theme/mixin.config.php old mode 100644 new mode 100755 diff --git a/theme/templates/RecordDriver/SolrDefault/link-bkl.phtml b/theme/templates/RecordDriver/SolrDefault/link-bkl.phtml old mode 100644 new mode 100755 diff --git a/theme/templates/RecordDriver/SolrDefault/link-class.phtml b/theme/templates/RecordDriver/SolrDefault/link-class.phtml old mode 100644 new mode 100755 diff --git a/theme/templates/RecordDriver/SolrDefault/link-detail.phtml b/theme/templates/RecordDriver/SolrDefault/link-detail.phtml old mode 100644 new mode 100755 diff --git a/theme/templates/RecordDriver/SolrDefault/link-isn.phtml b/theme/templates/RecordDriver/SolrDefault/link-isn.phtml old mode 100644 new mode 100755 diff --git a/theme/templates/RecordDriver/SolrDefault/link-issnj.phtml b/theme/templates/RecordDriver/SolrDefault/link-issnj.phtml old mode 100644 new mode 100755 diff --git a/theme/templates/RecordDriver/SolrDefault/link-person.phtml b/theme/templates/RecordDriver/SolrDefault/link-person.phtml old mode 100644 new mode 100755 diff --git a/theme/templates/RecordDriver/SolrDefault/link-ppn.phtml b/theme/templates/RecordDriver/SolrDefault/link-ppn.phtml old mode 100644 new mode 100755 diff --git a/theme/templates/RecordDriver/SolrDefault/link-rvk.phtml b/theme/templates/RecordDriver/SolrDefault/link-rvk.phtml old mode 100644 new mode 100755 diff --git a/theme/templates/RecordDriver/SolrDefault/link-search.phtml b/theme/templates/RecordDriver/SolrDefault/link-search.phtml old mode 100644 new mode 100755 diff --git a/theme/templates/RecordDriver/SolrDefault/link-subject.phtml b/theme/templates/RecordDriver/SolrDefault/link-subject.phtml old mode 100644 new mode 100755 diff --git a/theme/templates/RecordDriver/SolrDefault/link-zdb.phtml b/theme/templates/RecordDriver/SolrDefault/link-zdb.phtml old mode 100644 new mode 100755 diff --git a/theme/templates/RecordDriver/SolrDefault/recorddriver-core-data.phtml b/theme/templates/RecordDriver/SolrDefault/recorddriver-core-data.phtml old mode 100644 new mode 100755 diff --git a/theme/templates/RecordDriver/SolrDefault/recorddriver-core-title.phtml b/theme/templates/RecordDriver/SolrDefault/recorddriver-core-title.phtml old mode 100644 new mode 100755 diff --git a/theme/templates/RecordDriver/SolrDefault/recorddriver-result-list.phtml b/theme/templates/RecordDriver/SolrDefault/recorddriver-result-list.phtml old mode 100644 new mode 100755 diff --git a/theme/templates/RecordDriver/SolrDefault/template-rvk.phtml b/theme/templates/RecordDriver/SolrDefault/template-rvk.phtml old mode 100644 new mode 100755 From a7f75c7e42073659edab7525eb33f510bad1fa90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6hr?= Date: Tue, 11 Jul 2023 16:22:35 +0200 Subject: [PATCH 04/14] Update SolrDetails --- .../View/Helper/RecordDriver/SolrDetails.php | 275 +++++++++++++++++- .../AbstractClassBasedTemplateRenderer.php | 119 ++++++++ 2 files changed, 384 insertions(+), 10 deletions(-) create mode 100644 src/RecordDriver/View/Helper/Root/AbstractClassBasedTemplateRenderer.php diff --git a/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php b/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php index 64fdcb5..346c167 100644 --- a/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php +++ b/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php @@ -27,8 +27,8 @@ */ namespace RecordDriver\View\Helper\RecordDriver; -use Laminas\View\Helper\AbstractHelper; use RecordDriver\RecordDriver\SolrMarc as RecordDriver; +use RecordDriver\View\Helper\Root\AbstractClassBasedTemplateRenderer; /** * SolrDetails helpers @@ -39,8 +39,17 @@ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development Wiki */ -class SolrDetails extends AbstractHelper +class SolrDetails extends AbstractClassBasedTemplateRenderer { + + + protected $driver; + + protected $separatorSet = [ + [', ', ' / ', ' - '], + [', ', ' ', ' '] + ]; + /** * Get the core field entries * @@ -49,20 +58,266 @@ class SolrDetails extends AbstractHelper * * @return array */ -public function getCoreFields(RecordDriver $driver, $categories = []) + public function getCoreFields(RecordDriver $driver, $categories = []) { + $this->driver = $driver; $solrMarcData = []; - if (!empty($categories)) { - foreach ($categories as $category) { - foreach ($driver->getSolrMarcKeys($category) as $solrMarcKey) { - $solrMarcData[$solrMarcKey] = $driver->getMarcData($solrMarcKey); + if (empty($categories)) { + $categories = [[]]; + } + foreach ($categories as $category) { + foreach ($driver->getSolrMarcKeys($category) as $solrMarcKey) { + $solrMarcData[$solrMarcKey] = $driver->getMarcData($solrMarcKey); + if (empty($solrMarcData[$solrMarcKey])) { + continue; + } + $viewMethod = $solrMarcData[$solrMarcKey]['view-method'] ?? ''; + unset($solrMarcData[$solrMarcKey]['view-method']); + $matchKey = $solrMarcData[$solrMarcKey]['match-key'] ?? ''; + unset($solrMarcData[$solrMarcKey]['match-key']); + if (!empty($matchKey)) { + foreach ($solrMarcData[$solrMarcKey] as $index => $data) { + if (!empty($data[$matchKey]['data'][0])) { + foreach ($solrMarcData[$solrMarcKey] as $index2 => $data2) { + if ($index2 > $index && !empty($data2[$matchKey]['data'][0]) && $data2[$matchKey]['data'][0] == $data[$matchKey]['data'][0]) { + foreach ($solrMarcData[$solrMarcKey][$index2] as $name => $entry) { + $solrMarcData[$solrMarcKey][$index][$name] = $entry; + } + unset($solrMarcData[$solrMarcKey][$index2]); + } + } + } + } + } + $originalLetters = ''; + foreach ($solrMarcData[$solrMarcKey] as $data) { + foreach ($data as $date) { + if (isset($date['originalLetters'])) { + $originalLetters .= ' ' . $date['originalLetters']; + } + } + } + $templateData = []; + if (strpos($viewMethod, '-link') > 0) { + list($key, , $separators) = explode('-', $viewMethod); + if (empty($separators)) { + $separators = 0; + } + $templateData = $this->makeLink($solrMarcData[$solrMarcKey], $key, $separators); + } elseif ($viewMethod == 'directlink') { + foreach ($solrMarcData[$solrMarcKey] as $data) { + $templateData[] = $this->makeDirectLink($data); + } + } elseif ($viewMethod == 'chain') { + $templateData = $this->makeChain($solrMarcData[$solrMarcKey]); + } elseif (strpos($viewMethod, '-template') > 0) { + list($key, , $separators) = explode('-', $viewMethod); + if (empty($separators)) { + $separators = 0; + } + $templateData[] = $this->makeTemplate($solrMarcData[$solrMarcKey], $key, $separators); + } else { + foreach ($solrMarcData[$solrMarcKey] as $data) { + $templateData[] = $this->makeText($data); + } } + $solrMarcData[$solrMarcKey] = array_unique($templateData); + if (!empty($originalLetters)) { + $solrMarcData[$solrMarcKey]['originalLetters'] = $originalLetters; + } + } + } + return $solrMarcData; + } + + public function getResultListLine(RecordDriver $driver) { + $resultList = []; + $resultListData = $driver->getMarcData('ResultList'); + if (is_array($resultListData)) { + foreach ($resultListData as $resultListDate) { + if (is_array($resultListDate)) { + foreach ($resultListDate as $resultKey => $resultListArray) { + if(strpos($resultKey,"_array") !== false) { + if (isset($resultListArray['data'][0])) { + $resultList[$resultKey][] = $resultListArray['data'][0]; + } + } else { + if (!isset($resultList[$resultKey]) && isset($resultListArray['data'][0])) { + $resultList[$resultKey] = $resultListArray['data'][0]; + } + } + } + } + } + } + if (empty($resultList['title'])) { + $resultList['title'] = $this->view->transEsc('no title'); + } + return $resultList; + } + + private function makeLink($solrMarcData, $key, $separators = 0) { + $prefixes = $links = $linknames = $descriptions = $additionals = []; + list($sep0, $sep1, $sep2) = $this->separatorSet[$separators]; + foreach ($solrMarcData as $index => $data) { + if (!empty($data['link'])) { + if (!empty($data['prefix'])) { + $prefixes[$index] = implode(' ', $data['prefix']['data']); + unset($data['prefix']); + } + $links[$index] = implode($sep0, $data['link']['data']); + unset($data['link']); + } + if (!empty($data['prefix'])) { + unset($data['prefix']); + } + if (!empty($data['linkname'])) { + $linknames[$index] = implode($sep1, $data['linkname']['data']); + unset($data['linkname']); + } + if (!isset($links[$index]) && $index > 0) { + $index--; + } + if (!empty($data['description'])) { + $descriptions[$index] = implode($sep0, $data['description']['data']); + unset($data['description']); + } + $additional = []; + foreach ($data as $item => $date) { + $additional[] = implode($sep0, $date['data']); + } + if (!empty($additional) && empty($additionals[$index])) { + $additionals[$index] = $additional; + } + } + if (count($links) == 1) { + $prefixes = array_values($prefixes); + $links = array_values($links); + $linknames = array_values($linknames); + $descriptions = array_values($descriptions); + $additionals = array_values($additionals); + } + $strings = []; + foreach ($links as $index => $link) { + if (!empty($prefixes[$index])) { + $string = $prefixes[$index] . ': '; + } else { + $string = ''; + } + if (!empty($linknames[$index])) { + $linkname = $linknames[$index]; + } else { + $linkname = $link; + } + $string .= '' . $linkname . ''; + if (!empty($additionals[$index])) { + $additional = $additionals[$index]; + $string .= $sep2 . implode($sep0, $additional); } + if (!empty($descriptions[$index])) { + $string .= ' [' . $descriptions[$index] . ']'; + } + $strings[] = $string; + } + return $strings; + } + + private function makeDirectLink($data, $separator = ', ') { + if (empty($data['link'])) { + return ''; + } + $link = array_shift($data['link']['data']); + if (!empty($data['linkname'])) { + $linkname = array_shift($data['linkname']['data']); } else { - foreach ($driver->getSolrMarcKeys([], false) as $solrMarcKey) { - $solrMarcData[$solrMarcKey] = $driver->getMarcData($solrMarcKey); + $linkname = $link; + } + $string = '' . $linkname . ''; + $additionalData = []; + foreach ($data as $item => $date) { + if ($item != 'link' && $item != 'linkname' && $item != 'description') { + $additionalData[] = implode($separator, $date['data']); } } - return $solrMarcData; + if (!empty($additionalData)) { + $string .= ' (' . implode($separator, $additionalData) . ')'; + } + if (!empty($data['description']['data'])) { + $string .= ' [' . implode($separator, $data['description']['data']) . ']'; + } + return $string; + } + + private function makeChain($solrMarcData, $separator = ' / ') { + $result = $items = $links = $sequences = $descriptions = []; + foreach ($solrMarcData as $index => $data) { + $links[$index] = implode(', ', $data['link']['data']); + $sequences[$index] = intval($data['sequence']['data'][0]); + if (!empty($data['description']['data'])) { + $descriptions[$index] = implode(', ', $data['description']['data']); + } + } + foreach ($links as $index => $link) { + if (!empty($items) && $sequences[$index] == 0) { + $result[] = implode($separator, $items); + $items = []; + } + $item = '' . $link . ''; + if (!empty($descriptions[$index])) { + if (is_array($descriptions[$index])) { + $item .= ' [' . implode(', ', $descriptions[$index]) . ']'; + } else { + $item .= ' [' . $descriptions[$index] . ']'; + } + } + $items[] = $item; + } + $result[] = implode($separator, $items); + return $result; + } + + private function makeText($data, $separator = ' ; ') { + $string = ''; + foreach ($data as $key => $date) { + $translatedData = []; + foreach ($date['data'] as $value) { + $translatedData[] = $this->view->transEsc($value); + } + if ($key === 'description') { + $string .= ' [' . implode($separator, $translatedData) . ']'; + } elseif ($key === 'prefix') { + $string = implode(' ', $translatedData) . ': ' . $string; + } else { + $string .= implode($separator, $translatedData) . $separator; + } + } + return preg_replace('/(' . $separator . '|: )$/', '', $string); + } + + /** + * Render the link of the specified type. + * + * @param string $type Link type + * @param string $lookfor String to search for at link + * + * @return string + */ + private function getLink($type, $lookfor) + { + $template = 'RecordDriver/%s/' . 'link-' . $type . '.phtml'; + $className = get_class($this->driver); + $link = $this->renderClassTemplate( + $template, $className, ['driver' => $this->driver, 'lookfor' => $lookfor] + ); + return $link; + } + + private function makeTemplate($solrMarcData, $key) + { + $template = 'RecordDriver/%s/' . 'template-' . $key . '.phtml'; + $className = get_class($this->driver); + return $this->renderClassTemplate( + $template, $className, ['solrMarcData' => $solrMarcData] + ); } } diff --git a/src/RecordDriver/View/Helper/Root/AbstractClassBasedTemplateRenderer.php b/src/RecordDriver/View/Helper/Root/AbstractClassBasedTemplateRenderer.php new file mode 100644 index 0000000..02feb96 --- /dev/null +++ b/src/RecordDriver/View/Helper/Root/AbstractClassBasedTemplateRenderer.php @@ -0,0 +1,119 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +namespace RecordDriver\View\Helper\Root; + +use Laminas\View\Exception\RuntimeException; +use Laminas\View\Helper\AbstractHelper; + +/** + * Authentication view helper + * + * @category VuFind + * @package View_Helpers + * @author Demian Katz + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +abstract class AbstractClassBasedTemplateRenderer extends AbstractHelper +{ + /** + * Recursively locate and render a template that matches the provided class + * name (or one of its parent classes); throw an exception if no match is + * found. + * + * @param string $template Template path (with %s as class name placeholder) + * @param string $className Name of class to apply to template. + * @param string $topClassName Top-level parent class of $className (or null + * if $className is already the top level; used for recursion only). + * + * @return string + * @throws RuntimeException + */ + protected function resolveClassTemplate($template, $className, + $topClassName = null + ) { + // If the template resolves, we can render it! + $templateWithClass = sprintf($template, $this->getBriefClass($className)); + if ($this->getView()->resolver()->resolve($templateWithClass)) { + return $this->getView()->render($templateWithClass); + } + + // If the template doesn't resolve, let's see if we can inherit a + // template from a parent class: + $parentClass = get_parent_class($className); + if (empty($parentClass)) { + // No more parent classes left to try? Throw an exception! + throw new RuntimeException( + 'Cannot find ' . $templateWithClass . ' template for class: ' + . ($topClassName ?? $className) + ); + } + + // Recurse until we find a template or run out of parents... + return $this->resolveClassTemplate( + $template, $parentClass, $topClassName ?? $className + ); + } + + /** + * Render a template associated with the provided class name, applying to + * specified context variables. + * + * @param string $template Template path (with %s as class name placeholder) + * @param string $className Name of class to apply to template. + * @param array $context Context for rendering template + * + * @return string + */ + protected function renderClassTemplate($template, $className, $context = []) + { + // Set up the needed context in the view: + $contextHelper = $this->getView()->plugin('context'); + $oldContext = $contextHelper($this->getView())->apply($context); + + // Render the template for the current class: + $html = $this->resolveClassTemplate($template, $className); + + // Restore the original context before returning the result: + $contextHelper($this->getView())->restore($oldContext); + return $html; + } + + /** + * Helper to grab the end of the class name + * + * @param string $className Class name to abbreviate + * + * @return string + */ + protected function getBriefClass($className) + { + $classParts = explode('\\', $className); + return array_pop($classParts); + } +} From 1357cba30edc562f6858d865213d954df0483dda Mon Sep 17 00:00:00 2001 From: vhost vufind 9 hcu Date: Wed, 12 Jul 2023 08:58:17 +0200 Subject: [PATCH 05/14] Update module --- .../View/Helper/Root/AbstractClassBasedTemplateRenderer.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 src/RecordDriver/View/Helper/Root/AbstractClassBasedTemplateRenderer.php diff --git a/src/RecordDriver/View/Helper/Root/AbstractClassBasedTemplateRenderer.php b/src/RecordDriver/View/Helper/Root/AbstractClassBasedTemplateRenderer.php old mode 100644 new mode 100755 From 87debbe57cc204a7144b460b936aea190e03efeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6hr?= Date: Wed, 12 Jul 2023 11:36:59 +0200 Subject: [PATCH 06/14] Update themes and fix bugs --- src/RecordDriver/RecordDriver/SolrMarc.php | 6 +++--- .../RecordDriver/SolrDefault/recorddriver-result-list.phtml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/RecordDriver/RecordDriver/SolrMarc.php b/src/RecordDriver/RecordDriver/SolrMarc.php index 76e410f..ff1c661 100755 --- a/src/RecordDriver/RecordDriver/SolrMarc.php +++ b/src/RecordDriver/RecordDriver/SolrMarc.php @@ -293,9 +293,9 @@ public function getMarcData($dataName) $indicator = substr($subfield, 9, 1); $fieldData[] = $fieldObject->getIndicator($indicator); } else { - foreach ($fieldObject->getSubfields() as $subFieldObject) { - if ($subFieldObject->getCode() == $subfield) { - $fieldData[] = $subFieldObject->getData(); + foreach ($fieldObject['subfields'] as $subFieldObject) { + if ($subFieldObject['code'] == $subfield) { + $fieldData[] = $subFieldObject['data']; } } } diff --git a/theme/templates/RecordDriver/SolrDefault/recorddriver-result-list.phtml b/theme/templates/RecordDriver/SolrDefault/recorddriver-result-list.phtml index c222bb3..d3c9250 100755 --- a/theme/templates/RecordDriver/SolrDefault/recorddriver-result-list.phtml +++ b/theme/templates/RecordDriver/SolrDefault/recorddriver-result-list.phtml @@ -1,6 +1,6 @@ solrDetails()->getResultListLine($this->driver); ?>
- + : From 84f7b9de1ef75877da527bb789112d716f7c9cb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6hr?= Date: Wed, 12 Jul 2023 16:33:56 +0200 Subject: [PATCH 07/14] Fix bugs in RecordDriver --- src/RecordDriver/RecordDriver/SolrMarc.php | 6 ++-- .../View/Helper/RecordDriver/SolrDetails.php | 35 ++++++++++++++----- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/RecordDriver/RecordDriver/SolrMarc.php b/src/RecordDriver/RecordDriver/SolrMarc.php index ff1c661..e936b5c 100755 --- a/src/RecordDriver/RecordDriver/SolrMarc.php +++ b/src/RecordDriver/RecordDriver/SolrMarc.php @@ -254,11 +254,11 @@ public function getMarcData($dataName) if (!empty($subFieldSpecs['conditions'])) { foreach ($subFieldSpecs['conditions'] as $condition) { if ($condition[0] == 'indicator') { - if ($fieldObject->getIndicator($condition[1]) != $condition[2]) { + if ($fieldObject['i'.$condition[1]] != $condition[2]) { // get indicator continue 2; } } elseif ($condition[0] == 'field') { - $subField = $fieldObject->getSubfield($condition[1]); + $subField = $fieldObject['subfields'][$condition[1]]; if (!is_object($subField) || ($subField->getData() != $condition[2] && $condition[2] != '*')) { continue 2; } @@ -291,7 +291,7 @@ public function getMarcData($dataName) $fieldData = []; if (strpos($subfield, 'indicator') !== false) { $indicator = substr($subfield, 9, 1); - $fieldData[] = $fieldObject->getIndicator($indicator); + $fieldData[] = $fieldObject['i'.$indicator]; } else { foreach ($fieldObject['subfields'] as $subFieldObject) { if ($subFieldObject['code'] == $subfield) { diff --git a/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php b/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php index 346c167..9c12f49 100755 --- a/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php +++ b/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php @@ -91,9 +91,11 @@ public function getCoreFields(RecordDriver $driver, $categories = []) } $originalLetters = ''; foreach ($solrMarcData[$solrMarcKey] as $data) { - foreach ($data as $date) { - if (isset($date['originalLetters'])) { - $originalLetters .= ' ' . $date['originalLetters']; + if (is_array($data)) { + foreach ($data as $date) { + if (isset($date['originalLetters'])) { + $originalLetters .= ' ' . $date['originalLetters']; + } } } } @@ -118,6 +120,15 @@ public function getCoreFields(RecordDriver $driver, $categories = []) $templateData[] = $this->makeTemplate($solrMarcData[$solrMarcKey], $key, $separators); } else { foreach ($solrMarcData[$solrMarcKey] as $data) { + if (!is_array($data)) { + $data = [['data' => $data]]; + } else { + foreach ($data as $key => $date) { + if (!is_array($date)) { + $data[$key] = ['data' => $date]; + } + } + } $templateData[] = $this->makeText($data); } } @@ -138,12 +149,12 @@ public function getResultListLine(RecordDriver $driver) { if (is_array($resultListDate)) { foreach ($resultListDate as $resultKey => $resultListArray) { if(strpos($resultKey,"_array") !== false) { - if (isset($resultListArray['data'][0])) { - $resultList[$resultKey][] = $resultListArray['data'][0]; + if (isset($resultListArray['data'])) { + $resultList[$resultKey][] = $resultListArray['data']; } } else { - if (!isset($resultList[$resultKey]) && isset($resultListArray['data'][0])) { - $resultList[$resultKey] = $resultListArray['data'][0]; + if (!isset($resultList[$resultKey]) && isset($resultListArray['data'])) { + $resultList[$resultKey] = $resultListArray['data']; } } } @@ -280,8 +291,14 @@ private function makeText($data, $separator = ' ; ') { $string = ''; foreach ($data as $key => $date) { $translatedData = []; - foreach ($date['data'] as $value) { - $translatedData[] = $this->view->transEsc($value); + if (is_array($date['data'])) { + foreach ($date['data'] as $value) { + $translatedData[] = $this->view->transEsc($value); + } + } else { + foreach ($date as $value) { + $translatedData[] = $this->view->transEsc($value); + } } if ($key === 'description') { $string .= ' [' . implode($separator, $translatedData) . ']'; From 318362c1dda77233c80f5a73b21cd0aea52dc8f4 Mon Sep 17 00:00:00 2001 From: Johannes Schultze Date: Mon, 17 Jul 2023 14:56:09 +0200 Subject: [PATCH 08/14] Umstellung RecordDriver Object -> Array. --- config/module.config.php | 17 + .../RecordDriver/SolrDefaultFactory.php | 68 +++ src/RecordDriver/RecordDriver/SolrMarc.php | 395 ++++++++++++++---- 3 files changed, 393 insertions(+), 87 deletions(-) create mode 100644 src/RecordDriver/RecordDriver/SolrDefaultFactory.php diff --git a/config/module.config.php b/config/module.config.php index d3b4772..ef31905 100755 --- a/config/module.config.php +++ b/config/module.config.php @@ -14,6 +14,23 @@ 'RecordDriver\RecordDriver\SolrMarc' => 'RecordDriver\RecordDriver\SolrDefaultFactory' ], ], + 'vufind' => [ + 'plugin_managers' => [ + 'recorddriver' => [ + 'factories' => [ + 'RecordDriver\RecordDriver\SolrMarc' => 'RecordDriver\RecordDriver\SolrDefaultFactory', + ], + 'aliases' => [ + 'VuFind\RecordDriver\SolrMarc' => 'RecordDriver\RecordDriver\SolrMarc', + ], + 'delegators' => [ + 'RecordDriver\RecordDriver\SolrMarc' => [ + 0 => 'VuFind\RecordDriver\IlsAwareDelegatorFactory', + ], + ], + ], + ], + ], ]; return $config; diff --git a/src/RecordDriver/RecordDriver/SolrDefaultFactory.php b/src/RecordDriver/RecordDriver/SolrDefaultFactory.php new file mode 100644 index 0000000..d10f00d --- /dev/null +++ b/src/RecordDriver/RecordDriver/SolrDefaultFactory.php @@ -0,0 +1,68 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +namespace RecordDriver\RecordDriver; + +use Interop\Container\ContainerInterface; +use VuFind\RecordDriver\AbstractBaseFactory; + +/** + * Factory for SolrDefault record drivers. + * + * @category VuFind + * @package RecordDrivers + * @author Demian Katz + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class SolrDefaultFactory extends AbstractBaseFactory +{ + /** + * Create an object + * + * @param ContainerInterface $container Service manager + * @param string $requestedName Service being created + * @param null|array $options Extra options (optional) + * + * @return object + * + * @throws ServiceNotFoundException if unable to resolve the service. + * @throws ServiceNotCreatedException if an exception is raised when + * creating a service. + * @throws ContainerException if any other error occurs + */ + public function __invoke(ContainerInterface $container, $requestedName, + array $options = null + ) { + $searchConfig = $container->get('VuFind\Config\PluginManager')->get('searches'); + $solrMarcYaml = 'solrmarc.yaml'; + $finalOptions = [null, $searchConfig, $solrMarcYaml]; + $driver = parent::__invoke($container, $requestedName, $finalOptions); + $driver->attachSearchService($container->get('VuFindSearch\Service')); + return $driver; + } +} diff --git a/src/RecordDriver/RecordDriver/SolrMarc.php b/src/RecordDriver/RecordDriver/SolrMarc.php index e936b5c..47f4472 100755 --- a/src/RecordDriver/RecordDriver/SolrMarc.php +++ b/src/RecordDriver/RecordDriver/SolrMarc.php @@ -44,20 +44,21 @@ class SolrMarc extends SolrDefault { use \VuFind\RecordDriver\Feature\IlsAwareTrait; use \VuFind\RecordDriver\Feature\MarcReaderTrait; + use \VuFind\RecordDriver\Feature\MarcAdvancedTrait; /** - * Configuration (yaml) + * actual Configuration (yaml) * * @var string */ - protected $solrMarcYaml = 'solrmarc.yaml'; + protected $solrMarcYamls = []; /** * Specifications to use * * @var array */ - protected $solrMarcSpecs; + protected $solrMarcSpecs = []; /** * Data in original letters @@ -84,25 +85,40 @@ class SolrMarc extends SolrDefault * @param string $marcYaml */ public function __construct($mainConfig = null, $recordConfig = null, - $searchSettings = null, $marcYaml = null + $searchSettings = null, $solrMarcYaml = null ) { - if (!empty($marcYaml)) { - $this->$solrMarcYaml = $marcYaml; - } + $this->addSolrMarcYaml($solrMarcYaml, false); parent::__construct($mainConfig, $recordConfig, $searchSettings); } + /** + * Set and parse SolrMarcSpecs config. + * + * @return void + */ + public function addSolrMarcYaml($solrMarcYaml, $parse = true) + { + if (!in_array($solrMarcYaml, $this->solrMarcYamls)) { + $this->solrMarcYamls[] = $solrMarcYaml; + if ($parse) { + $this->parseSolrMarcSpecs($solrMarcYaml); + } + } + } + /** * Get and parse SolrMarcSpecs config. * * @return array */ - private function getSolrMarcSpecs($item) + public function getSolrMarcSpecs($item) { if (empty($this->solrMarcSpecs)) { - $this->parseSolrMarcSpecs(); + foreach ($this->solrMarcYamls as $solrMarcYaml) { + $this->parseSolrMarcSpecs($solrMarcYaml); } - return $this->solrMarcSpecs[$item]; + } + return $this->solrMarcSpecs[$item] ?? []; } /** @@ -110,21 +126,21 @@ private function getSolrMarcSpecs($item) * * @return array */ - public function getSolrMarcKeys($category = '', $others = true) + public function getSolrMarcKeys($category = '', $others = false) { if (empty($this->solrMarcSpecs)) { - $this->parseSolrMarcSpecs(); + foreach ($this->solrMarcYamls as $solrMarcYaml) { + $this->parseSolrMarcSpecs($solrMarcYaml); + } } $specKeys = array_keys($this->solrMarcSpecs); if (empty($category)) { - if ($others) { - return $specKeys; - } else { - $solrMarcKeys = $this->solrMarcKeys; - unset($solrMarcKeys['other']); - $keys = array_reduce($solrMarcKeys, 'array_merge', []); - return array_intersect($keys, $specKeys); + if (!$others) { + if (($key = array_search('other', $specKeys)) !== false) { + unset($specKeys[$key]); + } } + return $specKeys; } else { if (is_array($this->solrMarcKeys[$category])) { return array_intersect($this->solrMarcKeys[$category], $specKeys); @@ -139,11 +155,11 @@ public function getSolrMarcKeys($category = '', $others = true) * * @return null */ - private function parseSolrMarcSpecs() + private function parseSolrMarcSpecs($solrMarcYaml) { $specsReader = new SearchSpecsReader(); - $rawSolrMarcSpecs = $specsReader->get($this->solrMarcYaml); - $solrMarcSpecs = []; + $rawSolrMarcSpecs = $specsReader->get($solrMarcYaml); + $solrMarcSpecs = $this->solrMarcSpecs; foreach ($rawSolrMarcSpecs as $item => $solrMarcSpec) { $solrMarcSpecs[$item] = []; if (array_key_exists('category', $solrMarcSpec)) { @@ -160,43 +176,58 @@ private function parseSolrMarcSpecs() $solrMarcSpecs[$item]['originalletters'] = 'no'; } unset($solrMarcSpec['originalletters']); + if (!empty($solrMarcSpec['mandatory-field'])) { + $solrMarcSpecs[$item]['mandatory-field'] = $solrMarcSpec['mandatory-field']; + } + unset($solrMarcSpec['mandatory-field']); + $solrMarcSpecs[$item]['view-method'] = 'default'; + if (!empty($solrMarcSpec['view-method'])) { + $solrMarcSpecs[$item]['view-method'] = $solrMarcSpec['view-method']; + } + unset($solrMarcSpec['view-method']); + $solrMarcSpecs[$item]['match-key'] = ''; + if (!empty($solrMarcSpec['match-key'])) { + $solrMarcSpecs[$item]['match-key'] = $solrMarcSpec['match-key']; + } + unset($solrMarcSpec['match-key']); + $conditions = $subfields = $parentMethods = $description = []; foreach ($solrMarcSpec as $marcField => $fieldSpec) { - $solrMarcSpecs[$item][$marcField] = []; - $conditions = $subfields = $parentMethods = $description = []; - foreach ($fieldSpec as $subField => $subFieldSpec) { - if (is_array($subFieldSpec)) { - if ($subField == 'conditions') { - foreach ($subFieldSpec as $spec) { - $conditions[] = $spec; - } - } elseif ($subField == 'parent') { - foreach ($subFieldSpec as $spec) { - $parentMethods[] = $spec; - } - } elseif ($subField == 'description') { - $descriptions[] = $subFieldSpec; - } elseif ($subField == 'subfields') { - $specs = []; - foreach ($subFieldSpec as $index => $spec) { - if ($index != 0) { - $specs[] = $spec; + if (!empty($fieldSpec)) { + $conditions = $subfields = $parentMethods = $description = []; + foreach ($fieldSpec as $subField => $subFieldSpec) { + if (is_array($subFieldSpec)) { + if ($subField == 'conditions') { + foreach ($subFieldSpec as $spec) { + $conditions[] = $spec; + } + } elseif ($subField == 'parent') { + foreach ($subFieldSpec as $spec) { + $parentMethods[] = $spec; + } + } elseif ($subField == 'description') { + $descriptions[] = $subFieldSpec; + } elseif ($subField == 'subfields') { + $specs = []; + foreach ($subFieldSpec as $index => $spec) { + if ($index != 0) { + $specs[] = $spec; + } + } + foreach ($subFieldSpec[0] as $subField) { + $subfields[$subField] = $specs; + } + } else { + foreach ($subFieldSpec as $index => $spec) { + $subfields[$subField][$index] = $spec; } - } - foreach ($subFieldSpec[0] as $subField) { - $subfields[$subField] = $specs; - } - } else { - foreach ($subFieldSpec as $index => $spec) { - $subfields[$subField][$index] = $spec; } } } - $solrMarcSpecs[$item][$marcField]['conditions'] = $conditions; - $solrMarcSpecs[$item][$marcField]['subfields'] = $subfields; - $solrMarcSpecs[$item][$marcField]['parent'] = $parentMethods; } + $solrMarcSpecs[$item][$marcField]['conditions'] = $conditions; + $solrMarcSpecs[$item][$marcField]['subfields'] = $subfields; + $solrMarcSpecs[$item][$marcField]['parent'] = $parentMethods; } - $solrMarcSpecs[$item]['title'] = (array_key_exists('title', $solrMarcSpec)) ? $solrMarcSpec['title'] : $item; } $this->solrMarcSpecs = $solrMarcSpecs; if (empty($this->originalLetters)) { @@ -215,8 +246,12 @@ public function getMarcData($dataName) if (empty($solrMarcSpecs) && method_exists($this, 'get' . $dataName)) { return call_user_func([$this, 'get' . $dataName]); } - $title = $solrMarcSpecs['title']; + $title = $solrMarcSpecs['title'] ?? ''; unset($solrMarcSpecs['title']); + $mandatoryField = $solrMarcSpecs['mandatory-field'] ?? ''; + unset($solrMarcSpecs['mandatory-field']); + $mandatoryFieldSet = (empty($mandatoryField)); + if (is_array($solrMarcSpecs)) { foreach ($solrMarcSpecs as $field => $subFieldSpecs) { $indexData = []; if (!empty($subFieldSpecs['parent'])) { @@ -229,10 +264,10 @@ public function getMarcData($dataName) $indexValues = call_user_func([$this, 'parent::' . $method]); if (is_array($indexValues)) { foreach ($indexValues as $indexKey => $value) { - $tmpData[$indexKey] = $value; + $tmpData[$indexKey] = ['data'=> [$value]]; } } else { - $tmpData[] = $value; + $tmpData = $indexValues; } } } elseif ($subFieldSpec[0] == 'name') { @@ -240,31 +275,68 @@ public function getMarcData($dataName) } } if (!empty($tmpData)) { - if (!empty($tmpKey)) { - foreach ($tmpData as $value) { - $indexData[] = [$tmpKey => $value]; - } + if (is_array($tmpData)) { + $indexData = [$tmpData]; + } elseif (!empty($tmpKey)) { + $indexData[] = [$tmpKey => ['data' => [$tmpData]]]; } else { - $indexData[] = $tmpData; + $indexData[] = [['data' => [$tmpData]]]; } } } - foreach ($this->getMarcReader()->getFields($field) as $index => $fieldObject) { - $data = $indexData; + foreach ($this->getMarcReader()->getFields($field) as $index => $fieldObject) { + $data = $indexData[0] ?? []; + $conditionForcedValue = []; if (!empty($subFieldSpecs['conditions'])) { foreach ($subFieldSpecs['conditions'] as $condition) { - if ($condition[0] == 'indicator') { - if ($fieldObject['i'.$condition[1]] != $condition[2]) { // get indicator + list($type, $key, $val) = $condition; + if (is_object($val) && get_class($val) == 'Symfony\Component\Yaml\Tag\TaggedValue') { + $val = $val->getValue(); + } + + $val = strval($val); + if (substr($val, 0, 1) == '!') { + $val = substr($val, 1); + if ($type == 'indicator') { + $indicator = $fieldObject['i'.$key]; + if (!empty($indicator) && ($val == '*' || preg_match('/'.$val.'/', $indicator))) { + continue 2; + } + } elseif ($type == 'field') { + foreach ($fieldObject['subfields'] as $subFieldObject) { + if ($subFieldObject['code'] == $key) { + if ($val == '*' || preg_match('/'.$val.'/', $subFieldObject['data'])) { + continue 3; + } + } + } + } + } else { + if ($type == 'indicator') { + $indicator = $fieldObject['i'.$key]; + if (!isset($indicator) || $val != '*' && !preg_match('/'.$val.'/', $indicator)) { continue 2; } - } elseif ($condition[0] == 'field') { - $subField = $fieldObject['subfields'][$condition[1]]; - if (!is_object($subField) || ($subField->getData() != $condition[2] && $condition[2] != '*')) { + } elseif ($type == 'field') { + $fieldExists = false; + $subfieldCheckPassed = false; + foreach ($fieldObject['subfields'] as $subFieldObject) { + if ($subFieldObject['code'] == $key) { + $fieldExists = true; + if ($val == '*' || preg_match('/'.$val.'/', $subFieldObject['data'])) { + $subfieldCheckPassed = true; + $conditionForcedValue[$key] = $subFieldObject['data']; + break; + } + } + } + if (!$subfieldCheckPassed || !$fieldExists) { continue 2; } } } } + } if (!empty($subFieldSpecs['subfields'])) { $subFieldList = []; foreach ($subFieldSpecs['subfields'] as $subField => $specs) { @@ -273,68 +345,119 @@ public function getMarcData($dataName) foreach ($specs as $spec) { if (isset($spec[0])) { if ($spec[0] == 'name') { + if (!empty($subFieldList[$subField]['name'])) { + $subFieldList[$subField]['name'] .= '#' . $spec[1]; + } else { $subFieldList[$subField]['name'] = $spec[1]; + } } elseif ($spec[0] == 'match') { $subFieldList[$subField]['filter'] = $spec[1]; $subFieldList[$subField]['match'] = intval($spec[2]); } elseif ($spec[0] == 'replace') { - $subFieldList[$subField]['toReplace'] = $spec[1]; - $subFieldList[$subField]['replacement'] = $spec[2]; + if (!isset($subFieldList[$subField]['toReplace'])) { + $subFieldList[$subField]['toReplace'] = []; + $subFieldList[$subField]['replacement'] = []; + } + $subFieldList[$subField]['toReplace'][] = $spec[1]; + $subFieldList[$subField]['replacement'][] = $spec[2]; } elseif ($spec[0] == 'function') { - $subFieldList[$subField]['function'] = $spec[1]; + if (!isset($subFieldList[$subField]['function'])) { + $subFieldList[$subField]['function'] = []; + $subFieldList[$subField]['parameter'] = []; } + $subFieldList[$subField]['function'][] = $spec[1]; + $subFieldList[$subField]['parameter'][] = $spec[2]; } } } } + } + $dataIndex = 0; foreach ($subFieldList as $subfield => $properties) { $fieldData = []; if (strpos($subfield, 'indicator') !== false) { $indicator = substr($subfield, 9, 1); - $fieldData[] = $fieldObject['i'.$indicator]; + $fieldData[] = $fieldObject['i'.$indicator]; + } else { + foreach ($fieldObject['subfields'] as $subFieldObject) { + if ($subFieldObject['code'] == $subfield) { + if (!empty($conditionForcedValue[$subfield])) { + if ($subFieldObject['data'] == $conditionForcedValue[$subfield]) { + $fieldData[] = $conditionForcedValue[$subfield]; + } } else { - foreach ($fieldObject['subfields'] as $subFieldObject) { - if ($subFieldObject['code'] == $subfield) { - $fieldData[] = $subFieldObject['data']; + $fieldData[] = $subFieldObject['data']; + } } } } if (!empty($fieldData)) { - foreach ($fieldData as $dataIndex => $fieldDate) { + foreach ($fieldData as $fieldDate) { if (isset($properties['filter']) && isset($properties['match'])) { if (preg_match('/'.$properties['filter'].'/', $fieldDate, $matches)) { $fieldDate = $matches[$properties['match']]; + } else { + $fieldDate = ''; } } - if (isset($properties['toReplace']) && isset($properties['replacement'])) { - $fieldDate = preg_replace('/'.$properties['toReplace'].'/', $properties['replacement'], $fieldDate); - } if (isset($properties['function'])) { - $function = $properties['function']; + for ($i = 0; $i < count($properties['function']); $i++) { + $function = $properties['function'][$i]; + if (!empty($properties['parameter'][$i])) { + $fieldDate = $function($fieldDate, $properties['parameter'][$i]); + #$fieldDate = $function($fieldDate, MB_CASE_TITLE); + } else { $fieldDate = $function($fieldDate); } - $name = $properties['name'] ?? $dataIndex; - $data[$name] = ['data'=>trim($fieldDate)]; + } + } + if (isset($properties['toReplace']) && isset($properties['replacement'])) { + for ($i = 0; $i < count($properties['toReplace']); $i++) { + $fieldDate = preg_replace('/' . $properties['toReplace'][$i] . '/', $properties['replacement'][$i], $fieldDate); + } + } + $fieldDate = trim($fieldDate); + if (empty($fieldDate) && $fieldDate !== '0' && $fieldDate !== 0) { + continue; + } + $tmpName = $properties['name'] ?? $dataIndex++; + $names = explode('#', $tmpName); + foreach ($names as $name) { + if (!isset($data[$name]['data'])) { + $data[$name]['data'] = []; + } + $data[$name]['data'][] = $fieldDate; if (empty($solrMarcSpecs['originalletters']) || $solrMarcSpecs['originalletters'] != 'no') { if (!empty($this->originalLetters[$field][$index][$subfield])) { $data[$name]['originalLetters'] = $this->originalLetters[$field][$index][$subfield]; } } + if ($name == $mandatoryField) { + $mandatoryFieldSet = true; + } + } } } } } + if (!empty($data)) { $returnData[] = $data; } + } if (empty($returnData)) { $returnData = $indexData; } } + } if (!empty($returnData)) { - $returnData['title'] = $title; + $returnData['view-method'] = $solrMarcSpecs['view-method']; + $returnData['match-key'] = $solrMarcSpecs['match-key']; + } + if (!$mandatoryFieldSet) { + return []; } - return $returnData; + return $returnData ?? []; } /** @@ -347,14 +470,14 @@ protected function getOriginalLetters() $originalLetters = []; if ($fields = $this->getMarcReader()->getFields('880')) { foreach ($fields as $field) { - $subfields = $field->getSubfields(); + $subfields = $field['subfields']; $letters = []; foreach ($subfields as $subfield) { - $code = $subfield->getCode(); + $code = $subfield['code']; if ($code == '6') { - $index = preg_replace('/-.*$/', '', $subfield->getData()); + $index = preg_replace('/-.*$/', '', $subfield['data']); } elseif(!is_numeric($code)) { - $letters[$code] = $subfield->getData(); + $letters[$code] = $subfield['data']; } } if (isset($originalLetters[$index])) { @@ -394,4 +517,102 @@ public function getBibliographicLevel() return "Unknown"; } } + + /** + * Get the multipart resource record level level of the current record. + * + * @return string + */ + public function getMultipartResourceRecordLevel() + { + $leader = $this->getMarcReader()->getLeader(); + $mrrLevel = strtoupper($leader[19]); + + switch ($mrrLevel) { + case 'A': // Set + return "Set"; + case 'B': // Part with independent title + return "Part with independent title"; + case 'C': // Part with dependent title + return "Part with dependent title"; + default: + return "Unknown"; + } + } + + /** + * Return an XML representation of the record using the specified format. + * Return false if the format is unsupported. + * + * @param string $format Name of format to use (corresponds with OAI-PMH + * metadataPrefix parameter). + * @param string $baseUrl Base URL of host containing VuFind (optional; + * may be used to inject record URLs into XML when appropriate). + * @param RecordLink $recordLink Record link helper (optional; may be used to + * inject record URLs into XML when appropriate). + * + * @return mixed XML, or false if format unsupported. + */ + public function getXML($format, $baseUrl = null, $recordLink = null) + { + // Special case for MARC: + if ($format == 'marc21') { + $xml = $this->getMarcReader()->toXML(); + $xml = str_replace( + [chr(27), chr(28), chr(29), chr(30), chr(31)], ' ', $xml + ); + $xml = simplexml_load_string($xml); + if (!$xml || !isset($xml->record)) { + return false; + } + + // Set up proper namespacing and extract just the tag: + $xml->record->addAttribute('xmlns', "http://www.loc.gov/MARC21/slim"); + $xml->record->addAttribute( + 'xsi:schemaLocation', + 'http://www.loc.gov/MARC21/slim ' . + 'http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd', + 'http://www.w3.org/2001/XMLSchema-instance' + ); + $xml->record->addAttribute('type', 'Bibliographic'); + return $xml->record->asXML(); + } + + // Try the parent method: + return parent::getXML($format, $baseUrl, $recordLink); + } + + /** + * Get the OpenURL parameters to represent this record (useful for the + * title attribute of a COinS span tag). + * + * @param bool $overrideSupportsOpenUrl Flag to override checking + * supportsOpenUrl() (default is false) + * + * @return string OpenURL parameters. + */ + public function getOpenUrl($overrideSupportsOpenUrl = false) + { + return parent::getOpenUrl($overrideSupportsOpenUrl); + } + + /** + * Get OpenURL parameters for an article. + * + * @return array + */ + protected function getArticleOpenUrlParams() + { + $params = parent::getArticleOpenUrlParams(); + $pages = $this->getMarcData('Pages'); + if (strpos($pages, '-') !== false) { + list($spage, $epage) = explode('-', $pages[0]['pages']['data'][0]); + $params['rft.epage'] = $epage; + } + return $params; + } + + public function getLibraryHolding () { + return $this->getMarcReader()->getFields('980'); + } } From ed08073b0ccf41674181121eff18fc70af4b5a98 Mon Sep 17 00:00:00 2001 From: Johannes Schultze Date: Tue, 18 Jul 2023 10:25:52 +0200 Subject: [PATCH 09/14] VuFind 9. --- src/RecordDriver/RecordDriver/SolrMarc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RecordDriver/RecordDriver/SolrMarc.php b/src/RecordDriver/RecordDriver/SolrMarc.php index 47f4472..916b406 100755 --- a/src/RecordDriver/RecordDriver/SolrMarc.php +++ b/src/RecordDriver/RecordDriver/SolrMarc.php @@ -40,7 +40,7 @@ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development:plugins:record_drivers Wiki */ -class SolrMarc extends SolrDefault +class SolrMarc extends \Findex\RecordDriver\SolrMarc { use \VuFind\RecordDriver\Feature\IlsAwareTrait; use \VuFind\RecordDriver\Feature\MarcReaderTrait; From 1e49bf93da0d3a4a874149cc5d4dbd4b25893519 Mon Sep 17 00:00:00 2001 From: Johannes Schultze Date: Tue, 18 Jul 2023 11:18:59 +0200 Subject: [PATCH 10/14] VuFind 9. --- src/RecordDriver/RecordDriver/SolrMarc.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/RecordDriver/RecordDriver/SolrMarc.php b/src/RecordDriver/RecordDriver/SolrMarc.php index 916b406..f428fae 100755 --- a/src/RecordDriver/RecordDriver/SolrMarc.php +++ b/src/RecordDriver/RecordDriver/SolrMarc.php @@ -605,9 +605,11 @@ protected function getArticleOpenUrlParams() { $params = parent::getArticleOpenUrlParams(); $pages = $this->getMarcData('Pages'); - if (strpos($pages, '-') !== false) { - list($spage, $epage) = explode('-', $pages[0]['pages']['data'][0]); - $params['rft.epage'] = $epage; + foreach ($pages as $page) { + if (strpos($page, '-') !== false) { + list($spage, $epage) = explode('-', $page[0]['pages']['data'][0]); + $params['rft.epage'] = $epage; + } } return $params; } From a3a718e86c3a0abc0600986783f47f989f2d82c3 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 26 Jul 2023 13:42:48 +0200 Subject: [PATCH 11/14] Update. --- src/RecordDriver/RecordDriver/SolrMarc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RecordDriver/RecordDriver/SolrMarc.php b/src/RecordDriver/RecordDriver/SolrMarc.php index f428fae..ba1630c 100755 --- a/src/RecordDriver/RecordDriver/SolrMarc.php +++ b/src/RecordDriver/RecordDriver/SolrMarc.php @@ -40,7 +40,7 @@ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development:plugins:record_drivers Wiki */ -class SolrMarc extends \Findex\RecordDriver\SolrMarc +class SolrMarc extends SolrDefault { use \VuFind\RecordDriver\Feature\IlsAwareTrait; use \VuFind\RecordDriver\Feature\MarcReaderTrait; From c36e0eb4c46e894b388add0a5aeee1d42141a61a Mon Sep 17 00:00:00 2001 From: Johannes Schultze Date: Wed, 26 Jul 2023 15:37:31 +0200 Subject: [PATCH 12/14] Update. --- src/RecordDriver/RecordDriver/SolrMarc.php | 38 +++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/RecordDriver/RecordDriver/SolrMarc.php b/src/RecordDriver/RecordDriver/SolrMarc.php index ba1630c..6fb1b4e 100755 --- a/src/RecordDriver/RecordDriver/SolrMarc.php +++ b/src/RecordDriver/RecordDriver/SolrMarc.php @@ -130,7 +130,9 @@ public function getSolrMarcKeys($category = '', $others = false) { if (empty($this->solrMarcSpecs)) { foreach ($this->solrMarcYamls as $solrMarcYaml) { - $this->parseSolrMarcSpecs($solrMarcYaml); + if ($solrMarcYaml) { + $this->parseSolrMarcSpecs($solrMarcYaml); + } } } $specKeys = array_keys($this->solrMarcSpecs); @@ -617,4 +619,38 @@ protected function getArticleOpenUrlParams() public function getLibraryHolding () { return $this->getMarcReader()->getFields('980'); } + + /* Correction for Findex/K10 */ + /** + * Get the short (pre-subtitle) title of the record. + * + * @return string + */ + public function getShortTitle() + { + return isset($this->fields['title_short']) ? + is_array($this->fields['title_short']) ? $this->fields['title_short'][0] : $this->fields['title_short'] : ''; + } + + /** + * Get the full title of the record. + * + * @return string + */ + public function getTitle() + { + return isset($this->fields['title']) ? + is_array($this->fields['title']) ? $this->fields['title'][0] : $this->fields['title'] : ''; + } + + /** + * Get the subtitle of the record. + * + * @return string + */ + public function getSubtitle() + { + return isset($this->fields['title_sub']) ? + is_array($this->fields['title_sub']) ? $this->fields['title_sub'][0] : $this->fields['title_sub'] : ''; + } } From 52a3fda85234473406cc5416810151f4b5763d7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6hr?= Date: Thu, 24 Aug 2023 15:59:42 +0200 Subject: [PATCH 13/14] Reactivate/fix templates --- src/RecordDriver/RecordDriver/SolrMarc.php | 42 +++++++++---------- .../View/Helper/RecordDriver/SolrDetails.php | 8 +++- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/RecordDriver/RecordDriver/SolrMarc.php b/src/RecordDriver/RecordDriver/SolrMarc.php index 6fb1b4e..173458d 100755 --- a/src/RecordDriver/RecordDriver/SolrMarc.php +++ b/src/RecordDriver/RecordDriver/SolrMarc.php @@ -345,31 +345,31 @@ public function getMarcData($dataName) $subFieldList[$subField] = []; if (!empty($specs)) { foreach ($specs as $spec) { - if (isset($spec[0])) { + if (isset($spec[0]) && array_key_exists(0, $spec)) { if ($spec[0] == 'name') { - if (!empty($subFieldList[$subField]['name'])) { - $subFieldList[$subField]['name'] .= '#' . $spec[1]; - } else { - $subFieldList[$subField]['name'] = $spec[1]; - } - } elseif ($spec[0] == 'match') { + if (!empty($subFieldList[$subField]['name'])) { + $subFieldList[$subField]['name'] .= '#' . $spec[1]; + } else { + $subFieldList[$subField]['name'] = $spec[1]; + } + } elseif ($spec[0] == 'match' && array_key_exists(2, $spec)) { $subFieldList[$subField]['filter'] = $spec[1]; $subFieldList[$subField]['match'] = intval($spec[2]); - } elseif ($spec[0] == 'replace') { - if (!isset($subFieldList[$subField]['toReplace'])) { - $subFieldList[$subField]['toReplace'] = []; - $subFieldList[$subField]['replacement'] = []; - } - $subFieldList[$subField]['toReplace'][] = $spec[1]; - $subFieldList[$subField]['replacement'][] = $spec[2]; - } elseif ($spec[0] == 'function') { - if (!isset($subFieldList[$subField]['function'])) { - $subFieldList[$subField]['function'] = []; - $subFieldList[$subField]['parameter'] = []; + } elseif ($spec[0] == 'replace' && array_key_exists(2, $spec)) { + if (!isset($subFieldList[$subField]['toReplace'])) { + $subFieldList[$subField]['toReplace'] = []; + $subFieldList[$subField]['replacement'] = []; + } + $subFieldList[$subField]['toReplace'][] = $spec[1]; + $subFieldList[$subField]['replacement'][] = $spec[2]; + } elseif ($spec[0] == 'function' && array_key_exists(2, $spec)) { + if (!isset($subFieldList[$subField]['function'])) { + $subFieldList[$subField]['function'] = []; + $subFieldList[$subField]['parameter'] = []; + } + $subFieldList[$subField]['function'][] = $spec[1]; + $subFieldList[$subField]['parameter'][] = $spec[2]; } - $subFieldList[$subField]['function'][] = $spec[1]; - $subFieldList[$subField]['parameter'][] = $spec[2]; - } } } } diff --git a/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php b/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php index 9c12f49..7d86b10 100755 --- a/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php +++ b/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php @@ -101,7 +101,9 @@ public function getCoreFields(RecordDriver $driver, $categories = []) } $templateData = []; if (strpos($viewMethod, '-link') > 0) { - list($key, , $separators) = explode('-', $viewMethod); + $array = explode('-', $viewMethod); + $array[2] = null; + list($key, , $separators) = $array; if (empty($separators)) { $separators = 0; } @@ -113,7 +115,9 @@ public function getCoreFields(RecordDriver $driver, $categories = []) } elseif ($viewMethod == 'chain') { $templateData = $this->makeChain($solrMarcData[$solrMarcKey]); } elseif (strpos($viewMethod, '-template') > 0) { - list($key, , $separators) = explode('-', $viewMethod); + $array = explode('-', $viewMethod); + $array[2] = null; + list($key, , $separators) = $array; if (empty($separators)) { $separators = 0; } From b3232e00d55715f0eb6d6a2341d7f84b49c73050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6hr?= Date: Wed, 10 Jan 2024 12:09:56 +0100 Subject: [PATCH 14/14] Add documentation --- README.md | 373 +----------------- config/vufind/solrmarc.yaml | 363 +++++++++++++++++ .../View/Helper/RecordDriver/SolrDetails.php | 9 +- 3 files changed, 374 insertions(+), 371 deletions(-) create mode 100644 config/vufind/solrmarc.yaml diff --git a/README.md b/README.md index 6f83a68..02eff59 100755 --- a/README.md +++ b/README.md @@ -1,369 +1,6 @@ -Customizable RecordDriver Module to use as a module for VuFind 5 +# RecordDriver +Customizable RecordDriver Module to use as a module for VuFind 9. -Add a file "solrmarc.yaml" with the following content to you [VUFIND_LOCAL_DIR]/config/vufind/ directory: - -``` ---- -# Listing of data to be read from marc bibliographic data -# -# Format is: -# : -# category: -# title should be set; other categories are mandatory -# originalletters: whether item in original letters should be -# shown or not (see marc 880) -#
: at least one should be set; fields with a leading 0 should be quoted -# if only parent methods are used the main field is '000' -# conditions: conditions which should be fulfilled if the data is read -# - [, , ] is either field or indicator -# is the name of the field or indicator -# is the value it should have -# parent: use a parent method (from SolrDefault driver) -# - [] the method to use -# subfields: only read the fields -# - [] list of fields to read -# : enhanced processing of a subfield -# - [name, ] name it -# - [replace, , ] replace a substring from to (using a regex) -# - [match, , ] match a substring () and use the th parantesis -# (using a regex) -# - [function, ] use th return value of a php-function -# -#----------------------------------------------------------------------------------- -# -ShortTitle: - category: title - originalletters: yes - 245: - subfields: - - [a] -SubTitle: - category: title - 245: - subfields: - - [b] -TitleSection: - category: title - 245: - subfields: - - [n] - p: - - [name, extended] -TitleStatement: - category: title - 245: - subfields: - - [c] -Summary: - category: title - 520: - subfields: - - [a] -WorkTitle: - category: title2 - 130: - a: - - [name, title] - - [replace, '@', ''] - 240: - a: - - [name, title] - - [replace, '@', ''] - 100: - a: - - [name, person] - c: - - [name, titles] - d: - - [name, dates] -OtherTitles: - category: title2 - 246: - subfields: - - [a] -PreviousTitles: - category: title2 - 780: - t: - - [name, title] - w: - - [name, id] - - [match, '\(DE-(599)|(600)\)([0-9xX-]+)', 3] -NewerTitles: - category: title2 - 785: - t: - - [name, title] - w: - - [name, id] - - [match, '\(DE-(599)|(600)\)([0-9xX-]+)', 3] -Series: - category: title2 - 490: - subfields: - a: - - [name, title] - - [match, '^([^<>]+)( <([^<>]+)>(.*))?$', 1] - a: - - [name, supplement] - - [match, '^([^<>]+)( <([^<>]+)>(.*))?$', 3] - v: - - [name, volume] - 830: - subfields: - v: - - [name, volume] - w: - - [name, ppn] - - [match, '\(DE-601\)([0-9xX]+)', 1] -Person: - category: person - 100: - a: - - [name, name] - b: - - [name, number] - c: - - [name, title] - d: - - [name, date] - e: - - [name, description] - - [replace, 'in( |$)$', 'In '] - - [function, 'ucfirst'] - 700: - a: - - [name, name] - b: - - [name, number] - c: - - [name, title] - d: - - [name, date] - e: - - [name, description] - - [replace, 'in( |$)$', 'In '] - - [function, 'ucfirst'] -Cooperation: - category: person - 110: - a: - - [name, name] - b: - - [name, unit] - c: - - [name, location] - d: - - [name, date] - e: - - [name, description] - - [function, 'ucfirst'] - 710: - a: - - [name, name] - b: - - [name, unit] - c: - - [name, location] - d: - - [name, date] - e: - - [name, description] - - [function, 'ucfirst'] -CongressData: - category: person - 111: - a: - - [name, name] - c: - - [name, location] - d: - - [name, date] - e: - - [name, unit] - 711: - a: - - [name, name] - c: - - [name, location] - d: - - [name, date] - e: - - [name, unit] -Performers: - category: person - 511: - subfields: - - [a] -Formats: - category: description - '000': - parent: - - [getFormats] -Languages: - category: description - 546: - parent: - - [getLanguages] - subfields: - - [a] -OriginalLanguage: - category: description - '041': - subfields: - - [a] -FormNote: - category: description - 655: - subfields: - - [a] -GeneralNotes: - category: description - 500: - subfields: - - [a] -PhysicalDescription: - category: description - 300: - subfields: - - [a, b, c, e] -MapInfos: - category: description - 255: - subfields: - - [a, b, c, d, e, f, g] -SystemDetails: - category: description - 520: - subfields: - - [a] -ISBNs: - category: description - '020': - 9: - - [name, isbn] -ISSNs: - category: description - '022': - a: - - [match, '([0-9xX-]+)', 1] -PublicationDetails: - category: publication - 264: - a: - - [name, location] - - [replace, ' ;.*$', ''] - b: - - [name, name] - c: - - [name, date] - 260: - a: - - [name, location] - - [replace, ' ;.*$', ''] - b: - - [name, name] - c: - - [name, date] -URLs: - category: publication - 856: - conditions: - - [field, y, !C] - u: - - [name, url] - 3: - - [name, description] - z: - - [name, description] - 555: - conditions: - - [field, y, !C] - u: - - [name, url] - a: - - [name, description] -IncludedItems: - category: related - 501: - subfields: - - [a] -RelationshipNotes: - category: related - 580: - subfields: - - [a] -SecondaryEditions: - category: related - 533: - subfields: - - [a, b, c, d, f] - e: - - [name, content] -OtherEditions: - category: related - 787: - conditions: - - [field, i, '*'] - i: - - [name, fieldType] - t: - - [name, fieldDesc] - w: - - [name, type] - - [replace, '^\(DE-600\).+$', 'ZDBID'] - - [replace, '^\(DE-601\).+$', 'PPN'] - w: - - [name, id] - - [match, '\(DE-60[01]\)([^()]+)', 1] -NLM: - category: subject - '060': - subfields: - - [a] -BasicClassifications: - category: subject - '084': - conditions: - - [field, 2, bcl] - subfields: - - [a, 9] -ContainingWork: - category: related - 773: - i: - - [name, prefix] - t: - - [name, title] - z: - - [name, isn] - - [match, '\(.+\)([^()]+)', 1] - x: - - [name, isn] - - [match, '\(.+\)([^()]+)', 1] - w: - - [name, ppn] - - [match, '\(.+\)([^()]+)', 1] - d: - - [name, location] - g: - - [name, issue] - 800: - i: - - [name, prefix] - t: - - [name, title] - z: - - [name, isn] - - [match, '\(.+\)([^()]+)', 1] - x: - - [name, isn] - - [match, '\(.+\)([^()]+)', 1] - w: - - [name, ppn] - - [match, '\(.+\)([^()]+)', 1] - d: - - [name, location] - g: - - [name, issue] -``` \ No newline at end of file +## Usage +Integrate the module in the `modules` directory of VuFind and activate it by adding `RecordDriver` to `VUFIND_LOCAL_MODULES`. +When adding the module manually make sure to copy and adapt the config files and copy/symlink the theme. diff --git a/config/vufind/solrmarc.yaml b/config/vufind/solrmarc.yaml new file mode 100644 index 0000000..64faf6f --- /dev/null +++ b/config/vufind/solrmarc.yaml @@ -0,0 +1,363 @@ +--- +# Listing of data to be read from marc bibliographic data +# +# Format is: +# : +# category: +# title should be set; other categories are mandatory +# originalletters: whether item in original letters should be +# shown or not (see marc 880) +#
: at least one should be set; fields with a leading 0 should be quoted +# if only parent methods are used the main field is '000' +# conditions: conditions which should be fulfilled if the data is read +# - [, , ] is either field or indicator +# is the name of the field or indicator +# is the value it should have +# parent: use a parent method (from SolrDefault driver) +# - [] the method to use +# subfields: only read the fields +# - [] list of fields to read +# : enhanced processing of a subfield +# - [name, ] name it +# - [replace, , ] replace a substring from to (using a regex) +# - [match, , ] match a substring () and use the th parantesis +# (using a regex) +# - [function, ] use th return value of a php-function +# +#----------------------------------------------------------------------------------- +# +ShortTitle: + category: title + originalletters: yes + 245: + subfields: + - [a] +SubTitle: + category: title + 245: + subfields: + - [b] +TitleSection: + category: title + 245: + subfields: + - [n] + p: + - [name, extended] +TitleStatement: + category: title + 245: + subfields: + - [c] +Summary: + category: title + 520: + subfields: + - [a] +WorkTitle: + category: title2 + 130: + a: + - [name, title] + - [replace, '@', ''] + 240: + a: + - [name, title] + - [replace, '@', ''] + 100: + a: + - [name, person] + c: + - [name, titles] + d: + - [name, dates] +OtherTitles: + category: title2 + 246: + subfields: + - [a] +PreviousTitles: + category: title2 + 780: + t: + - [name, title] + w: + - [name, id] + - [match, '\(DE-(599)|(600)\)([0-9xX-]+)', 3] +NewerTitles: + category: title2 + 785: + t: + - [name, title] + w: + - [name, id] + - [match, '\(DE-(599)|(600)\)([0-9xX-]+)', 3] +Series: + category: title2 + 490: + subfields: + a: + - [name, title] + - [match, '^([^<>]+)( <([^<>]+)>(.*))?$', 1] + a: + - [name, supplement] + - [match, '^([^<>]+)( <([^<>]+)>(.*))?$', 3] + v: + - [name, volume] + 830: + subfields: + v: + - [name, volume] + w: + - [name, ppn] + - [match, '\(DE-601\)([0-9xX]+)', 1] +Person: + category: person + 100: + a: + - [name, name] + b: + - [name, number] + c: + - [name, title] + d: + - [name, date] + e: + - [name, description] + - [replace, 'in( |$)$', 'In '] + - [function, 'ucfirst'] + 700: + a: + - [name, name] + b: + - [name, number] + c: + - [name, title] + d: + - [name, date] + e: + - [name, description] + - [replace, 'in( |$)$', 'In '] + - [function, 'ucfirst'] +Cooperation: + category: person + 110: + a: + - [name, name] + b: + - [name, unit] + c: + - [name, location] + d: + - [name, date] + e: + - [name, description] + - [function, 'ucfirst'] + 710: + a: + - [name, name] + b: + - [name, unit] + c: + - [name, location] + d: + - [name, date] + e: + - [name, description] + - [function, 'ucfirst'] +CongressData: + category: person + 111: + a: + - [name, name] + c: + - [name, location] + d: + - [name, date] + e: + - [name, unit] + 711: + a: + - [name, name] + c: + - [name, location] + d: + - [name, date] + e: + - [name, unit] +Performers: + category: person + 511: + subfields: + - [a] +Formats: + category: description + '000': + parent: + - [getFormats] +Languages: + category: description + 546: + parent: + - [getLanguages] + subfields: + - [a] +OriginalLanguage: + category: description + '041': + subfields: + - [a] +FormNote: + category: description + 655: + subfields: + - [a] +GeneralNotes: + category: description + 500: + subfields: + - [a] +PhysicalDescription: + category: description + 300: + subfields: + - [a, b, c, e] +MapInfos: + category: description + 255: + subfields: + - [a, b, c, d, e, f, g] +SystemDetails: + category: description + 520: + subfields: + - [a] +ISBNs: + category: description + '020': + 9: + - [name, isbn] +ISSNs: + category: description + '022': + a: + - [match, '([0-9xX-]+)', 1] +PublicationDetails: + category: publication + 264: + a: + - [name, location] + - [replace, ' ;.*$', ''] + b: + - [name, name] + c: + - [name, date] + 260: + a: + - [name, location] + - [replace, ' ;.*$', ''] + b: + - [name, name] + c: + - [name, date] +URLs: + category: publication + 856: + conditions: + - [field, y, !C] + u: + - [name, url] + 3: + - [name, description] + z: + - [name, description] + 555: + conditions: + - [field, y, !C] + u: + - [name, url] + a: + - [name, description] +IncludedItems: + category: related + 501: + subfields: + - [a] +RelationshipNotes: + category: related + 580: + subfields: + - [a] +SecondaryEditions: + category: related + 533: + subfields: + - [a, b, c, d, f] + e: + - [name, content] +OtherEditions: + category: related + 787: + conditions: + - [field, i, '*'] + i: + - [name, fieldType] + t: + - [name, fieldDesc] + w: + - [name, type] + - [replace, '^\(DE-600\).+$', 'ZDBID'] + - [replace, '^\(DE-601\).+$', 'PPN'] + w: + - [name, id] + - [match, '\(DE-60[01]\)([^()]+)', 1] +NLM: + category: subject + '060': + subfields: + - [a] +BasicClassifications: + category: subject + '084': + conditions: + - [field, 2, bcl] + subfields: + - [a, 9] +ContainingWork: + category: related + 773: + i: + - [name, prefix] + t: + - [name, title] + z: + - [name, isn] + - [match, '\(.+\)([^()]+)', 1] + x: + - [name, isn] + - [match, '\(.+\)([^()]+)', 1] + w: + - [name, ppn] + - [match, '\(.+\)([^()]+)', 1] + d: + - [name, location] + g: + - [name, issue] + 800: + i: + - [name, prefix] + t: + - [name, title] + z: + - [name, isn] + - [match, '\(.+\)([^()]+)', 1] + x: + - [name, isn] + - [match, '\(.+\)([^()]+)', 1] + w: + - [name, ppn] + - [match, '\(.+\)([^()]+)', 1] + d: + - [name, location] + g: + - [name, issue] \ No newline at end of file diff --git a/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php b/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php index 7d86b10..c7f3200 100755 --- a/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php +++ b/src/RecordDriver/View/Helper/RecordDriver/SolrDetails.php @@ -41,8 +41,6 @@ */ class SolrDetails extends AbstractClassBasedTemplateRenderer { - - protected $driver; protected $separatorSet = [ @@ -53,7 +51,7 @@ class SolrDetails extends AbstractClassBasedTemplateRenderer /** * Get the core field entries * - * @param RecordDriver $driever RecordDriver to use + * @param RecordDriver $driver RecordDriver to use * @param array $categories Categories to read (see config) * * @return array @@ -145,6 +143,11 @@ public function getCoreFields(RecordDriver $driver, $categories = []) return $solrMarcData; } + /** + * Get the result list entry. + * @param RecordDriver $driver RecordDriver to use + * @return array + */ public function getResultListLine(RecordDriver $driver) { $resultList = []; $resultListData = $driver->getMarcData('ResultList');