From 9d264f6f9dc38dfd64d5085c4cae03ea5c7a8f21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Lahmann?= <lahmann@ub.uni-leipzig.de> Date: Fri, 13 Mar 2015 10:00:13 +0100 Subject: [PATCH] refs #4826: * implemented RecordDriver SolrAI.php * implemented ResolverDriver Redi.php * modified core, staff view for SolrAI * modified openurl.js * added .ini file for SolrAI * added OpenUrl settings for dev/config.ini.sample --- local/alpha/config/vufind/SolrAI.ini | 22 + local/config/vufind/SolrAI.ini | 3 + local/dev/config/vufind/SolrAI.ini.sample | 26 + local/dev/config/vufind/config.ini.sample | 13 + local/languages/de.ini | 5 +- local/languages/en.ini | 4 + .../VuFind/Search/Solr/MultiIndexListener.php | 6 +- .../VuFind/src/VuFind/Search/Solr/Params.php | 2 +- module/finc/config/module.config.php | 18 +- module/finc/src/finc/RecordDriver/Factory.php | 16 + module/finc/src/finc/RecordDriver/SolrAI.php | 867 ++++++++++++++++++ .../src/finc/RecordDriver/SolrDefault.php | 59 +- .../finc/src/finc/Resolver/Driver/Factory.php | 58 ++ module/finc/src/finc/Resolver/Driver/Redi.php | 318 +++++++ .../src/finc/View/Helper/Root/Factory.php | 56 ++ .../finc/src/finc/View/Helper/Root/Record.php | 72 ++ themes/finc/js/openurl.js | 41 + .../templates/RecordDriver/SolrAI/core.phtml | 264 ++++++ .../RecordDriver/SolrAI/link-isn.phtml | 1 + .../RecordDriver/SolrAI/result-list.phtml | 193 ++++ .../templates/RecordTab/description.phtml | 242 +++++ .../templates/RecordTab/staffviewarray.phtml | 23 + .../finc/templates/ajax/resolverLinks.phtml | 51 ++ themes/finc/theme.config.php | 7 +- 24 files changed, 2323 insertions(+), 44 deletions(-) create mode 100644 local/alpha/config/vufind/SolrAI.ini create mode 100644 local/config/vufind/SolrAI.ini create mode 100644 local/dev/config/vufind/SolrAI.ini.sample create mode 100644 module/finc/src/finc/RecordDriver/SolrAI.php create mode 100644 module/finc/src/finc/Resolver/Driver/Factory.php create mode 100644 module/finc/src/finc/Resolver/Driver/Redi.php create mode 100644 module/finc/src/finc/View/Helper/Root/Factory.php create mode 100644 module/finc/src/finc/View/Helper/Root/Record.php create mode 100644 themes/finc/js/openurl.js create mode 100644 themes/finc/templates/RecordDriver/SolrAI/core.phtml create mode 100644 themes/finc/templates/RecordDriver/SolrAI/link-isn.phtml create mode 100644 themes/finc/templates/RecordDriver/SolrAI/result-list.phtml create mode 100644 themes/finc/templates/RecordTab/description.phtml create mode 100644 themes/finc/templates/RecordTab/staffviewarray.phtml create mode 100644 themes/finc/templates/ajax/resolverLinks.phtml diff --git a/local/alpha/config/vufind/SolrAI.ini b/local/alpha/config/vufind/SolrAI.ini new file mode 100644 index 00000000000..2860cc75855 --- /dev/null +++ b/local/alpha/config/vufind/SolrAI.ini @@ -0,0 +1,22 @@ +;#################################################################### +;##################### DO NOT DELETE THIS HEADER #################### +;################### Leipzig University Library © 2015 ############## +; +; This is the default ALPHA-INI-file and inherits +; all the settings from the INI-file defined in [Parent_Config] which +; points to the default INI-file located in the folder vufind2/local +; + +[Parent_Config] +relative_path = ../../../config/vufind/SolrAI.ini + +; A comma-separated list of config sections from the parent which should be +; completely overwritten by the equivalent sections in this configuration; +; any sections not listed here will be merged on a section-by-section basis. +;override_full_sections = "Languages,AlphaBrowse_Types" + +; +; Add ALPHA-specific customization after this header. +; +;##################### DO NOT DELETE THIS HEADER #################### +;#################################################################### diff --git a/local/config/vufind/SolrAI.ini b/local/config/vufind/SolrAI.ini new file mode 100644 index 00000000000..4ace37943b2 --- /dev/null +++ b/local/config/vufind/SolrAI.ini @@ -0,0 +1,3 @@ +[General] +; Set the URI-pattern of the server which serves the raw Ai-record-data. +baseUrl = "https://ai.ub.uni-leipzig.de/blob?%s" diff --git a/local/dev/config/vufind/SolrAI.ini.sample b/local/dev/config/vufind/SolrAI.ini.sample new file mode 100644 index 00000000000..84c18ffc83b --- /dev/null +++ b/local/dev/config/vufind/SolrAI.ini.sample @@ -0,0 +1,26 @@ +;#################################################################### +;##################### DO NOT DELETE THIS HEADER #################### +;################### Leipzig University Library © 2015 ############## +; +; This is the default DEV-INI-file and inherits +; all the settings from the INI-file defined in [Parent_Config] which +; points to the default INI-file located in the folder vufind2/local +; + +;[Parent_Config] +;relative_path = ../../../config/vufind/SolrAI.ini + +; A comma-separated list of config sections from the parent which should be +; completely overwritten by the equivalent sections in this configuration; +; any sections not listed here will be merged on a section-by-section basis. +;override_full_sections = "Languages,AlphaBrowse_Types" + +; +; Add DEV-specific customization after this header. +; +;##################### DO NOT DELETE THIS HEADER #################### +;#################################################################### + +[General] +; base url to ai blob server +baseUrl = "https://ai.ub.uni-leipzig.de/blob?%s" diff --git a/local/dev/config/vufind/config.ini.sample b/local/dev/config/vufind/config.ini.sample index 1f3c3a72f60..8f5345b61d2 100644 --- a/local/dev/config/vufind/config.ini.sample +++ b/local/dev/config/vufind/config.ini.sample @@ -41,3 +41,16 @@ hash_passwords = "1" encrypt_ils_password = "1" ils_encryption_key = "3e2ac9b644dd4e0b64b179a0309ead13bb59202a" + +; OpenURL configuration institution specified +; sample configuration for ubl +[OpenURL] +url = "http://www.redi-bw.de/links/ubl?rl_site=ubl" +rfr_id = www.ub.uni-leipzig.de +resolver = redi +window_settings = "toolbar=no,location=no,directories=no,buttons=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=550,height=600" +show_in_results = false ; include in search results +show_in_record = false ; include in core record metadata +show_in_holdings = true ; include in holdings tab of record view +embed = true +replace_other_urls = true diff --git a/local/languages/de.ini b/local/languages/de.ini index 849f10adf3b..4c6b333c40c 100644 --- a/local/languages/de.ini +++ b/local/languages/de.ini @@ -1817,4 +1817,7 @@ Zweigbibliothek = Branch Library Fachgebiet = Subject history = Search History renew_item_maximum = There is a maximum of three renewals allowed. -guser_dunning_process = User account is blocked due to a dunning process \ No newline at end of file +guser_dunning_process = User account is blocked due to a dunning process + +################### finc-spezifisch inzugefuegt ########################## +p. = S. \ No newline at end of file diff --git a/local/languages/en.ini b/local/languages/en.ini index 332ac43c3a1..e29e8218f40 100644 --- a/local/languages/en.ini +++ b/local/languages/en.ini @@ -1761,3 +1761,7 @@ Check interlibrary loans = Check interlibrary loans Check availability via interlibrary loans = Check availability via interlibrary loans Initiate purchase order = Initiate purchase order Please purchase = Please purchase + + +################### finc-spezifisch hinzugefuegt ########################## +p. = p. \ No newline at end of file diff --git a/module/VuFind/src/VuFind/Search/Solr/MultiIndexListener.php b/module/VuFind/src/VuFind/Search/Solr/MultiIndexListener.php index 36502f9cf85..1620d1a8c75 100644 --- a/module/VuFind/src/VuFind/Search/Solr/MultiIndexListener.php +++ b/module/VuFind/src/VuFind/Search/Solr/MultiIndexListener.php @@ -124,7 +124,11 @@ class MultiIndexListener } else { // In any other context, we should make sure our field values are // all legal. - $shards = explode(',', implode(',', $params->get('shards'))); + + // Check if $params->get('shards') returns an array to prevent + // invalid argument warnings. + $shards = explode(',', implode(',', + (is_array($params->get('shards')) ? $params->get('shards') : array()))); $fields = $this->getFields($shards); $specs = $this->getSearchSpecs($fields); $backend->getQueryBuilder()->setSpecs($specs); diff --git a/module/VuFind/src/VuFind/Search/Solr/Params.php b/module/VuFind/src/VuFind/Search/Solr/Params.php index f08961a0e9e..861d6df6b70 100644 --- a/module/VuFind/src/VuFind/Search/Solr/Params.php +++ b/module/VuFind/src/VuFind/Search/Solr/Params.php @@ -459,7 +459,7 @@ class Params extends \VuFind\Search\Base\Params // Shards $allShards = $this->getOptions()->getShards(); $shards = $this->getSelectedShards(); - if (is_null($shards)) { + if (empty($shards)) { $shards = array_keys($allShards); } diff --git a/module/finc/config/module.config.php b/module/finc/config/module.config.php index db891c69720..1932dc217f5 100644 --- a/module/finc/config/module.config.php +++ b/module/finc/config/module.config.php @@ -18,7 +18,13 @@ $config = array( 'solrdefault' => 'finc\RecordDriver\Factory::getSolrDefault', 'solrmarc' => 'finc\RecordDriver\Factory::getSolrMarc', 'solrmarcremote' => 'finc\RecordDriver\Factory::getSolrMarcRemote', - 'solrmarcremotefinc' => 'finc\RecordDriver\Factory::getSolrMarcRemoteFinc' + 'solrmarcremotefinc' => 'finc\RecordDriver\Factory::getSolrMarcRemoteFinc', + 'solrai' => 'finc\RecordDriver\Factory::getSolrAI', + ), + ), + 'resolver_driver' => array( + 'factories' => array( + 'redi' => 'finc\Resolver\Driver\Factory::getRedi', ), ), ), @@ -62,6 +68,16 @@ $config = array( 'Preview' => 'preview', 'HierarchyTree' => 'HierarchyTree', 'Map' => 'Map', 'Details' => 'StaffViewMARC', + ), + 'defaultTab' => null, + ), + 'finc\RecordDriver\SolrAI' => array( + 'tabs' => array ( + 'Holdings' => 'HoldingsILS', 'Description' => 'Description', + 'TOC' => 'TOC', 'UserComments' => 'UserComments', + 'Reviews' => 'Reviews', 'Excerpt' => 'Excerpt', + 'HierarchyTree' => 'HierarchyTree', 'Map' => 'Map', + 'Details' => 'StaffViewArray', ), 'defaultTab' => null, ), diff --git a/module/finc/src/finc/RecordDriver/Factory.php b/module/finc/src/finc/RecordDriver/Factory.php index 7579e829f1b..1336afd0ad0 100644 --- a/module/finc/src/finc/RecordDriver/Factory.php +++ b/module/finc/src/finc/RecordDriver/Factory.php @@ -63,6 +63,22 @@ class Factory return $driver; } + /** + * Factory for SolrAI record driver. + * + * @param ServiceManager $sm Service manager. + * + * @return SolrAI + */ + public static function getSolrAI(ServiceManager $sm) + { + return new SolrAI( + $sm->getServiceLocator()->get('VuFind\Config')->get('config'), + $sm->getServiceLocator()->get('VuFind\Config')->get('SolrAI'), + null + ); + } + /** * Factory for SolrMarcRemoteFinc record driver. * diff --git a/module/finc/src/finc/RecordDriver/SolrAI.php b/module/finc/src/finc/RecordDriver/SolrAI.php new file mode 100644 index 00000000000..b766d7167a2 --- /dev/null +++ b/module/finc/src/finc/RecordDriver/SolrAI.php @@ -0,0 +1,867 @@ +<?php +/** + * Recorddriver for Solr records from the aggregated index of Leipzig University + * Library + * + * PHP version 5 + * + * Copyright (C) Leipzig University Library 2015. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @category VuFind2 + * @package RecordDrivers + * @author André Lahmann <lahmann@ub.uni-leipzig.de> + * @author Gregor Gawol <gawol@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:record_drivers Wiki + */ +namespace finc\RecordDriver; + +/** + * Recorddriver for Solr records from the aggregated index of Leipzig University + * Library + * + * @category VuFind2 + * @package RecordDrivers + * @author André Lahmann <lahmann@ub.uni-leipzig.de> + * @author Gregor Gawol <gawol@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:record_drivers Wiki + * @SuppressWarnings(PHPMD.ExcessivePublicCount) + */ +class SolrAI extends SolrDefault +{ + /** + * Logger (or false for none) + * + * @var LoggerInterface|bool + */ + protected $logger = false; + + /** + * AI record + * + * @var array + */ + protected $aiRecord; + + /** + * holds config.ini data + * + * @var array + */ + protected $mainConfig; + + + /** + * gets the description of the record + * + * @return string description + */ + public function getDescriptions() + { + return $this->_getAIFullrecordArrayValue('abstract'); + } + + /** + * gets the edition key from the record + * + * @return string edition + */ + public function getEdition() + { + return $this->_getAIFullrecordStringValue('rft.edition'); + } + + /** + * gets the publication date of the record + * + * @return string publication date + */ + public function getDate() + { + return isset($this->fields['publishDateSort']) ? + $this->fields['publishDateSort'] : ''; + } + + /** + * gets an array of issues from record + * + * @return array of issues + */ + public function getIssues() + { + return $this->_getAIFullrecordStringValue('rft.issue'); + } + + + /** + * Get an array of publication detail of first entry combined from + * place, publisher and data. + * + * @return array + * @access protected + */ + /*public function getFirstPublicationDetails() + { + $place = $this->getPlacesOfPublication(); + $date = $this->getPublicationDates(); + $array = array(); + if (isset($this->fields['format']) && is_array($this->fields['format'])) { + $array['issue'] = (isset($this->fields['hierarchy_parent_title']) ? + 'In: '.$this->fields['hierarchy_parent_title'][0] : ''); + $array['date'] = ((is_array($date) && (count($date) > 0) ? + $date[0] : '')); + switch ((count($this->fields['format']) > 0) ? + $this->fields['format'][0] : '') { + case 'eBook': + $array['place'] = ((is_array($place) && (count($place) > 0) ? + $place[0] : '')); + break; + case 'ElectronicArticle': + $array['place'] = ''; + break; + default: + break; + } + } + + return $array; + }*/ + + /** + * Has FirstPublicationsDetails a Date in it + * + * @return boolean + * @access protected + */ + protected function getIsPublicationDetailsDate() + { + return true; + } + + /** + * Get the main author of the record. + * + * @return string + * @access protected + */ + public function getPrimaryAuthor() + { + return null; + } + + /** + * Get additional entries for personal names. + * + * @return array + * @access protected + * @link http://www.loc.gov/marc/bibliographic/bd700.html + */ + protected function getAdditionalAuthors() + { + if (isset($this->record['authors']) + && is_array($this->record['authors']) + && (count($this->record['authors']) > 0) + ) { + $retval = array(); + $i = 0; + $authors = $this->record['authors']; + foreach ($authors as $value) { + $retval[$i]['name'] = (isset($value['rft.aulast']) ? + $value['rft.aulast'].', ' : '') + .(isset($value['rft.aufirst']) ? $value['rft.aufirst'] : ''); + $i++; + } + return $retval; + } + return array(); + } + + /** + * Get the title of the item that contains this record (i.e. MARC 773s of a + * journal). + * + * @return string + */ + public function getContainerTitle() + { + return (isset($this->fields['hierarchy_parent_title']) ? + $this->fields['hierarchy_parent_title'][0] : ''); + } + + /** + * Get an array of publication detail lines combining information from + * getPublicationDates(), getPublishers() and getPlacesOfPublication(). + * + * @return array + * @access protected + */ + public function getPublicationDetails() + { + $names = $this->_getAIFullrecordArrayValue('rft.pub'); + $i = 0; + $retval = array(); + while (isset($names[$i])) { + // Build objects to represent each set of data; these will + // transform seamlessly into strings in the view layer. + $retval[] = new \VuFind\RecordDriver\Response\PublicationDetails( + null, + isset($names[$i]) ? $names[$i] : '', + null + ); + $i++; + } + return $retval; + } + + /** + * Get the publication dates of the record. See also getDateSpan(). + * + * @return array + */ + public function getPublicationDates() + { + return isset($this->fields['publishDateSort']) ? + $this->fields['publishDateSort'] : ''; + } + + /** + * Returns an array with the necessary information to create a detailed + * "Published in" line in RecordDriver core.phtml + * + * @return array + */ + public function getAIDataIn() + { + return array( + 'jtitle' => $this->getJTitle(), + 'volume' => $this->getVolume(), + 'date' => $this->getDate(), + 'issue' => $this->getIssues(), + 'issns' => $this->getISSNs(), + 'pages' => $this->getPages() + ); + } + + /** + * gets an array of series from record + * + * @return array of series + */ + public function getSeries() + { + return $this->_getAIFullrecordArrayValue('rft.series'); + } + + /** + * gets an array of volumes from record + * + * @return array of volumes + */ + public function getVolume() + { + return $this->_getAIFullrecordStringValue('rft.volume'); + } + + /** + * Get the ISSN from a record. + * + * @return array + * @access protected + * @link https://intern.finc.info/fincproject/issues/969 description + */ + public function getISSNs() + { + return $this->_getAIFullrecordArrayValue('rft.issn'); + } + + /** + * Get the eISSN from a record. + * + * @return array + * @access protected + * @link https://intern.finc.info/fincproject/issues/969 description + */ + public function getEISSNs() + { + return $this->_getAIFullrecordArrayValue('rft.eissn'); + } + + /** + * Get an array of all ISSNs associated with the record (may be empty). + * Can be the main ISSN and the parent ISSNs. + * + * @return array + * @access protected + */ + public function getISBNs() + { + return $this->_getAIFullrecordArrayValue('rft.isbn'); + } + + /** + * gets pages as 'start - end' if both exist + * + * @return string pages + */ + public function getPages() + { + if ($this->hasStartpages() + && $this->hasEndpages() + ) { + return sprintf( + '%s - %s', + $this->aiRecord['rft.spage'], + $this->aiRecord['rft.epage'] + ); + } else if ($this->hasStartpages()) { + return $this->aiRecord['rft.spage'][0]; + } else if ($this->hasEndpages()) { + return $this->aiRecord['rft.epage'][0]; + } + } + + /** + * Return an associative array of URLs associated with this record (key = URL, + * value = description). + * + * @return array + * @access protected + */ + public function getURLs() + { + $rediUrl = $this->mainConfig->OpenURL->rediUrl; + if (isset($rediUrl)) { + $urls = array(); + $url = sprintf($rediUrl, $this->getOpenURL()); + $filter = function ($url) { + return array('url' => $url, 'desc' => (strlen($url) > 200) ? + $this->translate('full text') : $this->translate($url)); + }; + $urls[] = $url; + return array_map($filter, $urls); + } + return array(); + } + + /** + * Return the jtitle field of ai records + * + * @return array Return jtitle fields. + * @access public + */ + public function getJTitle () + { + return $this->_getAIFullrecordStringValue('rft.jtitle'); + } + + /** + * Return the jtitle field of ai records + * + * @return array Return jtitle fields. + * @access public + */ + public function getATitle () + { + return $this->_getAIFullrecordStringValue('rft.atitle'); + } + + /** + * Return the jtitle field of ai records + * + * @return array Return jtitle fields. + * @access public + */ + public function getBTitle () + { + return $this->_getAIFullrecordStringValue('rft.btitle'); + } + + /** + * Get the OpenURL parameters to represent this record (useful for the + * title attribute of a COinS span tag). + * + * @return string OpenURL parameters. + */ + public function getOpenURL() { + // Set up parameters based on the format of the record: + switch ($this->aiRecord['rft.genre']) { + case 'book': + $params = $this->getBookOpenURLParams(); + break; + case 'article': + $params = $this->getArticleOpenURLParams(); + break; + case 'journal': + $params = $this->getJournalOpenURLParams(); + break; + default: + $format = $this->getFormats(); + $params = $this->getUnknownFormatOpenURLParams($format); + break; + } + + // Assemble the URL: + return http_build_query($params); + } + + /** + * Get the COinS identifier. + * + * @return string + */ + protected function getCoinsID() + { + // Get the COinS ID -- it should be in the OpenURL section of config.ini, + // but we'll also check the COinS section for compatibility with legacy + // configurations (this moved between the RC2 and 1.0 releases). + if (isset($this->mainConfig->OpenURL->rfr_id) + && !empty($this->mainConfig->OpenURL->rfr_id) + ) { + return $this->mainConfig->OpenURL->rfr_id; + } + return 'vufind.svn.sourceforge.net'; + } + + /** + * Get default OpenURL parameters. + * + * @return array + */ + protected function getDefaultOpenURLParams() + { + // Start an array of OpenURL parameters: + return array( + 'ctx_ver' => 'Z39.88-2004', + 'ctx_enc' => 'info:ofi/enc:UTF-8', + 'rfr_id' => 'info:sid/' . $this->getCoinsID() . ':generator' + ); + } + + /** + * Get OpenURL parameters for an article. + * + * @return array + */ + protected function getArticleOpenURLParams() + { + $params = $this->getDefaultOpenURLParams(); + // unset default title -- we only want jtitle/atitle here: + //$params['rft_val_fmt'] = 'info:ofi/fmt:kev:mtx:journal'; + $params['genre'] = 'article'; + if (isset($this->aiRecord['finc.record_id'])) { + $params['rft_id'] = $this->aiRecord['finc.record_id']; + } + if (isset($this->aiRecord['rft.issn'])) { + foreach ($this->aiRecord['rft.issn'] as $issn) { + $params['issn'] = $issn; + } + } + // an article may have also an ISBN: + if (isset($this->aiRecord['rft.isbn'])) { + $params['isbn'] = $this->aiRecord['rft.isbn']; + } + if (isset($this->aiRecord['rft.ssn'])) { + $params['ssn'] = $this->aiRecord['rft.ssn']; + } + if (isset($this->aiRecord['rft.volume'])) { + $params['volume'] = $this->aiRecord['rft.volume']; + } + if (isset($this->aiRecord['rft.issue'])) { + $params['issue'] = $this->aiRecord['rft.issue']; + } + if (isset($this->aiRecord['rft.spage'])) { + $params['spage'] = $this->aiRecord['rft.spage']; + } + if (isset($this->aiRecord['rft.epage'])) { + $params['epage'] = $this->aiRecord['rft.epage']; + } + if (isset($this->aiRecord['rft.pages'])) { + $params['pages'] = $this->aiRecord['rft.pages']; + } + if (isset($this->aiRecord['rft.coden'])) { + $params['coden'] = $this->aiRecord['rft.coden']; + } + if (isset($this->aiRecord['rft.artnum'])) { + $params['artnum'] = $this->aiRecord['rft.artnum']; + } + if (isset($this->aiRecord['rft.sici'])) { + $params['sici'] = $this->aiRecord['rft.sici']; + } + if (isset($this->aiRecord['rft.chron'])) { + $params['chron'] = $this->aiRecord['rft.chron']; + } + if (isset($this->aiRecord['rft.quarter'])) { + $params['quarter'] = $this->aiRecord['rft.quarter']; + } + if (isset($this->aiRecord['rft.part'])) { + $params['part'] = $this->aiRecord['rft.part']; + } + if (isset($this->aiRecord['rft.jtitle'])) { + $params['jtitle'] = $this->getJTitle(); + } + if (isset($this->aiRecord['rft.atitle'])) { + $params['atitle'] = $this->getATitle(); + } + if (isset($this->aiRecord['rft.stitle'])) { + $params['stitle'] = $this->aiRecord['rft.stitle']; + } + if (isset($this->aiRecord['authors'])) { + foreach ($this->aiRecord['authors'] as $author) { + if (isset($author['rft.au'])) { + $params['au'] = $author['rft.au']; + } + if (isset($author['rft.aulast'])) { + $params['aulast'] = $author['rft.aulast']; + } + if (isset($author['rft.aucorp'])) { + $params['aucorp'] = $author['rft.aucorp']; + } + if (isset($author['rft.auinitm'])) { + $params['auinitm'] = $author['rft.auinitm']; + } + if (isset($author['rft.aufirst'])) { + $params['aufirst'] = $author['rft.aufirst']; + } + if (isset($author['rft.auinit'])) { + $params['auinit'] = $author['rft.auinit']; + } + if (isset($author['rft.auinit1'])) { + $params['auinit1'] = $author['rft.auinit1']; + } + if (isset($author['rft.ausuffix'])) { + $params['ausuffix'] = $author['rft.ausuffix']; + } + } + } + + if (isset($this->aiRecord['rft.format'])) { + $params['format'] = $this->aiRecord['rft.format']; + } + if (isset($this->aiRecord['doi'])) { + $params['rft_id'] = 'info:doi/'.$this->aiRecord['doi']; + } + if (isset($this->aiRecord['languages'])) { + $params['rft.language'] = $this->aiRecord['languages']; + } + if (isset($this->aiRecord['rft.date'])) { + $params['rft.date'] = $this->aiRecord['rft.date']; + } + return $params; + } + + /** + * Get OpenURL parameters for a book. + * + * @return array + */ + protected function getBookOpenURLParams() + { + $params = $this->getDefaultOpenURLParams(); + $params['rft_val_fmt'] = 'info:ofi/fmt:kev:mtx:book'; + $params['genre'] = 'book'; + if (isset($this->aiRecord['rft.atitle'])) { + $params['atitle'] = $this->getATitle(); + } + if (isset($this->aiRecord['rft.btitle'])) { + $params['rft.btitle'] = $this->getBTitle(); + } + if (isset($this->aiRecord['finc.record_id'])) { + $params['rft_id'] = $this->aiRecord['finc.record_id']; + } + if (isset($this->aiRecord['rft.issn'])) { + foreach ($this->aiRecord['rft.issn'] as $issn) { + $params['issn'] = $issn; + } + } + if (isset($this->aiRecord['rft.edition'])) { + $params['edition'] = $this->aiRecord['rft.edition']; + } + // an article may have also an ISBN: + if (isset($this->aiRecord['rft.isbn'])) { + $params['isbn'] = $this->aiRecord['rft.isbn']; + } + if (isset($this->aiRecord['rft.ssn'])) { + $params['ssn'] = $this->aiRecord['rft.ssn']; + } + if (isset($this->aiRecord['rft.eissn'])) { + $params['eissn'] = $this->aiRecord['rft.eissn']; + } + if (isset($this->aiRecord['rft.volume'])) { + $params['volume'] = $this->aiRecord['rft.volume']; + } + if (isset($this->aiRecord['rft.issue'])) { + $params['issue'] = $this->aiRecord['rft.issue']; + } + if (isset($this->aiRecord['rft.spage'])) { + $params['spage'] = $this->aiRecord['rft.spage']; + } + if (isset($this->aiRecord['rft.epage'])) { + $params['epage'] = $this->aiRecord['rft.epage']; + } + if (isset($this->aiRecord['rft.pages'])) { + $params['pages'] = $this->aiRecord['rft.pages']; + } + if (isset($this->aiRecord['rft.series'])) { + $params['series'] = $this->aiRecord['rft.series']; + } + if (isset($this->aiRecord['rft.tpages'])) { + $params['tpages'] = $this->aiRecord['rft.tpages']; + } + if (isset($this->aiRecord['rft.bici'])) { + $params['bici'] = $this->aiRecord['rft.bici']; + } + if (isset($this->aiRecord['authors'])) { + foreach ($this->aiRecord['authors'] as $author) { + if (isset($author['rft.au'])) { + $params['au'] = $author['rft.au']; + } + if (isset($author['rft.aulast'])) { + $params['aulast'] = $author['rft.aulast']; + } + if (isset($author['rft.aucorp'])) { + $params['aucorp'] = $author['rft.aucorp']; + } + if (isset($author['rft.auinitm'])) { + $params['auinitm'] = $author['rft.auinitm']; + } + if (isset($author['rft.aufirst'])) { + $params['aufirst'] = $author['rft.aufirst']; + } + if (isset($author['rft.auinit'])) { + $params['auinit'] = $author['rft.auinit']; + } + if (isset($author['rft.auinit1'])) { + $params['auinit1'] = $author['rft.auinit1']; + } + if (isset($author['rft.ausuffix'])) { + $params['ausuffix'] = $author['rft.ausuffix']; + } + } + } + + if (isset($this->aiRecord['rft.format'])) { + $params['format'] = $this->aiRecord['rft.format']; + } + if (isset($this->aiRecord['doi'])) { + $params['rft_id'] = 'info:doi/'.$this->aiRecord['doi']; + } + $publishers = $this->getPublishers(); + if (count($publishers) > 0) { + $params['rft.pub'] = $publishers[0]; + } + return $params; + } + + /** + * Retrieve raw data from object (primarily for use in staff view and + * autocomplete; avoid using whenever possible). + * + * @return mixed + */ + public function getRawData() + { + $tmp = array(); + $i = 0; + if (!empty($this->aiRecord)) { + foreach ($this->aiRecord as $key => $value) { + $tmp[$i]['key'] = $key; + $tmp[$i]['value'] = $value; + $i++; + } + } + return $tmp; + } + + /** + * Retrieve data from ai-blobserver + * + * @param string $id Record Id of the raw recorddata to be retrieved + * @param string $baseUrl The Ai fullrecord server url. + * + * @return mixed Raw curl request response (should be json). + * @throws Exception + */ + protected function retrieveAiFullrecord($id, $baseUrl) + { + if (!isset($id)) { + throw new Exception('no id given'); + } + + $url = sprintf($baseUrl, $id); + + $curlDefaultOptions = array( + CURLOPT_RETURNTRANSFER => true, + CURLOPT_SSL_VERIFYPEER => true, + CURLOPT_USERAGENT => "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" + ); + $curlOptions = array(); + $curlOptions[CURLOPT_URL] = $url; + $handle = curl_init(); + $curl_options = $curlDefaultOptions + $curlOptions; + curl_setopt_array($handle, $curl_options); + $response = curl_exec($handle); + if (false === $response) { + throw new Exception(curl_error($handle)); + } + return $response; + } + + /** + * Returns the AI fullrecord as decoded json. + * + * @param string $id Record id to be retrieved. + * + * @return array + * @throws \Exception + */ + protected function getAIJSONFullrecord($id) + { + if (!isset($this->recordConfig->General)) { + throw new \Exception('SolrAI General settings missing.'); + } + + $baseUrl = $this->recordConfig->General->baseUrl; + + if (!isset($baseUrl)) { + throw new \Exception('no ai-blobserver configurated'); + } + + $response = $this->retrieveAiFullrecord($id, $baseUrl); + + return json_decode($response, true); + } + + /** + * returns the value of a certain record key or the default value if not exists + * + * @param string $key of record array + * @param mixed $default [optional] return value + * + * @return mixed value of key + * @access private + */ + private function _getAIFullrecordStringValue($key, $default = '') + { + if (!$this->_hasAIFullrecordStringValue($key)) { + if ($this->_hasAIFullrecordArrayValue($key)) { + return implode(',', $this->aiRecord[$key]); + } + return $default; + } + + return $this->aiRecord[$key]; + } + + /** + * returns the value of a certain record key or the default value if not exists + * + * @param string $key of record array + * @param mixed $default [optional] return value + * + * @return mixed value of key + * @access private + */ + private function _getAIFullrecordArrayValue($key, $default = array()) + { + if (!$this->_hasAIFullrecordArrayValue($key)) { + return $default; + } + return $this->aiRecord[$key]; + } + + /** + * checks whether a certain array key exists and is not empty in record data array + * + * @param string $key Key to be checked. + * + * @return boolean true or false + * @access private + */ + private function _hasAIFullrecordStringValue($key) + { + if (empty($this->aiRecord)) { + $this->aiRecord = $this->getAIJSONFullrecord($this->fields['id']); + } + if (isset($this->aiRecord[$key]) + && !empty($this->aiRecord[$key]) + && !is_array($this->aiRecord[$key]) + ) { + return true; + } + + return false; + } + + + /** + * checks whether a certain array key exists, is an array and has elements in + * record data array + * + * @param string $key Key to be checked + * + * @return boolean true or false + * @access private + */ + private function _hasAIFullrecordArrayValue($key) + { + if (empty($this->aiRecord)) { + $this->aiRecord = $this->getAIJSONFullrecord($this->fields['id']); + } + if (isset($this->aiRecord[$key]) + && is_array($this->aiRecord[$key]) + && count($this->aiRecord[$key]) > 0 + ) { + return true; + } + + return false; + } + + /** + * checks whether record has start pages + * + * @return boolean + */ + public function hasStartpages() + { + if (isset($this->aiRecord['rft.spage']) + && !empty($this->aiRecord['rft.spage']) + ) { + return true; + } + + return false; + } + + /** + * checks whether record has Endpages + * + * @return boolean + */ + public function hasEndpages() + { + if (isset($this->aiRecord['rft.epage']) + && !empty($this->aiRecord['rft.epage']) + ) { + return true; + } + + return false; + } + + +} diff --git a/module/finc/src/finc/RecordDriver/SolrDefault.php b/module/finc/src/finc/RecordDriver/SolrDefault.php index 0b84d2a28ca..672cd5abc89 100644 --- a/module/finc/src/finc/RecordDriver/SolrDefault.php +++ b/module/finc/src/finc/RecordDriver/SolrDefault.php @@ -100,7 +100,6 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * @deprecated Should also be possible to be dropped (@see getLocalFormat()) * * @return array - * @access protected */ public function getFormat() { @@ -113,7 +112,6 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * format_{indexExtension}, format otherwise. * * @return array Array with formats associated with the record. - * @access protected */ public function getFormats() { @@ -144,7 +142,6 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * @todo Should be moved out of RecordDriver (Controller/View?) * * @return array - * @access protected */ /* protected function getFormatIcon() { @@ -186,9 +183,8 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * Get the GND of an author. * * @return array - * @access protected */ - protected function getAuthorId() + public function getAuthorId() { return isset($this->fields['author_id']) ? $this->fields['author_id'] : array(); @@ -200,10 +196,9 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * @todo Check whether static call of getCorporateAuthor is necessary * * @return array - * @access protected * @link https://intern.finc.info/issues/1866 */ - protected function getCombinedAuthors() + public function getCombinedAuthors() { $retval = array(); @@ -233,9 +228,8 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * Get the original author of the record. * * @return string - * @access protected */ - protected function getPrimaryAuthorOrig() + public function getPrimaryAuthorOrig() { return isset($this->fields['author_orig']) ? $this->_filterAuthorDates($this->fields['author_orig']) : ''; @@ -245,10 +239,9 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * Get the main author of the record. * * @return string - * @access protected * @deprecated */ - protected function getPrimaryAuthorRaw() + public function getPrimaryAuthorRaw() { return isset($this->fields['author']) ? $this->_removeAuthorDates($this->fields['author']) : ''; @@ -270,9 +263,8 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * Get the secondary corporate authors (if any) for the record. * * @return array - * @access protected */ - protected function getCorporateSecondaryAuthors() + public function getCorporateSecondaryAuthors() { return isset($this->fields['author_corp2']) ? $this->fields['author_corp2'] : array(); @@ -282,9 +274,8 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * Get an array of all ISMNs associated with the record (may be empty). * * @return array - * @access protected */ - protected function getISMNs() + public function getISMNs() { return isset($this->fields['ismn']) && is_array($this->fields['ismn']) ? $this->fields['ismn'] : array(); @@ -294,9 +285,8 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * Get an array of newer titles for the record. * * @return array - * @access protected */ - protected function getNewTitles() + public function getNewTitles() { return isset($this->fields['title_new']) ? $this->fields['title_new'] : array(); @@ -310,11 +300,10 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * @todo 1. Check if this method is still needed * @todo 2. Refactor Solr-Query to be compatible with VuFind2 * - * @param array $rids Array of record ids to test. + * @param array $rids Array of record ids to test. * - * @return int mixed If success return at least one finc id otherwise null. - * @access protected - * @deprecated Not used. + * @return int mixed If success return at least one finc id otherwise null. + * @deprecated Not used. */ protected function addFincIDToRecord ( $array ) { /* @@ -390,10 +379,9 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * Get percentage of relevance of a title. First implementaion for TUBAF. * * @return float Percentage of Score / Maximum Score rounded by 5. - * @access protected * @link https://intern.finc.info/issues/1908 */ - protected function getRelevance() { + public function getRelevance() { $score = isset($this->fields['score']) ? $this->fields['score'] : 0; $maxScore = isset($this->fields['score_maximum']) ? $this->fields['score_maximum'] : 0; @@ -408,9 +396,8 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * Get RVK classifcation number from Solr index. * * @return string - * @access protected */ - protected function getRvk() { + public function getRvk() { return isset($this->fields['rvk_facet']) ? $this->fields['rvk_facet'] : ''; } @@ -421,7 +408,6 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * @todo refactor to a more meaningful name? * * @return string - * @access protected */ public function getRID() { @@ -433,9 +419,8 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * Get the original title of the record. * * @return string - * @access protected */ - protected function getTitleOrig() + public function getTitleOrig() { return isset($this->fields['title_orig']) ? $this->fields['title_orig'] : ''; @@ -445,9 +430,8 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * Get the GND of topic. * * @return array - * @access protected */ - protected function getTopicId() + public function getTopicId() { return isset($this->fields['topic_id']) ? $this->fields['topic_id'] : array(); @@ -457,9 +441,8 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * Get alternatives series titles as array. * * @return array - * @access protected */ - protected function getSeriesAlternative() + public function getSeriesAlternative() { if (isset($this->fields['series2']) && !empty($this->fields['series2'])) { return $this->fields['series2']; @@ -471,9 +454,8 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * Get alternatives series titles as array. * * @return array - * @access protected */ - protected function getSeriesOrig() + public function getSeriesOrig() { if (isset($this->fields['series_orig']) && !empty($this->fields['series_orig'])) { return $this->fields['series_orig']; @@ -485,11 +467,11 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * Filter author data for author year of birth and death * to give a better mark up. * - * @param string authordata + * @param string $authordata + * * @return strings - * @access protected */ - protected function _filterAuthorDates( $authordata ) + private function _filterAuthorDates( $authordata ) { if (preg_match('/^(\s|.*)(\d{4})\s?-?\s?(\d{4})?$/Uu',$authordata, $match)) { return (isset($match[3])) @@ -505,10 +487,9 @@ class SolrDefault extends \VuFind\RecordDriver\SolrDefault * @param string authordata * * @return strings - * @access protected * @deprecated */ - protected function _removeAuthorDates( $authordata ) + private function _removeAuthorDates( $authordata ) { if (preg_match('/^(\s|.*)\s(fl.\s|d.\s|ca.\s)*\s?(\d{4})\??(\sor\s\d\d?)?\s?(-|–)?\s?(ca.\s|after\s)?(\d{1,4})?(.|,)?$/Uu',$authordata, $match)) { return (isset($match[1])) ? $match[1] : $authordata; diff --git a/module/finc/src/finc/Resolver/Driver/Factory.php b/module/finc/src/finc/Resolver/Driver/Factory.php new file mode 100644 index 00000000000..f17535739c6 --- /dev/null +++ b/module/finc/src/finc/Resolver/Driver/Factory.php @@ -0,0 +1,58 @@ +<?php +/** + * Resolver Driver Factory Class + * + * PHP version 5 + * + * Copyright (C) Villanova University 2014. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @category VuFind2 + * @package Resolver_Drivers + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:hierarchy_components Wiki + */ +namespace finc\Resolver\Driver; +use Zend\ServiceManager\ServiceManager; + +/** + * Resolver Driver Factory Class + * + * @category VuFind2 + * @package Resolver_Drivers + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:hierarchy_components Wiki + */ +class Factory +{ + + /** + * Factory for Redi record driver. + * + * @param ServiceManager $sm Service manager. + * + * @return Redi + */ + public static function getRedi(ServiceManager $sm) + { + $config = $sm->getServiceLocator()->get('VuFind\Config')->get('config'); + return new Redi( + $config->OpenURL->url, + $sm->getServiceLocator()->get('VuFind\Http')->createClient() + ); + } +} \ No newline at end of file diff --git a/module/finc/src/finc/Resolver/Driver/Redi.php b/module/finc/src/finc/Resolver/Driver/Redi.php new file mode 100644 index 00000000000..cb38f91904f --- /dev/null +++ b/module/finc/src/finc/Resolver/Driver/Redi.php @@ -0,0 +1,318 @@ +<?php +/** + * ReDi Link Resolver Driver + * + * PHP version 5 + * + * Copyright (C) Leipzig University Library 2015 + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @category VuFind2 + * @package Resolver_Drivers + * @author Gregor Gawol <gawol@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:link_resolver_drivers Wiki + */ +namespace finc\Resolver\Driver; +use DOMDocument; + +/** + * ReDi Link Resolver Driver + * + * @category VuFind2 + * @package Resolver_Drivers + * @author Gregor Gawol <gawol@ub.uni-leipzig.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:link_resolver_drivers Wiki + */ +class Redi implements \VuFind\Resolver\Driver\DriverInterface +{ + /** + * Base URL for link resolver + * + * @var string + */ + protected $baseUrl; + + /** + * HTTP client + * + * @var \Zend\Http\Client + */ + protected $httpClient; + + /** + * Base URL for link resolver + * + * @var string + */ + protected $doc; + + /** + * Constructor + * + * @param string $baseUrl Base URL for link resolver + * @param \Zend\Http\Client $httpClient HTTP client + */ + public function __construct($baseUrl, \Zend\Http\Client $httpClient) + { + $this->baseUrl = $baseUrl; + $this->httpClient = $httpClient; + } + + /** + * Fetch Links + * + * Fetches a set of links corresponding to an OpenURL + * + * @param string $openURL openURL (url-encoded) + * + * @return string raw XML returned by resolver + */ + public function fetchLinks($openURL) + { + $url = $this->baseUrl.'&'.$openURL; + $feed = $this->httpClient->setUri($url)->send()->getBody(); + return $feed; + } + + + /** + * Parse Links + * + * Parses an XML file returned by a link resolver + * and converts it to a standardised format for display + * + * @param string $xmlstr Raw XML returned by resolver + * + * @return array Array of values + */ + public function parseLinks($xmlstr) + { + $retval = array(); + $xml = new DOMDocument(); + if (!@$xml->loadHTML($xmlstr)) { + return $retval; + } + + $this->parseDOI($xml, $retval); + $this->parseRediInfo($xml, $retval); + $this->parseRediOpenURLs($xml, $retval); + + return $retval; + } + + /** + * Parse if the Redi xml snippet contains a DOI. + * + * @param DOMDocument $xml Loaded xml document + * @param array &$retval Get back a array with title, URL and service_type + * + * @return void + * @access private + */ + protected function parseDOI ($xml, &$retval) + { + $citation = $xml->getElementById('citation'); + if (is_object($citation->childNodes)) { + foreach ($citation->childNodes as $deflist) { + if (is_object($deflist->childNodes)) { + foreach ($deflist->childNodes as $defterm) { + $tmp = []; + if ($defterm->hasAttributes()) { + $elem = $defterm->getAttribute('class'); + if ($elem == 'doi_t') { + $doiText = trim($defterm->nodeValue); + $tmp['title'] = $doiText; + } + if ($elem == 'doi_d') { + $doiURL = trim($this->getRediLink($defterm)); + $tmp['href'] = $doiURL; + } + } + $tmp['service_type'] = 'getDOI'; + + if (!empty($tmp['title']) && !empty($tmp['href'])) { + $retval[] = $tmp; + } + } + } + } + } + } + + /** + * Parse if the Redi xml snippet contains information about the Redi offer. + * + * @param DOMDocument $xml Loaded xml document + * @param array &$retval Return array with Redi catalogue information + * consisting of Text & Link. + * + * @return void + * @access protected + */ + protected function parseRediInfo($xml, &$retval) + { + if ($ezb = $xml->getElementById('t_ezb')) { + if (is_object($ezb->childNodes)) { + foreach ($ezb->childNodes as $divClassT) { + if (is_object($divClassT->childNodes)) { + foreach ($divClassT->childNodes as $nodes) { + // infotext + + if ($nodes->nodeName == 'p') { + $tmp = []; + $rediInfoText = trim($nodes->firstChild->nodeValue); + if ($this->isRediOpenURLsWithInfo($xml)) { + $rediInfoInfo = trim($nodes->nodeValue); + } + $rediInfoURL = trim($this->getRediLink($nodes)); + if (is_object($nodes->childNodes)) { + foreach ($nodes->childNodes as $bold) { + if ($bold->nodeName == 'b') { + $rediInfoText = $rediInfoText + .' '.trim($bold->nodeValue); + } + } + } + $tmp['title'] = (isset($rediInfoText)? + $rediInfoText:''); + $tmp['href'] = (isset($rediInfoURL)? + $rediInfoURL:''); + $tmp['info'] = (isset($rediInfoInfo)? + $rediInfoInfo:''); + $tmp['service_type'] = 'getHolding'; + + if (!empty($tmp['title']) && !empty($tmp['href'])) { + $retval[] = $tmp; + } + } + } + } + } + } + } + } + + /** + * Parse if the Redi xml snippet contains Redi urls. + * + * @param DOMDocument $xml Loaded xml document + * @param array &$retval Get back Redi direct link to sources + * containing title, URL and service_type + * + * @return void + * @access protected + */ + protected function parseRediOpenURLs($xml, &$retval) + { + if ($ezb = $xml->getElementById('t_ezb')) { + if (is_object($ezb->childNodes)) { + foreach ($ezb->childNodes as $divClassT) { + if (is_object($divClassT->childNodes)) { + foreach ($divClassT->childNodes as $nodes) { + $tmp = []; + // fulltext + if ($nodes->nodeName == 'div') { + $text = trim( + str_replace( + array('»', + chr(194).chr(160) + ), + array('', ''), + $nodes->nodeValue + ) + ); // hack to replace \u00a0 + $available = $nodes->getElementsByTagName('span'); + foreach ($available as $span) { + if ($span->hasAttributes()) { + $class = $span->getAttribute('class'); + if ($class == 't_link') { + $url = $this->getRediLink($nodes); + } + } + } + $tmp['title'] = (isset($text)?$text:''); + $tmp['href'] = (isset($url)?$url:''); + $tmp['service_type'] = 'getFullTxt'; + + if (!empty($tmp['title']) && !empty($tmp['href'])) { + $retval[] = $tmp; + } + } + } // end foreach + } // end if + } // end foreach + } // end if + } // end if + } + + /** + * Is a star in ReDi links text snippet + * + * @param DOMDocument $xml loaded xml document + * + * @return bool + * @access protected + */ + protected function isRediOpenURLsWithInfo($xml) + { + if ($ezb = $xml->getElementById('t_ezb')) { + if (is_object($ezb->childNodes)) { + foreach ($ezb->childNodes as $divClassT) { + if (is_object($divClassT->childNodes)) { + foreach ($divClassT->childNodes as $nodes) { + if ($nodes->nodeName == 'div') { + $text = trim( + str_replace( + array('»', + chr(194).chr(160) + ), + array('',''), + $nodes->nodeValue + ) + ); // hack to replace \u00a0 + if (preg_match('/.*(\*).*/', $text)) { + return true; + } + } + } // end foreach + } // end if + } // end foreach + } // end if + } // end if + return false; + } + + /** + * Get the ReDi links of a DOM document snippet. + * + * @param object $doc Document snippet from ReDi site + * + * @return string Url of ReDi + * @access protected + */ + protected function getRediLink($doc) + { + $hrefs = $doc->getElementsByTagName('a'); + foreach ($hrefs as $a) { + if ($a->hasAttributes()) { + return $a->getAttribute('href'); + } + } + return ''; + } +} \ No newline at end of file diff --git a/module/finc/src/finc/View/Helper/Root/Factory.php b/module/finc/src/finc/View/Helper/Root/Factory.php new file mode 100644 index 00000000000..e0ad5a2c01b --- /dev/null +++ b/module/finc/src/finc/View/Helper/Root/Factory.php @@ -0,0 +1,56 @@ +<?php +/** + * Factory for Root view helpers. + * + * PHP version 5 + * + * Copyright (C) Villanova University 2014. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @category VuFind2 + * @package View_Helpers + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:developer_manual Wiki + */ +namespace finc\View\Helper\Root; +use Zend\ServiceManager\ServiceManager; + +/** + * Factory for Root view helpers. + * + * @category VuFind2 + * @package View_Helpers + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:developer_manual Wiki + */ +class Factory +{ + + /** + * Construct the Record helper. + * + * @param ServiceManager $sm Service manager. + * + * @return Record + */ + public static function getRecord(ServiceManager $sm) + { + return new Record( + $sm->getServiceLocator()->get('VuFind\Config')->get('config') + ); + } +} diff --git a/module/finc/src/finc/View/Helper/Root/Record.php b/module/finc/src/finc/View/Helper/Root/Record.php new file mode 100644 index 00000000000..9f5535a086f --- /dev/null +++ b/module/finc/src/finc/View/Helper/Root/Record.php @@ -0,0 +1,72 @@ +<?php +/** + * Record driver view helper + * + * PHP version 5 + * + * Copyright (C) Villanova University 2010. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @category VuFind2 + * @package View_Helpers + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:developer_manual Wiki + */ +namespace finc\View\Helper\Root; +use Zend\View\Exception\RuntimeException, Zend\View\Helper\AbstractHelper; + +/** + * Record driver view helper + * + * @category VuFind2 + * @package View_Helpers + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:developer_manual Wiki + */ +class Record extends \VuFind\View\Helper\Root\Record +{ + /** + * VuFind configuration + * + * @var \Zend\Config\Config + */ + protected $config; + + /** + * Constructor + * + * @param \Zend\Config\Config $config VuFind configuration + */ + public function __construct($config = null) + { + parent::__construct($config); + } + + /** + * Render the link of the type ISN. + * + * @param array $issns Array with ISSNS + * + * @return string + */ + public function getLinkISN($issns) + { + return $this->renderTemplate( + 'link-isn.phtml', array('issns' => $issns) + ); + } +} \ No newline at end of file diff --git a/themes/finc/js/openurl.js b/themes/finc/js/openurl.js new file mode 100644 index 00000000000..3a11b23995b --- /dev/null +++ b/themes/finc/js/openurl.js @@ -0,0 +1,41 @@ +/*global extractClassParams, path*/ + +function loadResolverLinks(target, openUrl) { + target.addClass('ajax_availability'); + var url = path + '/AJAX/JSON?' + $.param({method:'getResolverLinks',openurl:openUrl}); + $.ajax({ + dataType: 'json', + url: url, + success: function(response) { + if (response.status == 'OK') { + target.removeClass('ajax_availability') + .empty().append(response.data); + } else { + target.removeClass('ajax_availability').addClass('error') + .empty().append(response.data); + } + } + }); +} + +var redi = { + init: function(doc){ + var params = extractClassParams(doc); + var openUrl = $(doc).children('span.openUrl:first').attr('title'); + $(doc).hide(); + loadResolverLinks($('#openUrlEmbed'+params.openurl_id).removeClass('hidden'), openUrl); + return false; + } +} + +$(document).ready(function() { + // assign action to the openUrlWindow link class + $('a.openUrlWindow').click(function(){ + var params = extractClassParams(this); + var settings = params.window_settings; + window.open($(this).attr('href'), 'openurl', settings); + return false; + }); + + redi.init($('a.openUrlEmbed')); +}); \ No newline at end of file diff --git a/themes/finc/templates/RecordDriver/SolrAI/core.phtml b/themes/finc/templates/RecordDriver/SolrAI/core.phtml new file mode 100644 index 00000000000..fc36192f92a --- /dev/null +++ b/themes/finc/templates/RecordDriver/SolrAI/core.phtml @@ -0,0 +1,264 @@ +<div class="row" vocab="http://schema.org/" resource="#record" typeof="<?=$this->driver->getSchemaOrgFormats()?> Product"> + <div class="col-sm-3"> + <div class="text-center"> + <? /* Display thumbnail if appropriate: */ ?> + <? $mediumThumb = $this->record($this->driver)->getThumbnail('medium'); $largeThumb = $this->record($this->driver)->getThumbnail('large'); ?> + <? if ($mediumThumb): ?> + <? if ($largeThumb): ?><a href="<?=$this->escapeHtmlAttr($largeThumb)?>"><? endif; ?> + <img alt="<?=$this->transEsc('Cover Image')?>" class="recordcover" src="<?=$this->escapeHtmlAttr($mediumThumb);?>"/> + <? if ($largeThumb): ?></a><? endif; ?> + <? else: ?> + <img src="<?=$this->url('cover-unavailable')?>" class="recordcover" alt="<?=$this->transEsc('No Cover Image')?>"/> + <? endif; ?> + + <? /* Display qrcode if appropriate: */ ?> + <? $QRCode = $this->record($this->driver)->getQRCode("core"); ?> + <? if($QRCode): ?> + <span class="hidden-xs"> + <br/><img alt="<?=$this->transEsc('QR Code')?>" class="qrcode" src="<?=$this->escapeHtmlAttr($QRCode);?>"/> + </span> + <? endif; ?> + </div> + + <?=$this->record($this->driver)->getPreviews()?> + </div> + + <div class="col-sm-9"> + <h3 property="name"><?=$this->escapeHtml($this->driver->getTitle())?></h3> + + <? $summary = $this->driver->getSummary(); $summary = isset($summary[0]) ? $summary[0] : false; ?> + <? if ($summary): ?> + <p><?=$this->truncate($summary, 300)?></p> + + <? if(strlen($summary) > 300): ?> + <p><a href='<?=$this->recordLink()->getTabUrl($this->driver, 'Description')?>#tabnav'><?=$this->transEsc('Full description')?></a></p> + <? endif; ?> + <? endif; ?> + + <? if ($this->userlist()->getMode() !== 'disabled'): ?> + <? /* Display the lists that this record is saved to */ ?> + <div class="savedLists hidden alert alert-info" id="savedLists"> + <strong><?=$this->transEsc("Saved in")?>:</strong> + </div> + <? endif; ?> + + <?/* Display Main Details */?> + <table class="table table-striped" summary="<?=$this->transEsc('Bibliographic Details')?>"> + <? $journalTitle = $this->driver->getContainerTitle(); if (!empty($journalTitle)): ?> + <tr> + <th><?=$this->transEsc('Journal Title')?>:</th> + <td> + <a href="<?=$this->record($this->driver)->getLink('journaltitle', $journalTitle)?>"><?=$this->escapeHtml($journalTitle)?></a> + <? $ref = $this->driver->getContainerReference(); if (!empty($ref)) { echo $this->escapeHtml($ref); } ?> + </td> + </tr> + <? endif; ?> + + <? $nextTitles = $this->driver->getNewerTitles(); $prevTitles = $this->driver->getPreviousTitles(); ?> + <? if (!empty($nextTitles)): ?> + <tr> + <th><?=$this->transEsc('New Title')?>: </th> + <td> + <? foreach($nextTitles as $field): ?> + <a href="<?=$this->record($this->driver)->getLink('title', $field)?>"><?=$this->escapeHtml($field)?></a><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? if (!empty($prevTitles)): ?> + <tr> + <th><?=$this->transEsc('Previous Title')?>: </th> + <td> + <? foreach($prevTitles as $field): ?> + <a href="<?=$this->record($this->driver)->getLink('title', $field)?>"><?=$this->escapeHtml($field)?></a><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $authors = $this->driver->getDeduplicatedAuthors(); ?> + <? if (isset($authors['main']) && !empty($authors['main'])): ?> + <tr> + <th><?=$this->transEsc('Main Author')?>: </th> + <td property="author"><a href="<?=$this->record($this->driver)->getLink('author', $authors['main'])?>"><?=$this->escapeHtml($authors['main'])?></a></td> + </tr> + <? endif; ?> + + <? if (isset($authors['corporate']) && !empty($authors['corporate'])): ?> + <tr> + <th><?=$this->transEsc('Corporate Author')?>: </th> + <td property="creator"><a href="<?=$this->record($this->driver)->getLink('author', $authors['corporate'])?>"><?=$this->escapeHtml($authors['corporate'])?></a></td> + </tr> + <? endif; ?> + + <? if (isset($authors['secondary']) && !empty($authors['secondary'])): ?> + <tr> + <th><?=$this->transEsc('Other Authors')?>: </th> + <td> + <? $i = 0; foreach ($authors['secondary'] as $field): ?><?=($i++ == 0)?'':', '?><span property="contributor"><a href="<?=$this->record($this->driver)->getLink('author', $field)?>"><?=$this->escapeHtml($field)?></a></span><? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $aidatain = $this->driver->getAIDataIn(); if (!empty($aidatain)): ?> + <tr> + <th><?=$this->transEsc('In')?>: </th> + <td> + <? $issns = $aidatain['issns']; if (!empty($issns)): ?> + <a href="<?=$this->record($this->driver)->getLinkISN($issns)?>"> + <? $jtitle = $aidatain['jtitle']; + if (!empty($jtitle)): ?><?=$this->escapeHtml($jtitle)?><? endif; ?> + </a><? endif; ?><? $volume = $aidatain['volume']; if (!empty($volume)): ?>, <?=$this->escapeHtml($volume) ?><? endif; ?><? $date = $aidatain['date']; if (!empty($date)): ?><? if (empty($volume)): ?>, <? endif; ?>(<?=$this->escapeHtml($date) ?>)<? endif; ?><? $issue = $aidatain['issue']; if (!empty($issue)): ?>, <?=$this->escapeHtml($issue) ?><? endif; ?><? $pages = $aidatain['pages']; if (!empty($pages)): ?>, <?=$this->transEsc('p.')?> <?=$this->escapeHtml($pages) ?><? endif; ?> + </td> + </tr> + <? endif; ?> + + <? $publications = $this->driver->getPublicationDetails(); if (!empty($publications)): ?> + <tr> + <th><?=$this->transEsc('Published')?>: </th> + <td> + <? foreach ($publications as $field): ?> + <span property="publisher" typeof="Organization"> + <? $pubPlace = $field->getPlace(); if (!empty($pubPlace)): ?> + <span property="location"><?=$this->escapeHtml($pubPlace)?></span> + <? endif; ?> + <? $pubName = $field->getName(); if (!empty($pubName)): ?> + <span property="name"><?=$this->escapeHtml($pubName)?></span> + <? endif; ?> + </span> + <? $pubDate = $field->getDate(); if (!empty($pubDate)): ?> + <span property="publicationDate"><?=$this->escapeHtml($pubDate)?></span> + <? endif; ?> + <br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $formats = $this->driver->getFormats(); if (!empty($formats)): ?> + <tr> + <th><?=$this->transEsc('Format')?>: </th> + <td><?=$this->record($this->driver)->getFormatList()?></td> + </tr> + <? endif; ?> + + <? $langs = $this->driver->getLanguages(); if (!empty($langs)): ?> + <tr> + <th><?=$this->transEsc('Language')?>: </th> + <td><? foreach ($langs as $lang): ?><?= $this->escapeHtml($lang)?><br/><? endforeach; ?></td> + </tr> + <? endif; ?> + + <? $edition = $this->driver->getEdition(); if (!empty($edition)): ?> + <tr> + <th><?=$this->transEsc('Edition')?>: </th> + <td property="bookEdition"><?=$this->escapeHtml($edition)?></td> + </tr> + <? endif; ?> + + <?/* Display series section if at least one series exists. */?> + <? $series = $this->driver->getSeries(); if (!empty($series)): ?> + <tr> + <th><?=$this->transEsc('Series')?>: </th> + <td> + <? foreach ($series as $field): ?> + <?/* Depending on the record driver, $field may either be an array with + "name" and "number" keys or a flat string containing only the series + name. We should account for both cases to maximize compatibility. */?> + <? if (is_array($field)): ?> + <? if (!empty($field['name'])): ?> + <a href="<?=$this->record($this->driver)->getLink('series', $field['name'])?>"><?=$this->escapeHtml($field['name'])?></a> + <? if (!empty($field['number'])): ?> + <?=$this->escapeHtml($field['number'])?> + <? endif; ?> + <br/> + <? endif; ?> + <? else: ?> + <a href="<?=$this->record($this->driver)->getLink('series', $field)?>"><?=$this->escapeHtml($field)?></a><br/> + <? endif; ?> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $subjects = $this->driver->getAllSubjectHeadings(); if (!empty($subjects)): ?> + <tr> + <th><?=$this->transEsc('Subjects')?>: </th> + <td> + <? foreach ($subjects as $field): ?> + <div class="subjectLine" property="keywords"> + <? $subject = ''; ?> + <? if(count($field) == 1) $field = explode('--', $field[0]); ?> + <? $i = 0; foreach ($field as $subfield): ?> + <?=($i++ == 0) ? '' : ' > '?> + <? $subject = trim($subject . ' ' . $subfield); ?> + <a class="backlink" title="<?=$this->escapeHtmlAttr($subject)?>" href="<?=$this->record($this->driver)->getLink('subject', $subject)?>"><?=trim($this->escapeHtml($subfield))?></a> + <? endforeach; ?> + </div> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <?/* + $openUrl = $this->driver->openURLActive('record') ? $this->driver->getOpenURL() : false; + // Account for replace_other_urls setting + $urls = ($openUrl && $this->driver->replaceURLsWithOpenURL()) ? array() : $this->record($this->driver)->getLinkDetails(); + ?> + <? if (!empty($urls) || $openUrl): ?> + <tr> + <th><?=$this->transEsc('Online Access')?>: </th> + <td> + <? foreach ($urls as $current): ?> + <a href="<?=$this->escapeHtmlAttr($this->proxyUrl($current['url']))?>"><?=$this->escapeHtml($current['desc'])?></a><br/> + <? endforeach; ?> + <? if ($openUrl): ?> + <?=$this->openUrl($openUrl)?><br/> + <? endif; ?> + </td> + </tr> + <? endif; */?> + + <? $recordLinks = $this->driver->getAllRecordLinks(); ?> + <? if(!empty($recordLinks)): ?> + <tr> + <th><?=$this->transEsc('Related Items')?>:</th> + <td> + <? foreach ($recordLinks as $recordLink): ?> + <?=$this->transEsc($recordLink['title'])?>: + <a href="<?=$this->recordLink()->related($recordLink['link'])?>"><?=$this->escapeHtml($recordLink['value'])?></a><br /> + <? endforeach; ?> + <? /* if we have record links, display relevant explanatory notes */ + $related = $this->driver->getRelationshipNotes(); + if (!empty($related)): ?> + <? foreach ($related as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + <? endif; ?> + </td> + </tr> + <? endif; ?> + + <? if ($this->usertags()->getMode() !== 'disabled'): ?> + <? $tagList = $this->driver->getTags(); ?> + <tr> + <th><?=$this->transEsc('Tags')?>: </th> + <td> + <span class="pull-right"> + <i class="fa fa-plus"></i> <a id="tagRecord" class="modal-link" href="<?=$this->recordLink()->getActionUrl($this->driver, 'AddTag')?>" title="<?=$this->transEsc('Add Tag')?>"><?=$this->transEsc('Add Tag')?></a> + </span> + <div id="tagList"> + <? if (count($tagList) > 0): ?> + <? $i = 0; foreach ($tagList as $tag): ?><?=($i++ == 0)?'':', '?><a href="<?=$this->url('tag-home')?>?lookfor=<?=urlencode($tag->tag)?>"><?=$this->escapeHtml($tag->tag)?></a> (<?=$this->escapeHtml($tag->cnt)?>)<? endforeach; ?> + <? else: ?> + <?=$this->transEsc('No Tags')?>, <?=$this->transEsc('Be the first to tag this record')?>! + <? endif; ?> + </div> + </td> + </tr> + <? endif; ?> + </table> + <?/* End Main Details */?> + </div> +</div> diff --git a/themes/finc/templates/RecordDriver/SolrAI/link-isn.phtml b/themes/finc/templates/RecordDriver/SolrAI/link-isn.phtml new file mode 100644 index 00000000000..80531d8f5f9 --- /dev/null +++ b/themes/finc/templates/RecordDriver/SolrAI/link-isn.phtml @@ -0,0 +1 @@ +<?=$this->url('search-results')?>?join=AND&bool0[]=AND&<? $issns = $this->issns; if (isset($issns)): ?><? foreach ($issns as $issn): ?>lookfor0[]=<?=$this->escapeHtml($issn)?>&type0[]=ISN&<? endforeach; ?><? endif; ?>sort=year&view=list diff --git a/themes/finc/templates/RecordDriver/SolrAI/result-list.phtml b/themes/finc/templates/RecordDriver/SolrAI/result-list.phtml new file mode 100644 index 00000000000..925e7774845 --- /dev/null +++ b/themes/finc/templates/RecordDriver/SolrAI/result-list.phtml @@ -0,0 +1,193 @@ +<div class="<?=$this->driver->supportsAjaxStatus()?'ajaxItem ':''?>col-xs-11"> + <div class="row"> + <div class="col-sm-2 col-xs-3 left"> + <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getUniqueID())?>" class="hiddenId" /> + <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getResourceSource())?>" class="hiddenSource" /> + <a href="<?=$this->recordLink()->getUrl($this->driver)?>"> + <? if ($summThumb = $this->record($this->driver)->getThumbnail()): ?> + <img class="recordcover" src="<?=$this->escapeHtmlAttr($summThumb)?>" alt="<?=$this->transEsc('Cover Image')?>"/> + <? else: ?> + <img class="recordcover" src="<?=$this->url('cover-unavailable')?>" alt="<?=$this->transEsc('No Cover Image')?>"/> + <? endif; ?> + </a> + </div> + <div class="col-sm-7 col-xs-6 middle"> + <div> + <a href="<?=$this->recordLink()->getUrl($this->driver)?>" class="title"> + <? + $summHighlightedTitle = $this->driver->getHighlightedTitle(); + $summTitle = $this->driver->getTitle(); + if (!empty($summHighlightedTitle)) { + echo $this->highlight($this->addEllipsis($summHighlightedTitle, $summTitle)); + } else if (!empty($summTitle)) { + echo $this->escapeHtml($this->truncate($summTitle, 180)); + } else { + echo $this->transEsc('Title not available'); + } + ?> + </a> + </div> + + <div> + <? if($this->driver->isCollection()): ?> + <?=implode('<br>', $this->driver->getSummary()); ?> + <? else: ?> + <? $summAuthors = $this->driver->getCombinedAuthors(); if (!empty($summAuthors)): ?> + <? foreach($summAuthors as $summAuthor) : ?> + <a href="<?=$this->record($this->driver)->getLink('author', $summAuthor)?>"><? + $summHighlightedAuthor = $this->driver->getHighlightedAuthor(); + echo !empty($summHighlightedAuthor) + ? $this->highlight($summHighlightedAuthor) + : $this->escapeHtml($summAuthor); + ?></a> + <? endforeach; ?> + <? endif; ?> + + <? $journalTitle = $this->driver->getContainerTitle(); $summDate = $this->driver->getPublicationDates(); $placesOfPublication = $this->driver->getPlacesOfPublication(); ?> + <? if (!empty($journalTitle)): ?> + <?=!empty($summAuthor) ? '<br />' : ''?> + <?=/* TODO: handle highlighting more elegantly here */ $this->transEsc('Published in') . ' <a href="' . $this->record($this->driver)->getLink('journaltitle', str_replace(array('{{{{START_HILITE}}}}', '{{{{END_HILITE}}}}'), '', $journalTitle)) . '">' . $this->highlight($journalTitle) . '</a>';?> + <?=!empty($summDate) ? ' (' . $this->escapeHtml($summDate) . ')' : ''?> + <? elseif (!empty($summDate)): ?> + <?=!empty($summAuthor) ? '<br />' : ''?> + <?=$this->transEsc('Published') . ' ' . $this->escapeHtml($summDate)?> + <? endif; ?> + <? $summInCollection = $this->driver->getContainingCollections(); if (!empty($summInCollection)): ?> + <? foreach ($summInCollection as $collId => $collText): ?> + <div> + <b><?=$this->transEsc("in_collection_label")?></b> + <a class="collectionLinkText" href="<?=$this->url('collection', array('id' => $collId))?>?recordID=<?=urlencode($this->driver->getUniqueID())?>"> + <?=$this->escapeHtml($collText)?> + </a> + </div> + <? endforeach; ?> + <? endif; ?> + <? endif; ?> + </div> + + <? if(!$this->driver->isCollection()): ?> + <? if ($snippet = $this->driver->getHighlightedSnippet()): ?> + <? if (!empty($snippet['caption'])): ?> + <strong><?=$this->transEsc($snippet['caption']) ?>:</strong> '; + <? endif; ?> + <? if (!empty($snippet['snippet'])): ?> + <span class="quotestart">“</span>...<?=$this->highlight($snippet['snippet']) ?>...<span class="quoteend">”</span><br/> + <? endif; ?> + <? endif; ?> + <? endif; ?> + + <? + /* Display information on duplicate records if available */ + $dedupData = $this->driver->getDedupData(); + if ($dedupData): ?> + <div class="dedupInformation"> + <? + $i = 0; + foreach ($dedupData as $source => $current) { + if (++$i == 1) { + ?><span class="currentSource"><a href="<?=$this->recordLink()->getUrl($this->driver)?>"><?=$this->transEsc("source_$source", array(), $source)?></a></span><? + } else { + if ($i == 2) { + ?> <span class="otherSources">(<?=$this->transEsc('Other Sources')?>: <? + } else { + ?>, <? + } + ?><a href="<?=$this->recordLink()->getUrl($current['id'])?>"><?=$this->transEsc("source_$source", array(), $source)?></a><? + } + } + if ($i > 1) { + ?>)</span><? + }?> + </div> + <? endif; ?> + + <div class="callnumAndLocation ajax-availability hidden"> + <? if ($this->driver->supportsAjaxStatus()): ?> + <strong class="hideIfDetailed"><?=$this->transEsc('Call Number')?>:</strong> + <span class="callnumber ajax-availability hidden"> + <?=$this->transEsc('Loading')?>...<br/> + </span> + <strong><?=$this->transEsc('Located')?>:</strong> + <span class="location ajax-availability hidden"> + <?=$this->transEsc('Loading')?>... + </span> + <div class="locationDetails"></div> + <? else: ?> + <? $summCallNo = $this->driver->getCallNumber(); if (!empty($summCallNo)): ?> + <strong><?=$this->transEsc('Call Number')?>:</strong> <?=$this->escapeHtml($summCallNo)?> + <? endif; ?> + <? endif; ?> + </div> + + <? /* We need to find out if we're supposed to display an OpenURL link ($openUrlActive), + but even if we don't plan to display the link, we still want to get the $openUrl + value for use in generating a COinS (Z3988) tag -- see bottom of file. + */ + $openUrl = $this->driver->getOpenURL(); + $openUrlActive = $this->driver->openURLActive('results'); + $urls = $this->record($this->driver)->getLinkDetails(); + if ($openUrlActive || !empty($urls)): ?> + <? if ($openUrlActive): ?> + <br/> + <?=$this->openUrl($openUrl)?> + <? if ($this->driver->replaceURLsWithOpenURL()) $urls = array(); // clear URL list if replace setting is active ?> + <? endif; ?> + <? if (!is_array($urls)) $urls = array(); + if(!$this->driver->isCollection()): + foreach ($urls as $current): ?> + <a href="<?=$this->escapeHtmlAttr($this->proxyUrl($current['url']))?>" class="fulltext" target="new"><i class="fa fa-external-link"></i> <?=($current['url'] == $current['desc']) ? $this->transEsc('Get full text') : $this->escapeHtml($current['desc'])?></a><br/> + <? endforeach; ?> + <? endif; ?> + <? endif; ?> + + <?=str_replace('class="', 'class="label label-info ', $this->record($this->driver)->getFormatList())?> + + <? if (!$openUrlActive && empty($urls) && $this->driver->supportsAjaxStatus()): ?> + <span class="status ajax-availability hidden"> + <span class="label label-default"><?=$this->transEsc('Loading')?>...</span> + </span> + <? endif; ?> + <?=$this->record($this->driver)->getPreviews()?> + </div> + <div class="col-xs-3 right hidden-print"> + <? /* Display qrcode if appropriate: */ ?> + <? if ($QRCode = $this->record($this->driver)->getQRCode("results")): ?> + <? + // Add JS Variables for QrCode + $this->jsTranslations()->addStrings(array('qrcode_hide' => 'qrcode_hide', 'qrcode_show' => 'qrcode_show')); + ?> + <span class="hidden-xs"> + <i class="fa fa-qrcode"></i> <a href="<?=$this->escapeHtmlAttr($QRCode);?>" class="qrcodeLink"><?=$this->transEsc('qrcode_show')?></a> + <div class="qrcode hidden"> + <img alt="<?=$this->transEsc('QR Code')?>" src="<?=$this->escapeHtmlAttr($QRCode);?>"/> + </div><br/> + </span> + <? endif; ?> + + <? if ($this->userlist()->getMode() !== 'disabled'): ?> + <? /* Add to favorites */ ?> + <i class="fa fa-heart"></i> <a href="<?=$this->recordLink()->getActionUrl($this->driver, 'Save')?>" class="save-record modal-link" id="<?=$this->driver->getUniqueId() ?>" title="<?=$this->transEsc('Add to favorites')?>"><?=$this->transEsc('Add to favorites')?></a><br/> + + <? /* Saved lists */ ?> + <div class="savedLists alert alert-info hidden"> + <strong><?=$this->transEsc("Saved in")?>:</strong> + </div> + <? endif; ?> + + <? /* Hierarchy tree link */ ?> + <? $trees = $this->driver->tryMethod('getHierarchyTrees'); if (!empty($trees)): ?> + <? foreach ($trees as $hierarchyID => $hierarchyTitle): ?> + <div class="hierarchyTreeLink"> + <input type="hidden" value="<?=$this->escapeHtmlAttr($hierarchyID)?>" class="hiddenHierarchyId" /> + <i class="fa fa-sitemap"></i> + <a class="hierarchyTreeLinkText modal-link" href="<?=$this->recordLink()->getTabUrl($this->driver, 'HierarchyTree')?>?hierarchy=<?=urlencode($hierarchyID)?>#tabnav" title="<?=$this->transEsc('hierarchy_tree')?>"> + <?=$this->transEsc('hierarchy_view_context')?><? if (count($trees) > 1): ?>: <?=$this->escapeHtml($hierarchyTitle)?><? endif; ?> + </a> + </div> + <? endforeach; ?> + <? endif; ?> + + <?=$openUrl?'<span class="Z3988" title="'.$this->escapeHtmlAttr($openUrl).'"></span>':''?> + </div> + </div> +</div> \ No newline at end of file diff --git a/themes/finc/templates/RecordTab/description.phtml b/themes/finc/templates/RecordTab/description.phtml new file mode 100644 index 00000000000..2d682adf1b6 --- /dev/null +++ b/themes/finc/templates/RecordTab/description.phtml @@ -0,0 +1,242 @@ +<? + // Set page title. + $this->headTitle($this->translate('Description') . ': ' . $this->driver->getBreadcrumb()); + + // Grab clean ISBN for convenience: + $isbn = $this->driver->getCleanISBN(); +?> +<table class="table table-striped" summary="<?=$this->transEsc('Description')?>"> + <? $summ = $this->driver->getSummary(); if (!empty($summ)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('Summary')?>: </th> + <td> + <? foreach ($summ as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $dateSpan = $this->driver->getDateSpan(); if (!empty($dateSpan)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('Published')?>: </th> + <td> + <? foreach ($dateSpan as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $notes = $this->driver->getGeneralNotes(); if (!empty($notes)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('Item Description')?>: </th> + <td> + <? foreach ($notes as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $physical = $this->driver->getPhysicalDescriptions(); if (!empty($physical)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('Physical Description')?>: </th> + <td> + <? foreach ($physical as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $freq = $this->driver->getPublicationFrequency(); if (!empty($freq)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('Publication Frequency')?>: </th> + <td> + <? foreach ($freq as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $playTime = $this->driver->getPlayingTimes(); if (!empty($playTime)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('Playing Time')?>: </th> + <td> + <? foreach ($playTime as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $system = $this->driver->getSystemDetails(); if (!empty($system)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('Format')?>: </th> + <td> + <? foreach ($system as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $audience = $this->driver->getTargetAudienceNotes(); if (!empty($audience)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('Audience')?>: </th> + <td> + <? foreach ($audience as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $awards = $this->driver->getAwards(); if (!empty($awards)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('Awards')?>: </th> + <td> + <? foreach ($awards as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $credits = $this->driver->getProductionCredits(); if (!empty($credits)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('Production Credits')?>: </th> + <td> + <? foreach ($credits as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $bib = $this->driver->getBibliographyNotes(); if (!empty($bib)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('Bibliography')?>: </th> + <td> + <? foreach ($bib as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $isbns = $this->driver->getISBNs(); if (!empty($isbns)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('ISBN')?>: </th> + <td> + <? foreach ($isbns as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $issns = $this->driver->getISSNs(); if (!empty($issns)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('ISSN')?>: </th> + <td> + <? foreach ($issns as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $eissns = $this->driver->getEISSNs(); if (!empty($eissns)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('EISSN')?>: </th> + <td> + <? foreach ($eissns as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $related = $this->driver->getRelationshipNotes(); if (!empty($related)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('Related Items')?>: </th> + <td> + <? foreach ($related as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $access = $this->driver->getAccessRestrictions(); if (!empty($access)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('Access')?>: </th> + <td> + <? foreach ($access as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $findingAids = $this->driver->getFindingAids(); if (!empty($findingAids)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('Finding Aid')?>: </th> + <td> + <? foreach ($findingAids as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $publicationPlaces = $this->driver->getHierarchicalPlaceNames(); if (!empty($publicationPlaces)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('Publication_Place')?>: </th> + <td> + <? foreach ($publicationPlaces as $field): ?> + <?=$this->escapeHtml($field)?><br/> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? $authorNotes = empty($isbn) ? array() : $this->authorNotes($isbn); if (!empty($authorNotes)): ?> + <? $contentDisplayed = true; ?> + <tr> + <th><?=$this->transEsc('Author Notes')?>: </th> + <td> + <? foreach ($authorNotes as $provider => $list): ?> + <? foreach ($list as $field): ?> + <?=$field['Content']?><br/> + <? endforeach; ?> + <? endforeach; ?> + </td> + </tr> + <? endif; ?> + + <? if (!isset($contentDisplayed) || !$contentDisplayed): // Avoid errors if there were no rows above ?> + <tr><td><?=$this->transEsc('no_description')?></td></tr> + <? endif; ?> +</table> diff --git a/themes/finc/templates/RecordTab/staffviewarray.phtml b/themes/finc/templates/RecordTab/staffviewarray.phtml new file mode 100644 index 00000000000..03cee1701d7 --- /dev/null +++ b/themes/finc/templates/RecordTab/staffviewarray.phtml @@ -0,0 +1,23 @@ +<? + // Set page title. + $this->headTitle($this->translate('Staff View') . ': ' . $this->driver->getBreadcrumb()); +?> +<table class="citation table table-striped"> + <? foreach ($this->driver->getRawData() as $data): ?> + <tr> + <th><?=$this->escapeHtml($data['key'])?></th> + <td> + <? if (!is_array($data['value'])) { $data['value'] = array($data['value']); } ?> + <? foreach ($data['value'] as $values): ?> + <? if (is_array($values)): ?> + <? foreach ($values as $value): ?> + <?=$this->escapeHtml($value)?><br /> + <? endforeach; ?> + <? else: ?> + <?=$this->escapeHtml($values)?><br /> + <? endif; ?> + <? endforeach; ?> + </td> + </tr> + <? endforeach; ?> +</table> \ No newline at end of file diff --git a/themes/finc/templates/ajax/resolverLinks.phtml b/themes/finc/templates/ajax/resolverLinks.phtml new file mode 100644 index 00000000000..7f1d204a28e --- /dev/null +++ b/themes/finc/templates/ajax/resolverLinks.phtml @@ -0,0 +1,51 @@ +<div> + <? if (!empty($this->electronic)): ?> + <div class="openurls"> + <strong><?=$this->transEsc('Electronic')?></strong> + <ul> + <? foreach ($this->electronic as $link): ?> + <li> + <? if (isset($link['href']) && !empty($link['href'])): ?> + <a href="<?=$this->escapeHtmlAttr($link['href'])?>" title="<?=isset($link['service_type'])?$this->escapeHtmlAttr($link['service_type']):''?>"><?=isset($link['title'])?$this->escapeHtml($link['title']):''?></a> <?=isset($link['coverage'])?$this->escapeHtml($link['coverage']):''?> + <? else: ?> + <?=isset($link['title'])?$this->escapeHtml($link['title']):''?> <?=isset($link['coverage'])?$this->escapeHtml($link['coverage']):''?> + <? endif; ?> + <? if (isset($link['info']) && !empty($link['info'])): ?> + <?=$this->escapeHtml($link['info'])?> + <? endif; ?> + </li> + <? endforeach; ?> + </ul> + </div> + <? endif; ?> + <? if (!empty($this->print)): ?> + <div class="openurls"> + <strong><?=$this->transEsc('Holdings')?></strong> + <ul> + <? foreach ($this->print as $link): ?> + <li> + <? if (isset($link['href']) && !empty($link['href'])): ?> + <a href="<?=$this->escapeHtmlAttr($link['href'])?>" title="<?=isset($link['service_type'])?$this->escapeHtmlAttr($link['service_type']):''?>"><?=isset($link['title'])?$this->escapeHtml($link['title']):''?></a> <?=isset($link['coverage'])?$this->escapeHtml($link['coverage']):''?> + <? else: ?> + <?=isset($link['title'])?$this->escapeHtml($link['title']):''?> <?=isset($link['coverage'])?$this->escapeHtml($link['coverage']):''?> + <? endif; ?> + </li> + <? endforeach; ?> + </ul> + </div> + <? endif; ?> + <div class="openurls"> + <strong><a href="<?=$this->escapeHtmlAttr($this->openUrlBase)?>?<?=$this->escapeHtmlAttr($this->openUrl)?>"><?=$this->transEsc('More options')?></a></strong> + <? if (!empty($this->services)): ?> + <ul> + <? foreach ($this->services as $link): ?> + <? if (isset($link['href']) && !empty($link['href'])): ?> + <li> + <a href="<?=$this->escapeHtmlAttr($link['href'])?>" title="<?=isset($link['service_type'])?$this->escapeHtmlAttr($link['service_type']):''?>"><?=isset($link['title'])?$this->escapeHtml($link['title']):''?></a> + </li> + <? endif; ?> + <? endforeach; ?> + </ul> + <? endif; ?> + </div> +</div> diff --git a/themes/finc/theme.config.php b/themes/finc/theme.config.php index 018a473aeb6..a3a8cd17653 100644 --- a/themes/finc/theme.config.php +++ b/themes/finc/theme.config.php @@ -1,4 +1,9 @@ <?php return array( - 'extends' => 'bootstrap3' + 'extends' => 'bootstrap3', + 'helpers' => array( + 'factories' => array( + 'record' => 'finc\View\Helper\Root\Factory::getRecord' + ), + ), ); -- GitLab