From e1678d25bacf807237f3170d0cca94c490a69d77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Lahmann?= <lahmann@users.noreply.github.com> Date: Wed, 8 Feb 2017 15:41:40 +0100 Subject: [PATCH] Link resolver driver improvements (#685) - added support for datatype additionals in EZB-response for electronic journals - added support for datatype elements in EZB-response for print journals - added support for proper status mapping to access classes in VuFind - extended documentation - added tests for EZB resolver - implemented Resolver\Driver\AbstractBase and refactored existing drivers to extend it - added new required methods to DriverInterface --- .../src/VuFind/Controller/AjaxController.php | 6 +- .../VuFind/Resolver/Driver/AbstractBase.php | 87 ++++++++ .../src/VuFind/Resolver/Driver/Demo.php | 12 +- .../Resolver/Driver/DriverInterface.php | 23 ++ .../VuFind/src/VuFind/Resolver/Driver/Ezb.php | 203 ++++++++++++++---- .../src/VuFind/Resolver/Driver/Redi.php | 11 +- .../VuFind/src/VuFind/Resolver/Driver/Sfx.php | 11 +- .../VuFind/Resolver/Driver/Threesixtylink.php | 11 +- .../src/VuFind/View/Helper/Root/Factory.php | 3 + .../src/VuFind/View/Helper/Root/OpenUrl.php | 35 ++- .../tests/fixtures/resolver/response/ezb.xml | 110 ++++++++++ .../VuFindTest/Resolver/Driver/EzbTest.php | 168 +++++++++++++++ .../View/Helper/Root/OpenUrlTest.php | 4 +- .../templates/Helpers/openurl.phtml | 2 +- .../templates/ajax/resolverLinks.phtml | 2 +- 15 files changed, 609 insertions(+), 79 deletions(-) create mode 100644 module/VuFind/src/VuFind/Resolver/Driver/AbstractBase.php create mode 100644 module/VuFind/tests/fixtures/resolver/response/ezb.xml create mode 100644 module/VuFind/tests/unit-tests/src/VuFindTest/Resolver/Driver/EzbTest.php diff --git a/module/VuFind/src/VuFind/Controller/AjaxController.php b/module/VuFind/src/VuFind/Controller/AjaxController.php index bbf2a2a3d86..cc3319da597 100644 --- a/module/VuFind/src/VuFind/Controller/AjaxController.php +++ b/module/VuFind/src/VuFind/Controller/AjaxController.php @@ -1259,11 +1259,15 @@ class AjaxController extends AbstractBase $base = false; } + $moreOptionsLink = $resolver->supportsMoreOptionsLink() + ? $resolver->getResolverUrl($openUrl) : ''; + // Render the links using the view: $view = [ 'openUrlBase' => $base, 'openUrl' => $openUrl, 'print' => $print, 'electronic' => $electronic, 'services' => $services, - 'searchClassId' => $searchClassId + 'searchClassId' => $searchClassId, + 'moreOptionsLink' => $moreOptionsLink ]; $html = $this->getViewRenderer()->render('ajax/resolverLinks.phtml', $view); diff --git a/module/VuFind/src/VuFind/Resolver/Driver/AbstractBase.php b/module/VuFind/src/VuFind/Resolver/Driver/AbstractBase.php new file mode 100644 index 00000000000..2d9f1d5df71 --- /dev/null +++ b/module/VuFind/src/VuFind/Resolver/Driver/AbstractBase.php @@ -0,0 +1,87 @@ +<?php +/** + * AbstractBase for Resolver Driver + * + * PHP version 5 + * + * Copyright (C) Villanova University 2015. + * + * last update: 2011-04-13 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package Resolver_Drivers + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:link_resolver_drivers Wiki + */ +namespace VuFind\Resolver\Driver; + +/** + * AbstractBase for Resolver Driver + * + * @category VuFind + * @package Resolver_Drivers + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:link_resolver_drivers Wiki + */ +abstract class AbstractBase implements DriverInterface +{ + /** + * Base URL for link resolver + * + * @var string + */ + protected $baseUrl; + + /** + * Constructor + * + * @param string $baseUrl Base URL for link resolver + */ + public function __construct($baseUrl) + { + $this->baseUrl = $baseUrl; + } + + /** + * Get Resolver Url + * + * Transform the OpenURL as needed to get a working link to the resolver. + * + * @param string $openURL openURL (url-encoded) + * + * @return string Returns resolver specific url + */ + public function getResolverUrl($openURL) + { + return $this->baseUrl . '?' . $openURL; + } + + /** + * This controls whether a "More options" link will be shown below the fetched + * resolver links eventually linking to the resolver page previously being + * parsed. + * This is especially useful for resolver such as the EZB resolver returning + * XML which would not be of any immediate use for the user. + * + * @return bool + */ + public function supportsMoreOptionsLink() + { + return true; + } +} diff --git a/module/VuFind/src/VuFind/Resolver/Driver/Demo.php b/module/VuFind/src/VuFind/Resolver/Driver/Demo.php index 43ce20ba428..d864b7cf74d 100644 --- a/module/VuFind/src/VuFind/Resolver/Driver/Demo.php +++ b/module/VuFind/src/VuFind/Resolver/Driver/Demo.php @@ -39,8 +39,18 @@ use DOMDocument, DOMXpath; * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development:plugins:link_resolver_drivers Wiki */ -class Demo implements DriverInterface +class Demo extends AbstractBase { + /** + * Constructor + * + * @param string $baseUrl Base URL for link resolver + */ + public function __construct($baseUrl = 'http://localhost') + { + parent::__construct($baseUrl); + } + /** * Fetch Links * diff --git a/module/VuFind/src/VuFind/Resolver/Driver/DriverInterface.php b/module/VuFind/src/VuFind/Resolver/Driver/DriverInterface.php index 7f243ec690d..f0ec93d8310 100644 --- a/module/VuFind/src/VuFind/Resolver/Driver/DriverInterface.php +++ b/module/VuFind/src/VuFind/Resolver/Driver/DriverInterface.php @@ -66,4 +66,27 @@ interface DriverInterface * @return array Array of values */ public function parseLinks($xmlstr); + + /** + * Get Resolver Url + * + * Transform the OpenURL as needed to get a working link to the resolver. + * + * @param string $openURL openURL (url-encoded) + * + * @return string Returns resolver specific url + */ + public function getResolverUrl($openURL); + + /** + * This controls whether a "More options" link will be shown below the fetched + * resolver links eventually linking to the resolver page previously being + * parsed. + * This is especially useful for resolver such as the EZB resolver returning + * XML which would not be of any immediate use for the user. + * + * @return bool + */ + public function supportsMoreOptionsLink(); + } diff --git a/module/VuFind/src/VuFind/Resolver/Driver/Ezb.php b/module/VuFind/src/VuFind/Resolver/Driver/Ezb.php index ad375be428e..c507608d975 100644 --- a/module/VuFind/src/VuFind/Resolver/Driver/Ezb.php +++ b/module/VuFind/src/VuFind/Resolver/Driver/Ezb.php @@ -5,6 +5,9 @@ * EZB is a free service -- the API endpoint is available at * http://services.dnb.de/fize-service/gvr/full.xml * + * API documentation is available at + * http://www.zeitschriftendatenbank.de/services/schnittstellen/journals-online-print + * * PHP version 5 * * Copyright (C) Markus Fischer, info@flyingfischer.ch @@ -27,6 +30,7 @@ * @category VuFind * @package Resolver_Drivers * @author Markus Fischer <info@flyingfischer.ch> + * @author André Lahmann <lahmann@ub.uni-leipzig.de> * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development:plugins:link_resolver_drivers Wiki */ @@ -39,18 +43,12 @@ use DOMDocument, DOMXpath; * @category VuFind * @package Resolver_Drivers * @author Markus Fischer <info@flyingfischer.ch> + * @author André Lahmann <lahmann@ub.uni-leipzig.de> * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development:plugins:link_resolver_drivers Wiki */ -class Ezb implements DriverInterface +class Ezb extends AbstractBase { - /** - * Base URL for link resolver - * - * @var string - */ - protected $baseUrl; - /** * HTTP client * @@ -66,7 +64,7 @@ class Ezb implements DriverInterface */ public function __construct($baseUrl, \Zend\Http\Client $httpClient) { - $this->baseUrl = $baseUrl; + parent::__construct($baseUrl); $this->httpClient = $httpClient; } @@ -81,32 +79,10 @@ class Ezb implements DriverInterface */ public function fetchLinks($openURL) { - // Unfortunately the EZB-API only allows OpenURL V0.1 and - // breaks when sending a non expected parameter (like an ISBN). - // So we do have to 'downgrade' the OpenURL-String from V1.0 to V0.1 - // and exclude all parameters that are not compliant with the EZB. - - // Parse OpenURL into associative array: - $tmp = explode('&', $openURL); - $parsed = []; - - foreach ($tmp as $current) { - $tmp2 = explode('=', $current, 2); - $parsed[$tmp2[0]] = $tmp2[1]; - } - - // Downgrade 1.0 to 0.1 - if ($parsed['ctx_ver'] == 'Z39.88-2004') { - $openURL = $this->downgradeOpenUrl($parsed); - } - - // make the request IP-based to allow automatic - // indication on institution level - $openURL .= '&pid=client_ip%3D' . $_SERVER['REMOTE_ADDR']; + // Get the actual resolver url for the given openUrl + $url = $this->getResolverUrl($openURL); // Make the call to the EZB and load results - $url = $this->baseUrl . '?' . $openURL; - $feed = $this->httpClient->setUri($url)->send()->getBody(); return $feed; } @@ -146,6 +122,60 @@ class Ezb implements DriverInterface return $records; } + /** + * Get Resolver Url + * + * Transform the OpenURL as needed to get a working link to the resolver. + * + * @param string $openURL openURL (url-encoded) + * + * @return string Link + */ + public function getResolverUrl($openURL) + { + // Unfortunately the EZB-API only allows OpenURL V0.1 and + // breaks when sending a non expected parameter (like an ISBN). + // So we do have to 'downgrade' the OpenURL-String from V1.0 to V0.1 + // and exclude all parameters that are not compliant with the EZB. + + // Parse OpenURL into associative array: + $tmp = explode('&', $openURL); + $parsed = []; + + foreach ($tmp as $current) { + $tmp2 = explode('=', $current, 2); + $parsed[$tmp2[0]] = $tmp2[1]; + } + + // Downgrade 1.0 to 0.1 + if ($parsed['ctx_ver'] == 'Z39.88-2004') { + $openURL = $this->downgradeOpenUrl($parsed); + } + + // make the request IP-based to allow automatic + // indication on institution level + $openURL .= '&pid=client_ip%3D' . $_SERVER['REMOTE_ADDR']; + + // Make the call to the EZB and load results + $url = $this->baseUrl . '?' . $openURL; + + return $url; + } + + /** + * Allows for resolver driver specific enabling/disabling of the more options + * link which will link directly to the resolver URL. This should return false if + * the resolver returns data in XML or any other human unfriendly response. + * + * @return bool + */ + public function supportsMoreOptionsLink() + { + // the EZB link resolver returns unstyled XML which is not helpful for the + // user + return false; + } + /** * Downgrade an OpenURL from v1.0 to v0.1 for compatibility with EZB. * @@ -208,25 +238,73 @@ class Ezb implements DriverInterface "/OpenURLResponseXML/Full/ElectronicData/ResultList/Result[@state=" . $state . "]" ); + + /* + * possible state values: + * -1 ISSN nicht eindeutig + * 0 Standort-unabhängig frei zugänglich + * 1 Standort-unabhängig teilweise zugänglich (Unschärfe bedingt durch + * unspezifische Anfrage oder Moving-Wall) + * 2 Lizenziert + * 3 Für gegebene Bibliothek teilweise lizenziert (Unschärfe bedingt durch + * unspezifische Anfrage oder Moving-Wall) + * 4 nicht lizenziert + * 5 Zeitschrift gefunden + * Angaben über Erscheinungsjahr, Datum ... liegen außerhalb des + * hinterlegten bibliothekarischen Zeitraums + * 10 Unbekannt (ISSN unbekannt, Bibliothek unbekannt) + */ + $state_access_mapping = [ + '-1' => 'error', + '0' => 'open', + '1' => 'limited', + '2' => 'open', + '3' => 'limited', + '4' => 'denied', + '5' => 'denied', + '10' => 'unknown' + ]; + $i = 0; foreach ($results as $result) { $record = []; $titleXP = "/OpenURLResponseXML/Full/ElectronicData/ResultList/" . - "Result[@state={$state}]/Title"; - $record['title'] = strip_tags( - $xpath->query($titleXP, $result)->item($i)->nodeValue - ); - $record['coverage'] = $coverage; + "Result[@state={$state}][" . ($i + 1) . "]/Title"; + $title = $xpath->query($titleXP, $result)->item(0); + if (isset($title)) { + $record['title'] = strip_tags($title->nodeValue); + } + + $additionalXP = "/OpenURLResponseXML/Full/ElectronicData/ResultList/" . + "Result[@state={$state}][" . ($i + 1) . "]/Additionals/Additional"; + $additionalType = ['nali', 'intervall', 'moving_wall']; + $additionals = []; + foreach ($additionalType as $type) { + $additional = $xpath + ->query($additionalXP . "[@type='" . $type . "']", $result) + ->item(0); + if (isset($additional->nodeValue)) { + $additionals[$type] = strip_tags($additional->nodeValue); + } + } + $record['coverage'] + = !empty($additionals) ? implode("; ", $additionals) : $coverage; + + $record['access'] = $state_access_mapping[$state]; + $urlXP = "/OpenURLResponseXML/Full/ElectronicData/ResultList/" . - "Result[@state={$state}]/AccessURL"; - $record['href'] = $xpath->query($urlXP, $result)->item($i)->nodeValue; + "Result[@state={$state}][" . ($i + 1) . "]/AccessURL"; + $url = $xpath->query($urlXP, $result)->item(0); + if (isset($url->nodeValue)) { + $record['href'] = $url->nodeValue; + } // Service type needs to be hard-coded for calling code to properly // categorize links. The commented code below picks a more appropriate // value but won't work for now -- retained for future reference. //$service_typeXP = "/OpenURLResponseXML/Full/ElectronicData/ResultList/" - // . "Result[@state={$state}]/AccessLevel"; + // . "Result[@state={$state}][".($i+1)."]/AccessLevel"; //$record['service_type'] - // = $xpath->query($service_typeXP, $result)->item($i)->nodeValue; + // = $xpath->query($service_typeXP, $result)->item(0)->nodeValue; $record['service_type'] = 'getFullTxt'; array_push($records, $record); $i++; @@ -249,12 +327,51 @@ class Ezb implements DriverInterface $results = $xpath->query( "/OpenURLResponseXML/Full/PrintData/ResultList/Result[@state={$state}]" ); + + /* + * possible state values: + * -1 ISSN nicht eindeutig + * 2 Vorhanden + * 3 Teilweise vorhanden (Unschärfe bedingt durch unspezifische Anfrage bei + * nicht vollständig vorhandener Zeitschrift) + * 4 Nicht vorhanden + * 10 Unbekannt (ZDB-ID unbekannt, ISSN unbekannt, Bibliothek unbekannt) + */ + $state_access_mapping = [ + '-1' => 'error', + '2' => 'open', + '3' => 'limited', + '4' => 'denied', + '10' => 'unknown' + ]; + $i = 0; foreach ($results as $result) { $record = []; $record['title'] = $coverage; + + $resultXP = "/OpenURLResponseXML/Full/PrintData/ResultList/" . + "Result[@state={$state}][" . ($i + 1) . "]"; + $resultElements = [ + 'Title', 'Location', 'Signature', 'Period', 'Holding_comment' + ]; + $elements = []; + foreach ($resultElements as $element) { + $elem = $xpath->query($resultXP . "/" . $element, $result)->item(0); + if (isset($elem->nodeValue)) { + $elements[$element] = strip_tags($elem->nodeValue); + } + } + $record['coverage'] + = !empty($elements) ? implode("; ", $elements) : $coverage; + + $record['access'] = $state_access_mapping[$state]; + $urlXP = "/OpenURLResponseXML/Full/PrintData/References/Reference/URL"; - $record['href'] = $xpath->query($urlXP, $result)->item($i)->nodeValue; + $url = $xpath->query($urlXP, $result)->item($i); + if (isset($url->nodeValue)) { + $record['href'] = $url->nodeValue; + } // Service type needs to be hard-coded for calling code to properly // categorize links. The commented code below picks a more appropriate // value but won't work for now -- retained for future reference. diff --git a/module/VuFind/src/VuFind/Resolver/Driver/Redi.php b/module/VuFind/src/VuFind/Resolver/Driver/Redi.php index 7d90616ac5e..163fdeef2df 100644 --- a/module/VuFind/src/VuFind/Resolver/Driver/Redi.php +++ b/module/VuFind/src/VuFind/Resolver/Driver/Redi.php @@ -40,7 +40,7 @@ use DOMDocument, Zend\Dom\DOMXPath; * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development:plugins:link_resolver_drivers Wiki */ -class Redi implements DriverInterface +class Redi extends AbstractBase { /** * HTTP client @@ -49,13 +49,6 @@ class Redi implements DriverInterface */ protected $httpClient; - /** - * Base URL for link resolver - * - * @var string - */ - protected $baseUrl; - /** * Parsed resolver links * @@ -71,7 +64,7 @@ class Redi implements DriverInterface */ public function __construct($baseUrl, \Zend\Http\Client $httpClient) { - $this->baseUrl = $baseUrl; + parent::__construct($baseUrl); $this->httpClient = $httpClient; } diff --git a/module/VuFind/src/VuFind/Resolver/Driver/Sfx.php b/module/VuFind/src/VuFind/Resolver/Driver/Sfx.php index d2063132907..ccd6a7ec3c6 100644 --- a/module/VuFind/src/VuFind/Resolver/Driver/Sfx.php +++ b/module/VuFind/src/VuFind/Resolver/Driver/Sfx.php @@ -39,15 +39,8 @@ namespace VuFind\Resolver\Driver; * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development:plugins:link_resolver_drivers Wiki */ -class Sfx implements DriverInterface +class Sfx extends AbstractBase { - /** - * Base URL for link resolver - * - * @var string - */ - protected $baseUrl; - /** * HTTP client * @@ -63,7 +56,7 @@ class Sfx implements DriverInterface */ public function __construct($baseUrl, \Zend\Http\Client $httpClient) { - $this->baseUrl = $baseUrl; + parent::__construct($baseUrl); $this->httpClient = $httpClient; } diff --git a/module/VuFind/src/VuFind/Resolver/Driver/Threesixtylink.php b/module/VuFind/src/VuFind/Resolver/Driver/Threesixtylink.php index 791dd6ba5e8..0c72b3444f0 100644 --- a/module/VuFind/src/VuFind/Resolver/Driver/Threesixtylink.php +++ b/module/VuFind/src/VuFind/Resolver/Driver/Threesixtylink.php @@ -39,15 +39,8 @@ use DOMDocument, DOMXpath; * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development:plugins:link_resolver_drivers Wiki */ -class Threesixtylink implements DriverInterface +class Threesixtylink extends AbstractBase { - /** - * Base URL for link resolver - * - * @var string - */ - protected $baseUrl; - /** * HTTP client * @@ -63,7 +56,7 @@ class Threesixtylink implements DriverInterface */ public function __construct($baseUrl, \Zend\Http\Client $httpClient) { - $this->baseUrl = $baseUrl; + parent::__construct($baseUrl); $this->httpClient = $httpClient; } diff --git a/module/VuFind/src/VuFind/View/Helper/Root/Factory.php b/module/VuFind/src/VuFind/View/Helper/Root/Factory.php index 9544456c0bd..4987ebb9ace 100644 --- a/module/VuFind/src/VuFind/View/Helper/Root/Factory.php +++ b/module/VuFind/src/VuFind/View/Helper/Root/Factory.php @@ -339,9 +339,12 @@ class Factory ), true ); + $resolverPluginManager = $sm->getServiceLocator() + ->get('VuFind\ResolverDriverPluginManager'); return new OpenUrl( $sm->get('context'), $openUrlRules, + $resolverPluginManager, isset($config->OpenURL) ? $config->OpenURL : null ); } diff --git a/module/VuFind/src/VuFind/View/Helper/Root/OpenUrl.php b/module/VuFind/src/VuFind/View/Helper/Root/OpenUrl.php index 6f1393deedc..e7090ce5037 100644 --- a/module/VuFind/src/VuFind/View/Helper/Root/OpenUrl.php +++ b/module/VuFind/src/VuFind/View/Helper/Root/OpenUrl.php @@ -26,6 +26,7 @@ * @link https://vufind.org/wiki/development Wiki */ namespace VuFind\View\Helper\Root; +use VuFind\Resolver\Driver\PluginManager; /** * OpenUrl view helper @@ -59,6 +60,13 @@ class OpenUrl extends \Zend\View\Helper\AbstractHelper */ protected $openUrlRules; + /** + * Resolver plugin manager + * + * @var PluginManager + */ + protected $resolverPluginManager; + /** * Current RecordDriver * @@ -76,15 +84,17 @@ class OpenUrl extends \Zend\View\Helper\AbstractHelper /** * Constructor * - * @param \VuFind\View\Helper\Root\Context $context Context helper - * @param array $openUrlRules VuFind OpenURL rules - * @param \Zend\Config\Config $config VuFind OpenURL config + * @param \VuFind\View\Helper\Root\Context $context Context helper + * @param array $openUrlRules VuFind OpenURL rules + * @param PluginManager $pluginManager Resolver plugin manager + * @param \Zend\Config\Config $config VuFind OpenURL config */ public function __construct(\VuFind\View\Helper\Root\Context $context, - $openUrlRules, $config = null + $openUrlRules, PluginManager $pluginManager, $config = null ) { $this->context = $context; $this->openUrlRules = $openUrlRules; + $this->resolverPluginManager = $pluginManager; $this->config = $config; } @@ -192,8 +202,20 @@ class OpenUrl extends \Zend\View\Helper\AbstractHelper ); } + // instantiate the resolver plugin to get a proper resolver link + if ($this->resolverPluginManager->has($resolver)) { + $resolverObj = new \VuFind\Resolver\Connection( + $this->resolverPluginManager->get($resolver) + ); + $resolverUrl = $resolverObj->getResolverUrl($openurl); + } else { + $resolverUrl = empty($base) ? '' : $base . '?' . + $this->recordDriver->getOpenUrl(); + } + // Build parameters needed to display the control: $params = [ + 'resolverUrl' => $resolverUrl, 'openUrl' => $this->recordDriver->getOpenUrl(), 'openUrlBase' => empty($base) ? false : $base, 'openUrlWindow' => empty($this->config->window_settings) @@ -291,6 +313,11 @@ class OpenUrl extends \Zend\View\Helper\AbstractHelper */ protected function checkIfRulesApply() { + // special case if no rules are defined at all assume that any record is + // valid for openUrls + if (!isset($this->openUrlRules) || count($this->openUrlRules) < 1) { + return true; + } foreach ($this->openUrlRules as $rules) { if (!$this->checkExcludedRecordsRules($rules) && $this->checkSupportedRecordsRules($rules) diff --git a/module/VuFind/tests/fixtures/resolver/response/ezb.xml b/module/VuFind/tests/fixtures/resolver/response/ezb.xml new file mode 100644 index 00000000000..9604c86044f --- /dev/null +++ b/module/VuFind/tests/fixtures/resolver/response/ezb.xml @@ -0,0 +1,110 @@ +HTTP/1.1 200 OK +Date: Thu, 21 Apr 2016 13:25:49 GMT +Server: Apache +Content-Length: 5592 +Vary: Accept-Encoding +Content-Type: text/xml;charset=UTF-8 + + +<OpenURLResponseXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" xsi:noNamespaceSchemaLocation="http://ezb.uni-regensburg.de/ezeit/vascoda/vifa/vifaxml/response_vr_v1_0_1.xsd"> + <Full> + <ElectronicData> + <Library>Universitätsbibliothek Leipzig</Library> + <References> + <Reference> + <URL>http://www.bibliothek.uni-regensburg.de/ezeit/?1482826</URL> + <Label>EZB-Opac</Label> + </Reference> + <Reference> + <URL>http://www.bibliothek.uni-regensburg.de/ezeit/?2010839</URL> + <Label>EZB-Opac</Label> + </Reference> + <Reference> + <URL>http://www.bibliothek.uni-regensburg.de/ezeit/search.phtml?bibid=UBL&lang=de&jq_type1=KT&jq_term1=Noûs : a Quarterly Journal of Philosophy (1997-)</URL> + <Label>EZB-Suche</Label> + </Reference> + </References> + <ResultList> + <Result state="3"> + <Title>Noûs : a Quarterly Journal of Philosophy (1997-)</Title> + <JournalURL>http://onlinelibrary.wiley.com/journal/10.1111/(ISSN)1468-0068</JournalURL> + <AccessURL>http://onlinelibrary.wiley.com/journal/10.1111/(ISSN)1468-0068</AccessURL> + <AccessLevel>homepage</AccessLevel> + <Additionals> + <Additional type="intervall">ab Vol. 31, Iss. 1 (1997)</Additional> + </Additionals> + <ReadmeURL lang="de">https://www.ub.uni-leipzig.de/index.php?id=163#Wiley Core 2015</ReadmeURL> + <ReadmeURL lang="en">http://www.ub.uni-leipzig.de/kata_db/Readme.htm#Wiley Core 2015</ReadmeURL> + </Result> + <Result state="3"> + <Title>Noûs (ältere Jahrgänge via JSTOR)</Title> + <JournalURL>http://www.jstor.org/action/showPublication?journalCode=nous</JournalURL> + <AccessURL>http://www.jstor.org/action/showPublication?journalCode=nous</AccessURL> + <AccessLevel>homepage</AccessLevel> + <Additionals> + <Additional type="intervall">ab Vol. 1, Iss. 1 (1967)</Additional> + <Additional type="moving_wall">für die Ausgaben der aktuellen 11 Jahrgänge nicht verfügbar</Additional> + </Additionals> + <ReadmeURL lang="de">https://www.ub.uni-leipzig.de/index.php?id=163#jstor_arts1</ReadmeURL> + <ReadmeURL lang="en">http://www.ub.uni-leipzig.de/kata_db/Readme.htm#jstor_arts1</ReadmeURL> + </Result> + <Result state="3"> + <Title>Nous (via EBSCO Host)</Title> + <JournalURL>http://search.ebscohost.com/direct.asp?db=aph&jid=D97&scope=site</JournalURL> + <AccessURL>http://search.ebscohost.com/direct.asp?db=aph&jid=D97&scope=site</AccessURL> + <AccessLevel>homepage</AccessLevel> + <Additionals> + <Additional type="moving_wall">für die Ausgaben der vergangenen 12 Monate nicht verfügbar</Additional> + </Additionals> + <ReadmeURL lang="de">https://www.ub.uni-leipzig.de/index.php?id=163#ebsco_aph</ReadmeURL> + <ReadmeURL lang="en">http://www.ub.uni-leipzig.de/kata_db/Readme.htm#ebsco_aph</ReadmeURL> + </Result> + <Result state="3"> + <Title>Nous (via EBSCO Host)</Title> + <JournalURL>http://search.ebscohost.com/direct.asp?db=lfh&jid=D97&scope=site</JournalURL> + <AccessURL>http://search.ebscohost.com/direct.asp?db=lfh&jid=D97&scope=site</AccessURL> + <AccessLevel>homepage</AccessLevel> + <Additionals> + <Additional type="moving_wall">für die Ausgaben der vergangenen 12 Monate nicht verfügbar</Additional> + </Additionals> + <ReadmeURL lang="de">https://www.ub.uni-leipzig.de/index.php?id=163#ebsco_lfh</ReadmeURL> + <ReadmeURL lang="en">http://www.ub.uni-leipzig.de/kata_db/Readme.htm#ebsco_lfh</ReadmeURL> + </Result> + <Result state="3"> + <Title>Philosophical Perspectives (aktuelle Jahrgänge)</Title> + <JournalURL>http://onlinelibrary.wiley.com/journal/10.1111/%28ISSN%291520-8583</JournalURL> + <AccessURL>http://onlinelibrary.wiley.com/journal/10.1111/%28ISSN%291520-8583</AccessURL> + <AccessLevel>homepage</AccessLevel> + <Additionals> + <Additional type="intervall">ab Vol. 17 (2003)</Additional> + </Additionals> + <ReadmeURL lang="de">https://www.ub.uni-leipzig.de/index.php?id=163#Wiley Core 2015</ReadmeURL> + <ReadmeURL lang="en">http://www.ub.uni-leipzig.de/kata_db/Readme.htm#Wiley Core 2015</ReadmeURL> + </Result> + </ResultList> + </ElectronicData> + <PrintData> + <Library>Universitätsbibliothek Leipzig</Library> + <References> + <Reference> + <URL>http://dispatch.opac.dnb.de/CHARSET=ISO-8859-1/DB=1.1/CMD?ACT=SRCHA&IKT=8509&SRT=LST_ty&TRM=IDN+011960027+or+IDN+01545794X&HLIB=009030085#009030085</URL> + <Label>ZDB-OPAC</Label> + </Reference> + </References> + <ResultList> + <Result state="2"> + <Title>Philosophical perspectives</Title> + <Location>Leipzig UB</Location> + <Holding_comment>Nachweis als Serie</Holding_comment> + </Result> + <Result state="2"> + <Title>Noûs</Title> + <Location>Leipzig UB // HB/FH/ Standortsignatur: 96-7-558</Location> + <Signature>CA 5470 Magazin: 96-7-558</Signature> + <Period>1.1967 - 27.1993; 30.1996 - 43.2009</Period> + <Holding_comment>Letzten 15 Jg. Freihand</Holding_comment> + </Result> + </ResultList> + </PrintData> + </Full> +</OpenURLResponseXML> \ No newline at end of file diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Resolver/Driver/EzbTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Resolver/Driver/EzbTest.php new file mode 100644 index 00000000000..11d0dd2b88b --- /dev/null +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Resolver/Driver/EzbTest.php @@ -0,0 +1,168 @@ +<?php +/** + * Ezb resolver driver test + * + * 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 VuFind + * @package Tests + * @author André Lahmann <lahmann@ub.uni-leipzig.de> + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Page + */ +namespace VuFindTest\Resolver\Driver; +use VuFind\Resolver\Driver\Ezb; + +use Zend\Http\Client\Adapter\Test as TestAdapter; +use Zend\Http\Response as HttpResponse; + +use InvalidArgumentException; + +/** + * Ezb resolver driver test + * + * @category VuFind + * @package Tests + * @author André Lahmann <lahmann@ub.uni-leipzig.de> + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Page + */ +class EzbTest extends \VuFindTest\Unit\TestCase +{ + /** + * Test-Config + * + * @var array + */ + protected $openUrlConfig = [ + 'OpenURL' => [ + 'url' => "http://services.d-nb.de/fize-service/gvr/full.xml", + 'rfr_id' => "www.ub.uni-leipzig.de", + 'resolver' => "ezb", + '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, + 'show_in_record' => false, + 'show_in_holdings' => true, + 'embed' => true, + 'replace_other_urls' => true + ], + ]; + + /** + * Test + * + * @return void + */ + public function testParseLinks() + { + $conn = $this->createConnector('ezb.xml'); + + $openUrl = "url_ver=Z39.88-2004&ctx_ver=Z39.88-2004&ctx_enc=info%3Aofi%2Fenc%3AUTF-8&rfr_id=info%3Asid%2Fwww.ub.uni-leipzig.de%3Agenerator&rft.title=No%C3%BBs&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&rft.creator=&rft.pub=Wiley-Blackwell&rft.format=Journal&rft.language=English&rft.issn=0029-4624&zdbid=339287-9"; + $result = $conn->parseLinks($conn->fetchLinks($openUrl)); + + $testResult = [ + 0 => [ + 'title' => 'Noûs : a Quarterly Journal of Philosophy (1997-)', + 'coverage' => 'ab Vol. 31, Iss. 1 (1997)', + 'access' => 'limited', + 'href' => 'http://onlinelibrary.wiley.com/journal/10.1111/(ISSN)1468-0068', + 'service_type' => 'getFullTxt' + ], + 1 => [ + 'title' => 'Noûs (ältere Jahrgänge via JSTOR)', + 'coverage' => 'ab Vol. 1, Iss. 1 (1967); für die Ausgaben der aktuellen 11 Jahrgänge nicht verfügbar', + 'access' => 'limited', + 'href' => 'http://www.jstor.org/action/showPublication?journalCode=nous', + 'service_type' => 'getFullTxt' + ], + 2 => [ + 'title' => 'Nous (via EBSCO Host)', + 'coverage' => 'für die Ausgaben der vergangenen 12 Monate nicht verfügbar', + 'access' => 'limited', + 'href' => 'http://search.ebscohost.com/direct.asp?db=aph&jid=D97&scope=site', + 'service_type' => 'getFullTxt' + ], + 3 => [ + 'title' => 'Nous (via EBSCO Host)', + 'coverage' => 'für die Ausgaben der vergangenen 12 Monate nicht verfügbar', + 'access' => 'limited', + 'href' => 'http://search.ebscohost.com/direct.asp?db=lfh&jid=D97&scope=site', + 'service_type' => 'getFullTxt' + ], + 4 => [ + 'title' => 'Philosophical Perspectives (aktuelle Jahrgänge)', + 'coverage' => 'ab Vol. 17 (2003)', + 'access' => 'limited', + 'href' => 'http://onlinelibrary.wiley.com/journal/10.1111/%28ISSN%291520-8583', + 'service_type' => 'getFullTxt' + ], + 5 => [ + 'title' => 'Print available', + 'coverage' => 'Philosophical perspectives; Leipzig UB; Nachweis als Serie', + 'access' => 'open', + 'href' => 'http://dispatch.opac.dnb.de/CHARSET=ISO-8859-1/DB=1.1/CMD?ACT=SRCHA&IKT=8509&SRT=LST_ty&TRM=IDN+011960027+or+IDN+01545794X&HLIB=009030085#009030085', + 'service_type' => 'getHolding' + ], + 6 => [ + 'title' => 'Print available', + 'coverage' => 'Noûs; Leipzig UB // HB/FH/ Standortsignatur: 96-7-558; CA 5470 Magazin: 96-7-558; 1.1967 - 27.1993; 30.1996 - 43.2009; Letzten 15 Jg. Freihand', + 'access' => 'open', + 'service_type' => 'getHolding' + ] + ]; + + $this->assertEquals($result, $testResult); + } + + /** + * Create connector with fixture file. + * + * @param string $fixture Fixture file + * + * @return Connector + * + * @throws InvalidArgumentException Fixture file does not exist + */ + protected function createConnector($fixture = null) + { + $adapter = new TestAdapter(); + if ($fixture) { + $file = realpath( + __DIR__ . + '/../../../../../../tests/fixtures/resolver/response/' . $fixture + ); + if (!is_string($file) || !file_exists($file) || !is_readable($file)) { + throw new InvalidArgumentException( + sprintf('Unable to load fixture file: %s ', $file) + ); + } + $response = file_get_contents($file); + $responseObj = HttpResponse::fromString($response); + $adapter->setResponse($responseObj); + } + $_SERVER['REMOTE_ADDR'] = "127.0.0.1"; + + $client = new \Zend\Http\Client(); + $client->setAdapter($adapter); + + $conn = new Ezb($this->openUrlConfig['OpenURL']['url'], $client); + return $conn; + } +} diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/OpenUrlTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/OpenUrlTest.php index 6cd82aec1ce..5c02af1a1c1 100644 --- a/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/OpenUrlTest.php +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/OpenUrlTest.php @@ -295,7 +295,9 @@ class OpenUrlTest extends \VuFindTest\Unit\ViewHelperTestCase if (null === $mockContext) { $mockContext = $this->getMockContext(); } - $openUrl = new OpenUrl($mockContext, $rules, new Config($config)); + $mockPm = $this->getMockBuilder('VuFind\Resolver\Driver\PluginManager') + ->getMock(); + $openUrl = new OpenUrl($mockContext, $rules, $mockPm, new Config($config)); $openUrl->setView($this->getPhpRenderer()); return $openUrl; } diff --git a/themes/bootstrap3/templates/Helpers/openurl.phtml b/themes/bootstrap3/templates/Helpers/openurl.phtml index f68528b4b61..22d5cac3e2f 100644 --- a/themes/bootstrap3/templates/Helpers/openurl.phtml +++ b/themes/bootstrap3/templates/Helpers/openurl.phtml @@ -16,7 +16,7 @@ <span class="openUrlControls<? if ($this->openUrlEmbed): ?> openUrlEmbed<? if ($this->openUrlEmbedAutoLoad): ?> openUrlEmbedAutoLoad<? endif; ?><? endif; ?>"> <? if (!$this->openUrlImageBasedSrc || $this->openUrlImageBasedMode == 'both'): ?> - <a href="<?=$this->escapeHtmlAttr($this->openUrlBase . '?' . $this->openUrl)?>"<?=$class?> data-search-class-id="<?=$this->escapeHtmlAttr($this->searchClassId) ?>"> + <a href="<?=$this->escapeHtmlAttr($this->resolverUrl)?>"<?=$class?> data-search-class-id="<?=$this->escapeHtmlAttr($this->searchClassId) ?>"> <? /* put the openUrl here in a span (COinS almost) so we can retrieve it later */ ?> <span title="<?=$this->escapeHtmlAttr($this->openUrl)?>" class="openUrl"></span> <? if ($this->openUrlGraphic): ?> diff --git a/themes/bootstrap3/templates/ajax/resolverLinks.phtml b/themes/bootstrap3/templates/ajax/resolverLinks.phtml index 735b8f2b51a..2a602e55378 100644 --- a/themes/bootstrap3/templates/ajax/resolverLinks.phtml +++ b/themes/bootstrap3/templates/ajax/resolverLinks.phtml @@ -32,7 +32,7 @@ </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->moreOptionsLink)): ?><strong><a href="<?=$this->escapeHtmlAttr($this->moreOptionsLink)?>"><?=$this->transEsc('More options')?></a></strong><?endif; ?> <? if (!empty($this->services)): ?> <ul> <? foreach ($this->services as $link): ?> -- GitLab