Commit 25f12f71 authored by Sven-S. Porst's avatar Sven-S. Porst
Browse files

Refactor Query class to have subclasses for Pazpar2 and Service Proxy respectively

parent 3a4df2be
......@@ -59,6 +59,18 @@ class Tx_Pazpar2_Controller_Pazpar2Controller extends Tx_Extbase_MVC_Controller_
/**
* @return Tx_Pazpar2_Domain_Model_Query
*/
protected function createQuery () {
$query = t3lib_div::makeInstance('Tx_Pazpar2_Domain_Model_QueryPazpar2');
$query->setPazpar2Path($this->getPazpar2Path());
$query->setServiceName($this->conf['serviceID']);
return $query;
}
/**
* Initialiser
*
......@@ -79,7 +91,7 @@ class Tx_Pazpar2_Controller_Pazpar2Controller extends Tx_Extbase_MVC_Controller_
}
}
$this->query = t3lib_div::makeInstance('Tx_Pazpar2_Domain_Model_Query');
$this->query = $this->createQuery();
$this->query->setQueryFromArguments($this->request->getArguments());
}
......@@ -99,9 +111,7 @@ class Tx_Pazpar2_Controller_Pazpar2Controller extends Tx_Extbase_MVC_Controller_
$this->view->assign('extended', $arguments['extended']);
$this->view->assign('query', $this->query);
if (array_key_exists('useJS', $arguments) && $arguments['useJS'] !== 'yes') {
$this->query->setServiceName($this->conf['serviceID']);
$this->query->setSortOrder($this->determineSortCriteria($arguments));
$this->query->setPazpar2Path($this->getPazpar2Path());
$this->query->run();
}
$this->view->assign('conf', $this->conf);
......
......@@ -2,8 +2,7 @@
/*******************************************************************************
* Copyright notice
*
* Copyright (C) 2013 by Sven-S. Porst
* <ssp-web@earthlingsoft.net>
* Copyright (C) 2013 by Sven-S. Porst <ssp-web@earthlingsoft.net>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
......@@ -42,31 +41,27 @@
class Tx_Pazpar2_Controller_Pazpar2serviceproxyController extends Tx_Pazpar2_Controller_Pazpar2Controller {
/**
* Initialiser.
* Returns the path of the pazpar2 service on the server or NULL.
*
* Initialises parent class and sets up model object.
*
* @return void
* @return String|NULL
*/
public function initializeAction() {
parent::initializeAction();
protected function getPazpar2Path () {
return $this->conf['serviceProxyPath'];
}
/**
* Index: Make superclass insert <script> and <link> tags into <head>.
* Load subjects, set up the query string, run the superclass’ action
* (which does the relevant pazpar2 queries if necessary) and assign the
* results to the view.
*
* @return void
* @return Tx_Pazpar2_Domain_Model_Query
*/
public function indexAction () {
parent::indexAction();
protected function createQuery () {
$query = t3lib_div::makeInstance('Tx_Pazpar2_Domain_Model_QueryServiceProxy');
$query->setServiceProxyAuthPath($this->conf['serviceProxyAuthPath']);
$query->setPazpar2Path($this->getPazpar2Path());
return $query;
}
/**
* Adds <script> element to <head> containing the configuration for the
......
......@@ -168,14 +168,14 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
/**
* @return string|Null
*/
public function getInstitutionName () {
protected function getInstitutionName () {
return $this->institutionName;
}
/**
* @param string $newInstitutionName
*/
private function setInstitutionName ($newInstitutionName) {
protected function setInstitutionName ($newInstitutionName) {
$this->institutionName = $newInstitutionName;
}
......@@ -191,14 +191,14 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
/**
* @return Boolean
*/
public function getDidRun () {
protected function getDidRun () {
return $this->didRun;
}
/**
* @param Boolean $newDidRun
*/
private function setDidRun ($newDidRun) {
protected function setDidRun ($newDidRun) {
$this->didRun = $newDidRun;
}
......@@ -222,7 +222,7 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
/**
* @param Boolean $newAllTargetsActive
*/
private function setAllTargetsActive ($newAllTargetsActive) {
protected function setAllTargetsActive ($newAllTargetsActive) {
$this->allTargetsActive = $newAllTargetsActive;
}
......@@ -296,7 +296,7 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
/**
* @param integer $newTotalResultCount
*/
private function setTotalResultCount ($newTotalResultCount) {
protected function setTotalResultCount ($newTotalResultCount) {
$this->totalResultCount = $newTotalResultCount;
}
......@@ -306,12 +306,6 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
* VARIABLES FOR INTERNAL USE
*/
/**
* Stores session ID while pazpar2 is running.
* @var string
*/
protected $pazpar2SessionID;
/**
* Stores state of query.
* @var Boolean
......@@ -335,7 +329,7 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
* @param string $searchString
* @return string
*/
private function createSearchString ($indexName, $searchString) {
protected function createSearchString ($indexName, $searchString) {
$search = '(' . $indexName . '=' . $searchString . ')';
$search = str_replace(' and ', ' and ' . $indexName . '=', $search);
$search = str_replace(' not ', ' not ' . $indexName . '=', $search);
......@@ -351,7 +345,7 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
*
* @return string
*/
private function fullQueryString () {
protected function fullQueryString () {
$queryParts = Array();
// Main search can be default search or full text search.
......@@ -397,9 +391,9 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
* Returns URL to initialise pazpar2.
* If $serviceName has been set up, that service is used.
*
* @return sting
* @return string
*/
private function pazpar2InitURL () {
protected function pazpar2InitURL () {
$URL = $this->getPazpar2BaseURL() . '?command=init';
if ($this->getServiceName() != Null) {
$URL .= '&service=' . urlencode($this->getServiceName());
......@@ -411,12 +405,12 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
/**
* Returns URL for starting a search with the current pazpar2 session.
* Returns URL for pazpar2 search command.
*
* @return string
*/
private function pazpar2SearchURL () {
protected function pazpar2SearchURL () {
$URL = $this->getPazpar2BaseURL() . '?command=search';
$URL .= '&session=' . $this->pazpar2SessionID;
$URL .= '&query=' . urlencode($this->fullQueryString());
return $URL;
......@@ -425,14 +419,12 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
/**
* Returns URL for a status request of the current pazpar2 session.
* Returns URL for pazpar2 status command.
*
* @return string
*/
private function pazpar2StatURL () {
$URL = $this->getPazpar2BaseURL() . '?command=stat';
$URL .= '&session=' . $this->pazpar2SessionID;
return $URL;
protected function pazpar2StatURL () {
return $this->getPazpar2BaseURL() . '?command=stat';
}
......@@ -449,9 +441,8 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
* @param int $num number of records to retrieve (optional, default: 500)
* @return string
*/
private function pazpar2ShowURL ($start=0, $num=500) {
protected function pazpar2ShowURL ($start=0, $num=500) {
$URL = $this->getPazpar2BaseURL() . '?command=show';
$URL .= '&session=' . $this->pazpar2SessionID;
$URL .= '&query=' . urlencode($this->fullQueryString());
$URL .= '&start=' . $start . '&num=' . $num;
$URL .= '&sort=' . urlencode($this->sortOrderString());
......@@ -466,7 +457,7 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
*
* @return string
*/
private function sortOrderString () {
protected function sortOrderString () {
$sortOrderComponents = Array();
foreach ($this->getSortOrder() as $sortCriterion) {
$sortOrderComponents[] = $sortCriterion['fieldName'] . ':'
......@@ -480,38 +471,25 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
/**
* Initialise the pazpar2 session and store the session ID in $pazpar2SessionID.
* Returns the content loaded from the given URL.
*
* @param string $URL to fetch
* @return string
*/
protected function initialiseSession () {
$this->queryStartTime = time();
$initReplyString = t3lib_div::getURL($this->pazpar2InitURL());
$initReply = t3lib_div::xml2array($initReplyString);
if ($initReply) {
$status = $initReply['status'];
if ($status == 'OK') {
$sessionID = $initReply['session'];
if ($sessionID) {
$this->pazpar2SessionID = $sessionID;
}
else {
t3lib_div::devLog('did not receive pazpar2 session ID', 'pazpar2', 3);
}
protected function fetchURL ($URL) {
return t3lib_div::getURL($URL);
}
// Extract access rights information if it is available.
if (array_key_exists('accessRights', $initReply)) {
$accessRights = $initReply['accessRights'];
$this->setInstitutionName($accessRights['institutionName']);
$this->setAllTargetsActive($accessRights['allTargetsActive'] === '1');
}
}
else {
t3lib_div::devLog('pazpar2 init status is not "OK" but "' . $status . '"', 'pazpar2', 3);
}
}
else {
t3lib_div::devLog('could not parse pazpar2 init reply', 'pazpar2', 3);
}
/**
* Initialise pazpar2/Service Proxy.
* To be implemented in subclasses.
*
* @return boolean TRUE when initialisation was successful.
*/
protected function initialiseSession () {
return FALSE;
}
......@@ -521,15 +499,14 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
* Requires $pazpar2SessionID to be set.
*/
protected function startQuery () {
$this->initialiseSession();
if ($this->pazpar2SessionID) {
$searchReplyString = t3lib_div::getURL($this->pazpar2SearchURL());
$sessionOK = $this->initialiseSession();
if ($sessionOK) {
$searchReplyString = $this->fetchURL($this->pazpar2SearchURL());
$searchReply = t3lib_div::xml2array($searchReplyString);
if ($searchReply) {
$status = $searchReply['status'];
if ($status == 'OK') {
if ($status === 'OK') {
$this->queryIsRunning = True;
}
else {
......@@ -554,7 +531,7 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
protected function queryIsDone () {
$result = False;
$statReplyString = t3lib_div::getURL($this->pazpar2StatURL());
$statReplyString = $this->fetchURL($this->pazpar2StatURL());
$statReply = t3lib_div::xml2array($statReplyString);
if ($statReply) {
......@@ -585,7 +562,7 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
* @param Array $record location or full pazpar2 record
* @return Array of integers
*/
private function extractNewestDates ($record) {
protected function extractNewestDates ($record) {
$result = Array();
if (array_key_exists('md-date', $record['ch'])) {
......@@ -613,7 +590,7 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
* @param Array $b location or full pazpar2 record
* @return integer
*/
private function yearSort($a, $b) {
protected function yearSort($a, $b) {
$aDates = $this->extractNewestDates($a);
$bDates = $this->extractNewestDates($b);
......@@ -652,7 +629,7 @@ class Tx_Pazpar2_Domain_Model_Query extends Tx_Extbase_DomainObject_AbstractEnti
// in t3lib_div::xml2tree. We seem to typically need ~100KB per record (?).
while ($firstRecord < $maxResults) {
$recordsToFetchNow = min(Array($recordsToFetch, $maxResults - $firstRecord));
$showReplyString = t3lib_div::getURL($this->pazpar2ShowURL($firstRecord, $recordsToFetchNow));
$showReplyString = $this->fetchURL($this->pazpar2ShowURL($firstRecord, $recordsToFetchNow));
$firstRecord += $recordsToFetchNow;
// need xml2tree here as xml2array fails when dealing with arrays of tags with the same name
......
<?php
/*******************************************************************************
* Copyright notice
*
* Copyright (C) 2013 by Sven-S. Porst, SUB Göttingen
* <porst@sub.uni-goettingen.de>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
/**
* QueryPazpar2.php
*
* Pazpar2 specific aspects of the Query class.
*
* @author Sven-S. Porst <porst@sub-uni-goettingen.de>
*/
/**
* Query model object.
*/
class Tx_Pazpar2_Domain_Model_QueryPazpar2 extends Tx_Pazpar2_Domain_Model_Query {
/**
* VARIABLES FOR INTERNAL USE
*/
/**
* Stores session ID while pazpar2 is running.
* @var string
*/
protected $pazpar2SessionID;
/**
* Returns URL for pazpar2 search command.
*
* @return string
*/
protected function pazpar2SearchURL () {
return $this->appendSessionID(parent::pazpar2SearchURL());
}
/**
* Returns URL for a status request of the current pazpar2 session.
*
* @return string
*/
protected function pazpar2StatURL () {
return $this->appendSessionID(parent::pazpar2StatURL());
}
/**
* Returns URL for downloading pazpar2 results.
* The parameters can be used to give the the start record
* as well as the number of records required.
*
* TYPO3 typically starts running into out of memory errors when fetching
* around 1000 records in one go with a 128MB memory limit for PHP.
*
* @param int $start index of first record to retrieve (optional, default: 0)
* @param int $num number of records to retrieve (optional, default: 500)
* @return string
*/
protected function pazpar2ShowURL ($start=0, $num=500) {
return $this->appendSessionID(parent::pazpar2ShowURL($start, $num));
}
/**
* Appends the session ID to $URL.
*
* @param string $URL
* @return string
*/
protected function appendSessionID ($URL) {
return $URL . '&session=' . $this->pazpar2SessionID;
}
/**
* Initialise the pazpar2 session and store the session ID in $pazpar2SessionID.
*
* @return boolean TRUE when initialisation was successful
*/
protected function initialiseSession () {
$this->queryStartTime = time();
$initReplyString = $this->fetchURL($this->pazpar2InitURL());
$initReply = t3lib_div::xml2array($initReplyString);
if ($initReply) {
$status = $initReply['status'];
if ($status === 'OK') {
$sessionID = $initReply['session'];
if ($sessionID) {
$this->pazpar2SessionID = $sessionID;
}
else {
t3lib_div::devLog('did not receive pazpar2 session ID', 'pazpar2', 3);
}
// Extract access rights information if it is available.
if (array_key_exists('accessRights', $initReply)) {
$accessRights = $initReply['accessRights'];
$this->setInstitutionName($accessRights['institutionName']);
$this->setAllTargetsActive($accessRights['allTargetsActive'] === '1');
}
}
else {
t3lib_div::devLog('pazpar2 init status is not "OK" but "' . $status . '"', 'pazpar2', 3);
}
}
else {
t3lib_div::devLog('could not parse pazpar2 init reply', 'pazpar2', 3);
}
return ($this->pazpar2SessionID !== NULL);
}
}
?>
<?php
/*******************************************************************************
* Copyright notice
*
* Copyright (C) 2013 by Sven-S. Porst <ssp-web@earthlingsoft.net>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
/**
* QueryServiceProxy.php
*
* Service Proxy specific aspects of the Query class.
*
* @author Sven-S. Porst <ssp-web@earthlingsoft.net>
*/
/**
* Query model object.
*/
class Tx_Pazpar2_Domain_Model_QueryServiceProxy extends Tx_Pazpar2_Domain_Model_Query {
/**
* VARIABLES FOR INTERNAL USE
*/
/**
* Stores the cookie provided by Service Proxy.
* @var string
*/
protected $cookie;
/**
* Absolute path of the Service Proxy authentication service on the host.
*
* @var string
*/
protected $serviceProxyAuthPath;
/**
* @return string
*/
public function getServiceProxyAuthPath () {
return $this->serviceProxyAuthPath;
}
/**
* @param string $newPazpar2Path
* @return void
*/
public function setServiceProxyAuthPath ($newServiceProxyAuthPath) {
$this->serviceProxyAuthPath = $newServiceProxyAuthPath;
}
/**
* Return URL of pazpar2 service.
* If it is not set, return default URL on localhost.
*
* @return string
*/
public function getServiceProxyAuthURL () {
$URL = 'http://' . t3lib_div::getIndpEnv(HTTP_HOST) . $this->getServiceProxyAuthPath();
return $URL;
}
/**
* Returns the content loaded from the given URL.
* Uses curl to fetch the cookie from the response and insert it into
* requests, if available.
*
* @param string $URL to fetch
* @return string
*/
protected function fetchURL ($URL) {
$cookieHeader = array();
if ($this->cookie) {
$cookieHeader[] = 'Cookie: ' . $this->cookie . ';';
}
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $URL);
curl_setopt($curl, CURLOPT_HEADER, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HTTPHEADER, $cookieHeader);
$body = NULL;
$result = curl_exec($curl);
if ($result) {
$parts = explode("\r\n\r\n", $result, 2);
$headers = explode("\r\n", $parts[0]);
if (!$this->cookie) {
$setCookieString = 'Set-Cookie: ';
foreach ($headers as $header) {
if (strpos($header, $setCookieString) === 0) {
$cookieString = substr($header, strlen($setCookieString));
$cookieStringParts = explode(";", $cookieString);
$this->cookie = $cookieStringParts[0];
break;
}
}