Paul Pound
12 years ago
7 changed files with 1843 additions and 37 deletions
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<Config> |
||||
<Version>EDS API-PHP Demo 1.4</Version> |
||||
<EndPoints> |
||||
<EndPoint>http://eds-api.ebscohost.com/edsapi/rest</EndPoint> |
||||
<AuthenticationEndPoint>https://eds-api.ebscohost.com/Authservice/rest</AuthenticationEndPoint> |
||||
</EndPoints> |
||||
<AbstractLength>300</AbstractLength> |
||||
<ClientCredentials> |
||||
<User> |
||||
<UserId>insert client side profile</UserId> |
||||
<Password>insert client side profile</Password> |
||||
</User> |
||||
</ClientCredentials> |
||||
|
||||
<EDSCredentials> |
||||
<User> |
||||
<ClientUser>guest</ClientUser> |
||||
<EDSUserID>uprince</EDSUserID> |
||||
<EDSPassword>robertson1</EDSPassword> |
||||
<EDSProfile>edsapi</EDSProfile> |
||||
</User> |
||||
</EDSCredentials> |
||||
</Config> |
@ -0,0 +1,391 @@
|
||||
<?php |
||||
|
||||
|
||||
/** |
||||
* EBSCO API class |
||||
* |
||||
* PHP version 5 |
||||
* |
||||
*/ |
||||
|
||||
|
||||
/** |
||||
* EBSCO API class |
||||
*/ |
||||
class EBSCOAPI |
||||
{ |
||||
/** |
||||
* The authentication token used for API transactions |
||||
* @global string |
||||
*/ |
||||
private $authenticationToken; |
||||
|
||||
|
||||
/** |
||||
* The session token for API transactions |
||||
* @global string |
||||
*/ |
||||
private $sessionToken; |
||||
|
||||
/** |
||||
* The EBSCOConnector object used for API transactions |
||||
* @global object EBSCOConnector |
||||
*/ |
||||
private $connector; |
||||
|
||||
private $config; |
||||
|
||||
public function __construct($config) { |
||||
$this->config = $config; |
||||
$this->connector = new EBSCOConnector($config); |
||||
} |
||||
|
||||
/** |
||||
* Create a new EBSCOConnector object or reuse an existing one |
||||
* |
||||
* @param none |
||||
* |
||||
* @return EBSCOConnector object |
||||
* @access public |
||||
*/ |
||||
public function connector($config) |
||||
{ |
||||
if (empty($this->connector)) { |
||||
$this->connector = new EBSCOConnector($config); |
||||
} |
||||
|
||||
return $this->connector; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Create a new EBSCOResponse object |
||||
* |
||||
* @param object $response |
||||
* |
||||
* @return EBSCOResponse object |
||||
* @access public |
||||
*/ |
||||
public function response($response) |
||||
{ |
||||
$responseObj = new EBSCOResponse($response); |
||||
return $responseObj; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Request authentication and session tokens, then send the API request. |
||||
* Retry the request if authentication errors occur |
||||
* |
||||
* @param string $action The EBSCOConnector method name |
||||
* @param array $params The parameters for the HTTP request |
||||
* @param integer $attempts The number of retries. The default number is 3 but can be increased. |
||||
* 3 retries can handle a situation when both autentication and session tokens need to be refreshed + the current API call |
||||
* |
||||
* @return array An associative array with results. |
||||
* @access protected |
||||
*/ |
||||
protected function request($action, $params = null, $attempts = 3) |
||||
{ |
||||
try { |
||||
|
||||
$authenticationToken = $this->getAuthToken(); |
||||
$sessionToken = $this->getSessionToken($authenticationToken); |
||||
|
||||
if(empty($authenticationToken)){ |
||||
$authenticationToken = $this -> getAuthToken(); |
||||
} |
||||
|
||||
if(empty($sessionToken)){ |
||||
$sessionToken = $this -> getSessionToken($authenticationToken,'y'); |
||||
} |
||||
|
||||
$headers = array( |
||||
'x-authenticationToken: ' . $authenticationToken, |
||||
'x-sessionToken: ' . $sessionToken |
||||
); |
||||
|
||||
$response = call_user_func_array(array($this->connector($this->config), "request{$action}"), array($params, $headers)); |
||||
$result = $this->response($response)->result(); |
||||
$results = $result; |
||||
return $results; |
||||
} catch(EBSCOException $e) { |
||||
try { |
||||
// Retry the request if there were authentication errors |
||||
$code = $e->getCode(); |
||||
switch ($code) { |
||||
case EBSCOConnector::EDS_AUTH_TOKEN_INVALID: |
||||
$authenticationToken = $this->getAuthToken(); |
||||
$sessionToken = $this ->getSessionToken($authenticationToken); |
||||
$headers = array( |
||||
'x-authenticationToken: ' . $authenticationToken, |
||||
'x-sessionToken: ' . $sessionToken |
||||
); |
||||
if ($attempts > 0) { |
||||
return $this->request($action, $params, $headers, --$attempts); |
||||
} |
||||
break; |
||||
case EBSCOConnector::EDS_SESSION_TOKEN_INVALID: |
||||
$sessionToken = $this ->getSessionToken($authenticationToken,'y'); |
||||
$headers = array( |
||||
'x-authenticationToken: ' . $authenticationToken, |
||||
'x-sessionToken: ' . $sessionToken |
||||
); |
||||
if ($attempts > 0) { |
||||
return $this->request($action, $params, $headers, --$attempts); |
||||
} |
||||
break; |
||||
default: |
||||
$result = array( |
||||
'error' => $e->getMessage() |
||||
); |
||||
return $result; |
||||
break; |
||||
} |
||||
} catch(Exception $e) { |
||||
$result = array( |
||||
'error' => $e->getMessage() |
||||
); |
||||
return $result; |
||||
} |
||||
} catch(Exception $e) { |
||||
$result = array( |
||||
'error' => $e->getMessage() |
||||
); |
||||
return $result; |
||||
} |
||||
} |
||||
|
||||
private function writeLockFile(){ |
||||
$tokenFile = fopen("edstoken.txt","w+"); |
||||
$result = $this->apiAuthenticationToken(); |
||||
fwrite($tokenFile, $result['authenticationToken']."\n"); |
||||
fwrite($tokenFile, $result['authenticationTimeout']."\n"); |
||||
fwrite($tokenFile, $result['authenticationTimeStamp']); |
||||
fclose($tokenFile); |
||||
return $result['authenticationToken']; |
||||
} |
||||
|
||||
/* |
||||
* Get authentication token from appication scop |
||||
* Check authToen's expiration |
||||
* if expired get a new authToken and re-new the time stamp |
||||
* |
||||
* @param none |
||||
* |
||||
* @access public |
||||
*/ |
||||
public function getAuthToken(){ |
||||
$lockFile = fopen("edslock.txt","r"); |
||||
$tokenFile =fopen("edstoken.txt","r"); |
||||
if(empty($lockFile) || empty($tokenFile)){ |
||||
return $this->writeLockFile(); |
||||
} |
||||
while(!feof($tokenFile)){ |
||||
$authToken = rtrim(fgets($tokenFile),"\n"); |
||||
$timeout = fgets($tokenFile)-600; |
||||
$timestamp = fgets($tokenFile); |
||||
} |
||||
fclose($tokenFile); |
||||
if(time()-$timestamp>=$timeout){ |
||||
// Lock check. |
||||
if(flock($lockFile, LOCK_EX)){ |
||||
$tokenFile = fopen("edstoken.txt","w+"); |
||||
$result = $this->apiAuthenticationToken(); |
||||
fwrite($tokenFile, $result['authenticationToken']."\n"); |
||||
fwrite($tokenFile, $result['authenticationTimeout']."\n"); |
||||
fwrite($tokenFile, $result['authenticationTimeStamp']); |
||||
fclose($tokenFile); |
||||
return $result['authenticationToken']; |
||||
}else{ |
||||
return $authToken; |
||||
} |
||||
}else{ |
||||
return $authToken; |
||||
} |
||||
fclose($lockFile); |
||||
} |
||||
|
||||
/** |
||||
* Wrapper for authentication API call |
||||
* |
||||
* @param none |
||||
* |
||||
* @access public |
||||
*/ |
||||
public function apiAuthenticationToken() |
||||
{ |
||||
$response = $this->connector->requestAuthenticationToken(); |
||||
$result = $this->response($response)->result(); |
||||
return $result; |
||||
} |
||||
|
||||
/** |
||||
* Get session token for a profile |
||||
* If session token is not available |
||||
* a new session token will be generated |
||||
* |
||||
* @param Authentication token, Profile |
||||
* @access public |
||||
*/ |
||||
public function getSessionToken($authenToken, $invalid='n'){ |
||||
$token = ''; |
||||
|
||||
// Check user's login status |
||||
if(isset($_COOKIE['login'])){ |
||||
if($invalid=='y'){ |
||||
$profile = $_SESSION['sessionToken']['profile']; |
||||
$sessionToken = $this->apiSessionToken($authenToken, $profile,'n'); |
||||
$_SESSION['sessionToken']=$sessionToken; |
||||
} |
||||
$token = $_SESSION['sessionToken']['sessionToken']; |
||||
} |
||||
else if(isset($_COOKIE['Guest'])){ |
||||
if($invalid=='y'){ |
||||
$profile = $_SESSION['sessionToken']['profile']; |
||||
$sessionToken = $this->apiSessionToken($authenToken, $profile,'y'); |
||||
$_SESSION['sessionToken']=$sessionToken; |
||||
} |
||||
$token = $_SESSION['sessionToken']['sessionToken']; |
||||
}else{ |
||||
//$xml ="Config.xml"; |
||||
//$dom = new DOMDocument(); |
||||
//$dom->load($xml); |
||||
//$EDSCredentials = $dom ->getElementsByTagName('EDSCredentials')->item(0); |
||||
//$users = $EDSCredentials -> getElementsByTagName('User'); |
||||
$profileId = $this->config['profile']; |
||||
//foreach($users as $user){ |
||||
// $userType = $user->getElementsByTagName('ClientUser')->item(0)->nodeValue; |
||||
// if($userType == 'guest'){ |
||||
// $profileId = $user -> getElementsByTagName('EDSProfile')->item(0)->nodeValue; |
||||
// break; |
||||
// } |
||||
//} |
||||
$sessionToken = $this->apiSessionToken($authenToken, $profileId,'y'); |
||||
$_SESSION['profile'] = $profileId; |
||||
$_SESSION['sessionToken']=$sessionToken; |
||||
setcookie("Guest", $profileId, 0); |
||||
$token = $sessionToken['sessionToken']; |
||||
} |
||||
return $token; |
||||
} |
||||
|
||||
/** |
||||
* Wrapper for session API call |
||||
* |
||||
* @param Authentication token |
||||
* |
||||
* @access public |
||||
*/ |
||||
public function apiSessionToken($authenToken, $profile, $guest) |
||||
{ |
||||
// Add authentication tokens to headers |
||||
$headers = array( |
||||
'x-authenticationToken: ' . $authenToken |
||||
); |
||||
|
||||
$response = $this->connector($this->config)->requestSessionToken($headers, $profile,$guest); |
||||
$result = $this->response($response)->result(); |
||||
$token = array( |
||||
'sessionToken'=>$result, |
||||
'profile' => $profile |
||||
); |
||||
return $token; |
||||
} |
||||
|
||||
/** |
||||
* Wrapper for end session API call |
||||
* |
||||
* @param Authentication token |
||||
* |
||||
* @access public |
||||
*/ |
||||
public function apiEndSessionToken($authenToken, $sessionToken){ |
||||
|
||||
// Add authentication tokens to headers |
||||
$headers = array( |
||||
'x-authenticationToken: '.$authenToken |
||||
); |
||||
|
||||
$this -> connector($this->config)->requestEndSessionToken($headers, $sessionToken); |
||||
} |
||||
|
||||
/** |
||||
* Wrapper for search API call |
||||
* |
||||
* @param |
||||
* |
||||
* @throws object PEAR Error |
||||
* @return array An array of query results |
||||
* @access public |
||||
*/ |
||||
public function apiSearch($params) { |
||||
|
||||
$results = $this->request('Search', $params); |
||||
return $results; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Wrapper for retrieve API call |
||||
* |
||||
* @param array $an The accession number |
||||
* @param string $start The short database name |
||||
* |
||||
* @throws object PEAR Error |
||||
* @return array An associative array of data |
||||
* @access public |
||||
*/ |
||||
public function apiRetrieve($an, $db, $term) |
||||
{ |
||||
// Add the HTTP query params |
||||
$params = array( |
||||
'an' => $an, |
||||
'dbid' => $db, |
||||
'highlightterms' => $term // Get currect param name |
||||
); |
||||
$params = http_build_query($params); |
||||
$result = $this->request('Retrieve', $params); |
||||
return $result; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Wrapper for info API call |
||||
* |
||||
* @return array An associative array of data |
||||
* @access public |
||||
*/ |
||||
public function getInfo() |
||||
{ |
||||
if(isset($_SESSION['info'])){ |
||||
$InfoArray = $_SESSION['info']; |
||||
$timestamp = $InfoArray['timestamp']; |
||||
if(time()-$timestamp>=3600){ |
||||
// Get new Info for the profile |
||||
$InfoArray = $this->apiInfo(); |
||||
$_SESSION['info'] = $InfoArray; |
||||
$info = $InfoArray['Info']; |
||||
}else{ |
||||
$info = $InfoArray['Info']; |
||||
} |
||||
}else{ |
||||
// Get new Info for the profile |
||||
$InfoArray = $this->apiInfo(); |
||||
$_SESSION['info'] = $InfoArray; |
||||
$info = $InfoArray['Info']; |
||||
} |
||||
return $info; |
||||
} |
||||
|
||||
public function apiInfo(){ |
||||
|
||||
$response = $this->request('Info',''); |
||||
$Info = array( |
||||
'Info' => $response, |
||||
'timestamp'=>time() |
||||
); |
||||
return $Info; |
||||
} |
||||
} |
||||
?> |
@ -0,0 +1,379 @@
|
||||
<?php |
||||
|
||||
/** |
||||
* EBSCO Connector class |
||||
* |
||||
* PHP version 5 |
||||
* |
||||
*/ |
||||
|
||||
/** |
||||
* EBSCOException class |
||||
* Used when EBSCO API calls return an error message |
||||
*/ |
||||
class EBSCOException extends Exception { |
||||
|
||||
} |
||||
|
||||
/** |
||||
* EBSCO Connector class |
||||
*/ |
||||
class EBSCOConnector { |
||||
/** |
||||
* Error codes defined by EDS API |
||||
* |
||||
* @global integer EDS_UNKNOWN_PARAMETER Unknown Parameter |
||||
* @global integer EDS_INCORRECT_PARAMETER_FORMAT Incorrect Parameter Format |
||||
* @global integer EDS_INCORRECT_PARAMETER_FORMAT Invalid Parameter Index |
||||
* @global integer EDS_MISSING_PARAMETER Missing Parameter |
||||
* @global integer EDS_AUTH_TOKEN_INVALID Auth Token Invalid |
||||
* ... |
||||
*/ |
||||
|
||||
const EDS_UNKNOWN_PARAMETER = 100; |
||||
const EDS_INCORRECT_PARAMETER_FORMAT = 101; |
||||
const EDS_INVALID_PARAMETER_INDEX = 102; |
||||
const EDS_MISSING_PARAMETER = 103; |
||||
const EDS_AUTH_TOKEN_INVALID = 104; |
||||
const EDS_INCORRECT_ARGUMENTS_NUMBER = 105; |
||||
const EDS_UNKNOWN_ERROR = 106; |
||||
const EDS_AUTH_TOKEN_MISSING = 107; |
||||
const EDS_SESSION_TOKEN_MISSING = 108; |
||||
const EDS_SESSION_TOKEN_INVALID = 109; |
||||
const EDS_INVALID_RECORD_FORMAT = 110; |
||||
const EDS_UNKNOWN_ACTION = 111; |
||||
const EDS_INVALID_ARGUMENT_VALUE = 112; |
||||
const EDS_CREATE_SESSION_ERROR = 113; |
||||
const EDS_REQUIRED_DATA_MISSING = 114; |
||||
const EDS_TRANSACTION_LOGGING_ERROR = 115; |
||||
const EDS_DUPLICATE_PARAMETER = 116; |
||||
const EDS_UNABLE_TO_AUTHENTICATE = 117; |
||||
const EDS_SEARCH_ERROR = 118; |
||||
const EDS_INVALID_PAGE_SIZE = 119; |
||||
const EDS_SESSION_SAVE_ERROR = 120; |
||||
const EDS_SESSION_ENDING_ERROR = 121; |
||||
const EDS_CACHING_RESULTSET_ERROR = 122; |
||||
|
||||
|
||||
/** |
||||
* HTTP status codes constants |
||||
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html |
||||
*/ |
||||
const HTTP_OK = 200; |
||||
const HTTP_BAD_REQUEST = 400; |
||||
const HTTP_NOT_FOUND = 404; |
||||
const HTTP_INTERNAL_SERVER_ERROR = 500; |
||||
|
||||
/** |
||||
* The URL of the EBSCO API server |
||||
* @global string |
||||
*/ |
||||
private $end_point; |
||||
|
||||
/** |
||||
* The URL of the EBSCO API server |
||||
* @global string |
||||
*/ |
||||
private $authentication_end_point; |
||||
|
||||
/** |
||||
* The password used for API transactions |
||||
* @global string |
||||
*/ |
||||
private $password; |
||||
|
||||
/** |
||||
* The user id used for API transactions |
||||
* @global string |
||||
*/ |
||||
private $userId; |
||||
|
||||
/** |
||||
* The interface ID used for API transactions |
||||
* @global string |
||||
*/ |
||||
private $interfaceId; |
||||
|
||||
/** |
||||
* The customer ID used for API transactions |
||||
* @global string |
||||
*/ |
||||
private $orgId; |
||||
|
||||
private $profiled; |
||||
|
||||
/** |
||||
* Constructor |
||||
* |
||||
* Setup the EBSCO API credentials |
||||
* |
||||
* @param none |
||||
* |
||||
* @access public |
||||
*/ |
||||
public function __construct($config) { |
||||
|
||||
$this->end_point = $config['rest_url']; |
||||
$this->authentication_end_point = $config['auth_url']; |
||||
|
||||
$this->userId = $config['user']; |
||||
$this->password = $config['pass']; |
||||
$this->profiled = $config['profile']; |
||||
$this->interfaceId = ''; |
||||
$this->orgId = ''; |
||||
} |
||||
|
||||
/** |
||||
* Request the authentication token |
||||
* |
||||
* @param none |
||||
* |
||||
* @return string .The authentication token |
||||
* @access public |
||||
*/ |
||||
public function requestAuthenticationToken() { |
||||
$url = $this->authentication_end_point . '/UIDAuth'; |
||||
// Add the body of the request. Important. |
||||
$params = <<<BODY |
||||
<UIDAuthRequestMessage xmlns="http://www.ebscohost.com/services/public/AuthService/Response/2012/06/01"> |
||||
<UserId>{$this->userId}</UserId> |
||||
<Password>{$this->password}</Password> |
||||
<InterfaceId>{$this->interfaceId}</InterfaceId> |
||||
</UIDAuthRequestMessage> |
||||
BODY; |
||||
|
||||
// Set the content type to 'application/xml'. Important, otherwise cURL will use the usual POST content type. |
||||
$headers = array( |
||||
'Content-Type: application/xml', |
||||
'Conent-Length: ' . strlen($params) |
||||
); |
||||
|
||||
$response = $this->request($url, $params, $headers, 'POST'); |
||||
return $response; |
||||
} |
||||
|
||||
/** |
||||
* Request the session token |
||||
* |
||||
* @param array $headers Authentication token |
||||
* |
||||
* @return string .The session token |
||||
* @access public |
||||
*/ |
||||
public function requestSessionToken($headers, $profile, $guest) { |
||||
$url = $this->end_point . '/CreateSession'; |
||||
|
||||
// Add the HTTP query parameters |
||||
$params = array( |
||||
'profile' => $profile, |
||||
'org' => $this->orgId, |
||||
'guest' => $guest |
||||
); |
||||
$params = http_build_query($params); |
||||
$response = $this->request($url, $params, $headers); |
||||
return $response; |
||||
} |
||||
|
||||
/** |
||||
* End the session token |
||||
* |
||||
* @param array $headers Session token |
||||
* @access public |
||||
*/ |
||||
public function requestEndSessionToken($headers, $sessionToken) { |
||||
$url = $this->end_point . '/endsession'; |
||||
|
||||
// Add the HTTP query parameters |
||||
$params = array( |
||||
'sessiontoken' => $sessionToken |
||||
); |
||||
$params = http_build_query($params); |
||||
$this->request($url, $params, $headers); |
||||
} |
||||
|
||||
public function getProfiled(){ |
||||
return $profiled; |
||||
} |
||||
|
||||
/** |
||||
* Request the search records |
||||
* |
||||
* @param array $params Search specific parameters |
||||
* @param array $headers Authentication and session tokens |
||||
* |
||||
* @return array An associative array of data |
||||
* @access public |
||||
*/ |
||||
public function requestSearch($params, $headers) { |
||||
$url = $this->end_point . '/Search'; |
||||
|
||||
$response = $this->request($url, $params, $headers); |
||||
return $response; |
||||
} |
||||
|
||||
/** |
||||
* Request a specific record |
||||
* |
||||
* @param array $params Retrieve specific parameters |
||||
* @param array $headers Authentication and session tokens |
||||
* |
||||
* @return array An associative array of data |
||||
* @access public |
||||
*/ |
||||
public function requestRetrieve($params, $headers) { |
||||
$url = $this->end_point . '/Retrieve'; |
||||
|
||||
$response = $this->request($url, $params, $headers); |
||||
return $response; |
||||
} |
||||
|
||||
/** |
||||
* Request the info data |
||||
* |
||||
* @param null $params Not used |
||||
* @param array $headers Authentication and session tokens |
||||
* |
||||
* @return array An associative array of data |
||||
* @access public |
||||
*/ |
||||
public function requestInfo($params, $headers) { |
||||
$url = $this->end_point . '/Info'; |
||||
|
||||
$response = $this->request($url, $params, $headers); |
||||
return $response; |
||||
} |
||||
|
||||
/** |
||||
* Send an HTTP request and inspect the response |
||||
* |
||||
* @param string $url The url of the HTTP request |
||||
* @param array $params The parameters of the HTTP request |
||||
* @param array $headers The headers of the HTTP request |
||||
* @param array $body The body of the HTTP request |
||||
* @param string $method The HTTP method, default is 'GET' |
||||
* |
||||
* @return object SimpleXml |
||||
* @access protected |
||||
*/ |
||||
protected function request($url, $params = null, $headers = null, $method = 'GET') { |
||||
$log = fopen('curl.log', 'w'); // for debugging cURL |
||||
$xml = false; |
||||
//$return = false; |
||||
// Create a cURL instance |
||||
$ch = curl_init(); |
||||
|
||||
// Set the cURL options |
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); |
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); |
||||
curl_setopt($ch, CURLOPT_VERBOSE, true); |
||||
curl_setopt($ch, CURLOPT_STDERR, $log); // for debugging cURL |
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Termporary |
||||
// Set the query parameters and the url |
||||
if (empty($params)) { |
||||
// Only Info request has empty parameters |
||||
curl_setopt($ch, CURLOPT_URL, $url); |
||||
} |
||||
else { |
||||
// GET method |
||||
if ($method == 'GET') { |
||||
$url .= '?' . $params; |
||||
curl_setopt($ch, CURLOPT_URL, $url); |
||||
// POST method |
||||
} |
||||
else { |
||||
curl_setopt($ch, CURLOPT_URL, $url); |
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $params); |
||||
} |
||||
} |
||||
|
||||
// Set the header |
||||
if (!empty($headers)) { |
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); |
||||
} |
||||
|
||||
// Send the request |
||||
$response = curl_exec($ch); |
||||
|
||||
//Save XML file for debug mode |
||||
if (strstr($url, 'Search')) { |
||||
$_SESSION['resultxml'] = $response; |
||||
} |
||||
if (strstr($url, 'Retrieve')) { |
||||
$_SESSION['recordxml'] = $response; |
||||
} |
||||
// Parse the response |
||||
// In case of errors, throw 2 type of exceptions |
||||
// EBSCOException if the API returned an error message |
||||
// Exception in all other cases. Should be improved for better handling |
||||
if ($response === false) { |
||||
fclose($log); // for debugging cURL |
||||
throw new Exception(curl_error($ch)); |
||||
curl_close($ch); |
||||
} |
||||
else { |
||||
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE); |
||||
fclose($log); // for debugging cURL |
||||
curl_close($ch); |
||||
switch ($code) { |
||||
case self::HTTP_OK: |
||||
$xml = simplexml_load_string($response); |
||||
if ($xml === false) { |
||||
throw new Exception('Error while parsing the response.'); |
||||
} |
||||
else { |
||||
return $xml; |
||||
} |
||||
break; |
||||
case self::HTTP_BAD_REQUEST: |
||||
$xml = @simplexml_load_string($response); |
||||
if ($xml === false) { |
||||
throw new Exception('Error while parsing the response.'); |
||||
} |
||||
else { |
||||
// If the response is an API error |
||||
$error = ''; |
||||
$code = 0; |
||||
$isError = isset($xml->ErrorNumber) || isset($xml->ErrorCode); |
||||
if ($isError) { |
||||
if (isset($xml->DetailedErrorDescription) && !empty($xml->DetailedErrorDescription)) { |
||||
$error = (string) $xml->DetailedErrorDescription; |
||||
} |
||||
else if (isset($xml->ErrorDescription)) { |
||||
$error = (string) $xml->ErrorDescription; |
||||
} |
||||
else if (isset($xml->Reason)) { |
||||
$error = (string) $xml->Reason; |
||||
} |
||||
if (isset($xml->ErrorNumber)) { |
||||
$code = (integer) $xml->ErrorNumber; |
||||
} |
||||
else if (isset($xml->ErrorCode)) { |
||||
$code = (integer) $xml->ErrorCode; |
||||
} |
||||
throw new EBSCOException($error, $code); |
||||
} |
||||
else { |
||||
throw new Exception('The request could not be understood by the server |
||||
due to malformed syntax. Modify your search before retrying.'); |
||||
} |
||||
} |
||||
break; |
||||
case self::HTTP_NOT_FOUND: |
||||
throw new Exception('The resource you are looking for might have been removed, |
||||
had its name changed, or is temporarily unavailable.'); |
||||
break; |
||||
case self::HTTP_INTERNAL_SERVER_ERROR: |
||||
throw new Exception('The server encountered an unexpected condition which prevented |
||||
it from fulfilling the request.'); |
||||
break; |
||||
// Other HTTP status codes |
||||
default: |
||||
throw new Exception('Unexpected HTTP error.'); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
?> |
@ -0,0 +1,982 @@
|
||||
<?php |
||||
|
||||
/** |
||||
* EBSCO Response class |
||||
* |
||||
* PHP version 5 |
||||
* |
||||
*/ |
||||
|
||||
|
||||
/** |
||||
* EBSCOResponse class |
||||
*/ |
||||
class EBSCOResponse |
||||
{ |
||||
|
||||
/** |
||||
* A SimpleXml object |
||||
* @global object |
||||
*/ |
||||
private $response; |
||||
|
||||
/** |
||||
* Constructor |
||||
* |
||||
* Setup the EBSCO Response |
||||
* |
||||
* @param none |
||||
* |
||||
* @access public |
||||
*/ |
||||
public function __construct($response) |
||||
{ |
||||
$this->response = $response; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* A proxy method which decides which subsequent method should be * called, based on the SimpleXml object structure |
||||
* |
||||
* @param none |
||||
* |
||||
* @return array An associative array of data or the SimpleXml object itself in case of API error messages |
||||
* @access public |
||||
*/ |
||||
public function result() |
||||
{ |
||||
// If there is an ErrorNumber tag then return the object itself. |
||||
// Should not happen, this method is called after parsing the SimpleXml for API errors |
||||
if(!empty($this->response->ErrorNumber)) { |
||||
return $this->response; |
||||
} else { |
||||
if (!empty($this->response->AuthToken)) { |
||||
return $this->buildAuthenticationToken(); |
||||
} else if (!empty($this->response->SessionToken)) { |
||||
return (string)$this->buildSessionToken(); |
||||
} else if (!empty($this->response->SearchResult)) { |
||||
return $this->buildSearch(); |
||||
} else if(!empty($this->response->Record)) { |
||||
return $this->buildRetrieve(); |
||||
} else if(!empty($this->response->AvailableSearchCriteria)) { |
||||
return $this->buildInfo(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Parse the SimpleXml object when an AuthenticationToken API call was executed |
||||
* |
||||
* @param none |
||||
* |
||||
* @return array An associative array of data |
||||
* @access private |
||||
*/ |
||||
private function buildAuthenticationToken() |
||||
{ |
||||
$token = (string) $this->response->AuthToken; |
||||
$timeout = (integer) $this->response->AuthTimeout; |
||||
|
||||
$result = array( |
||||
'authenticationToken' => $token, |
||||
'authenticationTimeout' => $timeout, |
||||
'authenticationTimeStamp'=> time() |
||||
); |
||||
return $result; |
||||
} |
||||
/** |
||||
* Parse the SimpleXml object when an SessionToken API call was executed |
||||
* |
||||
* @param none |
||||
* |
||||
* @return sessionToken |
||||
* @access private |
||||
*/ |
||||
private function buildSessionToken() |
||||
{ |
||||
$sessionToken = (string) $this->response->SessionToken; |
||||
return $sessionToken; |
||||
} |
||||
|
||||
/** |
||||
* Parse the SimpleXml object when a Search API call was executed |
||||
* |
||||
* @param none |
||||
* |
||||
* @return array An associative array of data |
||||
* @access private |
||||
*/ |
||||
private function buildSearch() |
||||
{ |
||||
$hits = (integer) $this->response->SearchResult->Statistics->TotalHits; |
||||
$queryString = (string)$this->response->SearchRequestGet->QueryString; |
||||
$records = array(); |
||||
$facets = array(); |
||||
$queries = array(); |
||||
$appliedFacets = array(); |
||||
$appliedLimiters = array(); |
||||
$appliedExpanders = array(); |
||||
|
||||
if($this->response->SearchRequestGet->SearchCriteriaWithActions->QueriesWithAction){ |
||||
$queriesWithAction = $this->response->SearchRequestGet->SearchCriteriaWithActions->QueriesWithAction->QueryWithAction; |
||||
foreach($queriesWithAction as $queryWithAction){ |
||||
$queries[]=array( |
||||
'query' => (string)$queryWithAction->Query->Term, |
||||
'removeAction'=> (string) $queryWithAction->RemoveAction |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($this->response->SearchRequestGet->SearchCriteriaWithActions->FacetFiltersWithAction){ |
||||
$facetFiltersWithAction = $this->response->SearchRequestGet->SearchCriteriaWithActions->FacetFiltersWithAction->FacetFilterWithAction; |
||||
foreach($facetFiltersWithAction as $facetFilterWithAction){ |
||||
$facetValue = array(); |
||||
foreach($facetFilterWithAction->FacetValuesWithAction->FacetValueWithAction as $facetValueWithAction){ |
||||
$facetValue[] = array( |
||||
'Id' => (string)$facetValueWithAction->FacetValue->Id, |
||||
'value'=>(string)$facetValueWithAction->FacetValue->Value, |
||||
'removeAction'=>(string)$facetValueWithAction->RemoveAction |
||||
); |
||||
} |
||||
|
||||
$appliedFacets[] = array( |
||||
'filterId' => (string)$facetFilterWithAction->FilterId, |
||||
'facetValue'=> $facetValue, |
||||
'removeAction'=> (string)$facetFilterWithAction->RemoveAction |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($this->response->SearchRequestGet->SearchCriteriaWithActions->LimitersWithAction){ |
||||
$limitersWithAction = $this->response->SearchRequestGet->SearchCriteriaWithActions->LimitersWithAction->LimiterWithAction; |
||||
foreach($limitersWithAction as $limiterWithAction){ |
||||
$limiterValue = array( |
||||
'value' => (string) $limiterWithAction->LimiterValuesWithAction->LimiterValueWithAction->Value, |
||||
'removeAction'=> (string) $limiterWithAction->LimiterValuesWithAction->LimiterValueWithAction->RemoveAction |
||||
); |
||||
$appliedLimiters[] = array( |
||||
'Id' => (string)$limiterWithAction->Id, |
||||
'limiterValue'=>$limiterValue, |
||||
'removeAction'=> (string) $limiterWithAction->RemoveAction |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($this->response->SearchRequestGet->SearchCriteriaWithActions->ExpandersWithAction){ |
||||
$expandersWithAction = $this->response->SearchRequestGet->SearchCriteriaWithActions->ExpandersWithAction->ExpanderWithAction; |
||||
foreach($expandersWithAction as $expanderWithAction){ |
||||
$appliedExpanders[] = array( |
||||
'Id' => (string)$expanderWithAction->Id, |
||||
'removeAction'=>(string)$expanderWithAction->RemoveAction |
||||
); |
||||
} |
||||
} |
||||
|
||||
if ($hits > 0) { |
||||
$records = $this->buildRecords(); |
||||
$facets = $this->buildFacets(); |
||||
} |
||||
|
||||
$results = array( |
||||
'recordCount' => $hits, |
||||
'queryString' => $queryString, |
||||
'queries' => $queries, |
||||
'appliedFacets'=>$appliedFacets, |
||||
'appliedLimiters'=>$appliedLimiters, |
||||
'appliedExpanders'=>$appliedExpanders, |
||||
'records' => $records, |
||||
'facets' => $facets |
||||
); |
||||
|
||||
return $results; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Parse the SimpleXml object when a Search API call was executed |
||||
* and find all records |
||||
* |
||||
* @param none |
||||
* |
||||
* @return array An associative array of data |
||||
* @access private |
||||
*/ |
||||
private function buildRecords() |
||||
{ |
||||
$results = array(); |
||||
|
||||
$records = $this->response->SearchResult->Data->Records->Record; |
||||
foreach ($records as $record) { |
||||
$result = array(); |
||||
$result['AccessLevel'] = $record->Header -> AccessLevel?(string)$record->Header -> AccessLevel:''; |
||||
$result['pubType'] = $record -> Header-> PubType? (string)$record -> Header-> PubType:''; |
||||
$result['PubTypeId']=$record->Header->PubTypeId? (string) $record->Header->PubTypeId:''; |
||||
$result['ResultId'] = $record->ResultId ? (integer) $record->ResultId : ''; |
||||
$result['DbId'] = $record->Header->DbId ? (string) $record->Header->DbId : ''; |
||||
$result['DbLabel'] = $record->Header->DbLabel ? (string) $record->Header->DbLabel:''; |
||||
$result['An'] = $record->Header->An ? (string) $record->Header->An : ''; |
||||
$result['PLink'] = $record->PLink ? (string) $record->PLink : ''; |
||||
$result['PDF'] = $record->FullText->Links ? (string) $record->FullText->Links->Link->Type : ''; |
||||
$result['HTML'] = $record->FullText->Text->Availability? (string) $record->FullText->Text->Availability : ''; |
||||
if (!empty($record->ImageInfo->CoverArt)) { |
||||
foreach ($record->ImageInfo->CoverArt as $image) { |
||||
$size = (string) $image->Size; |
||||
$target = (string) $image->Target; |
||||
$result['ImageInfo'][$size] = $target; |
||||
} |
||||
} else { |
||||
$result['ImageInfo'] = ''; |
||||
} |
||||
|
||||
$result['FullText'] = $record->FullText ? (string) $record->FullText : ''; |
||||
|
||||
if ($record->CustomLinks) { |
||||
$result['CustomLinks'] = array(); |
||||
foreach ($record->CustomLinks->CustomLink as $customLink) { |
||||
$category = $customLink->Category ? (string) $customLink->Category : ''; |
||||
$icon = $customLink->Icon ? (string) $customLink->Icon : ''; |
||||
$mouseOverText = $customLink->MouseOverText ? (string) $customLink->MouseOverText : ''; |
||||
$name = $customLink->Name ? (string) $customLink->Name : ''; |
||||
$text = $customLink->Text ? (string) $customLink->Text : ''; |
||||
$url = $customLink->Url ? (string) $customLink->Url : ''; |
||||
$result['CustomLinks'][] = array( |
||||
'Category' => $category, |
||||
'Icon' => $icon, |
||||
'MouseOverText' => $mouseOverText, |
||||
'Name' => $name, |
||||
'Text' => $text, |
||||
'Url' => $url |
||||
); |
||||
} |
||||
} |
||||
|
||||
if ($record->FullText->CustomLinks) { |
||||
$result['FullTextCustomLinks'] = array(); |
||||
foreach ($record->FullText->CustomLinks->CustomLink as $customLink) { |
||||
$category = $customLink->Category ? (string) $customLink->Category : ''; |
||||
$icon = $customLink->Icon ? (string) $customLink->Icon : ''; |
||||
$mouseOverText = $customLink->MouseOverText ? (string) $customLink->MouseOverText : ''; |
||||
$name = $customLink->Name ? (string) $customLink->Name : ''; |
||||
$text = $customLink->Text ? (string) $customLink->Text : ''; |
||||
$url = $customLink->Url ? (string) $customLink->Url : ''; |
||||
$result['CustomLinks'][] = array( |
||||
'Category' => $category, |
||||
'Icon' => $icon, |
||||
'MouseOverText' => $mouseOverText, |
||||
'Name' => $name, |
||||
'Text' => $text, |
||||
'Url' => $url |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($record->Items) { |
||||
$result['Items'] = array(); |
||||
foreach ($record->Items->Item as $item) { |
||||
$label = $item->Label ? (string) $item->Label : ''; |
||||
$group = $item->Group ? (string) $item->Group : ''; |
||||
$data = $item->Data ? (string) $item->Data : ''; |
||||
$result['Items'][$group][] = array( |
||||
'Label' => $label, |
||||
'Group' => $group, |
||||
'Data' => $this->toHTML($data, $group) |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($record->RecordInfo){ |
||||
$result['RecordInfo'] = array(); |
||||
$result['RecordInfo']['BibEntity']=array( |
||||
'Identifiers'=>array(), |
||||
'Languages'=>array(), |
||||
'PhysicalDescription'=>array(), |
||||
'Subjects'=>array(), |
||||
'Titles'=>array() |
||||
); |
||||
|
||||
if($record->RecordInfo->BibRecord->BibEntity->Identifiers){ |
||||
foreach($record->RecordInfo->BibRecord->BibEntity->Identifiers->Identifier as $identifier){ |
||||
$type = $identifier->Type? (string) $identifier->Type:''; |
||||
$value = $identifier->Value? (string) $identifier->Value:''; |
||||
$result['RecordInfo']['BibEntity']['Identifiers'][]= array( |
||||
'Type'=>$type, |
||||
'Value'=>$value |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($record->RecordInfo->BibRecord->BibEntity->Languages){ |
||||
foreach($record->RecordInfo->BibRecord->BibEntity->Languages->Language as $language){ |
||||
$code = $language->Code? (string)$language->Code:''; |
||||
$text = $language->Text? (string)$language->Text:''; |
||||
$result['RecordInfo']['BibEntity']['Languages'][]= array( |
||||
'Code'=>$code, |
||||
'Text'=>$text |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($record->RecordInfo->BibRecord->BibEntity->PhysicalDescription){ |
||||
$pageCount = $record->RecordInfo->BibRecord->BibEntity->PhysicalDescription->Pagination->PageCount? (string) $record->RecordInfo->BibRecord->BibEntity->PhysicalDescription->Pagination->PageCount:''; |
||||
$startPage = $record->RecordInfo->BibRecord->BibEntity->PhysicalDescription->Pagination->StartPage? (string) $record->RecordInfo->BibRecord->BibEntity->PhysicalDescription->Pagination->StartPage:''; |
||||
$result['RecordInfo']['BibEntity']['PhysicalDescription']['Pagination'] = $pageCount; |
||||
$result['RecordInfo']['BibEntity']['PhysicalDescription']['StartPage'] = $startPage; |
||||
} |
||||
|
||||
if($record->RecordInfo->BibRecord->BibEntity->Subjects){ |
||||
foreach($record->RecordInfo->BibRecord->BibEntity->Subjects->Subject as $subject){ |
||||
$subjectFull = $subject->SubjectFull? (string)$subject->SubjectFull:''; |
||||
$type = $subject->Type? (string)$subject->Type:''; |
||||
$result['RecordInfo']['BibEntity']['Subjects'][]=array( |
||||
'SubjectFull'=>$subjectFull, |
||||
'Type'=>$type |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($record->RecordInfo->BibRecord->BibEntity->Titles){ |
||||
foreach($record->RecordInfo->BibRecord->BibEntity->Titles->Title as $title){ |
||||
$titleFull = $title->TitleFull? (string)$title->TitleFull:''; |
||||
$type = $title->Type? (string)$title->Type:''; |
||||
$result['RecordInfo']['BibEntity']['Titles'][]=array( |
||||
'TitleFull'=>$titleFull, |
||||
'Type'=>$type |
||||
); |
||||
} |
||||
} |
||||
|
||||
$result['RecordInfo']['BibRelationships']=array( |
||||
'HasContributorRelationships'=>array(), |
||||
'IsPartOfRelationships'=>array() |
||||
); |
||||
|
||||
if($record->RecordInfo->BibRecord->BibRelationships->HasContributorRelationships){ |
||||
foreach($record->RecordInfo->BibRecord->BibRelationships->HasContributorRelationships->HasContributor as $contributor){ |
||||
$nameFull = $contributor->PersonEntity->Name->NameFull? (string)$contributor->PersonEntity->Name->NameFull:''; |
||||
$result['RecordInfo']['BibRelationships']['HasContributorRelationships'][]=array( |
||||
'NameFull'=>$nameFull |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($record->RecordInfo->BibRecord->BibRelationships){ |
||||
foreach($record->RecordInfo->BibRecord->BibRelationships->IsPartOfRelationships->IsPartOf as $relationship){ |
||||
if($relationship->BibEntity->Dates){ |
||||
foreach($relationship->BibEntity->Dates->Date as $date){ |
||||
$d = $date->D? (string)$date->D:''; |
||||
$m = $date->M? (string)$date->M:''; |
||||
$type = $date->Type? (string)$date->Type:''; |
||||
$y = $date->Y? (string)$date->Y:''; |
||||
$result['RecordInfo']['BibRelationships']['IsPartOfRelationships']['date'][] = array( |
||||
'D'=> $d, |
||||
'M'=>$m, |
||||
'Type'=>$type, |
||||
'Y'=>$y |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($relationship->BibEntity->Identifiers){ |
||||
foreach($relationship->BibEntity->Identifiers->Identifier as $identifier){ |
||||
$type = $identifier->Type? (string) $identifier->Type :''; |
||||
$value = $identifier->Value? (string) $identifier->Value:''; |
||||
$result['RecordInfo']['BibRelationships']['IsPartOfRelationships']['Identifiers'][]=array( |
||||
'Type'=>$type, |
||||
'Value'=>$value |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($relationship->BibEntity->Titles){ |
||||
foreach($relationship->BibEntity->Titles->Title as $title){ |
||||
$titleFull = $title->TitleFull? (string)$title->TitleFull:''; |
||||
$type = $title->Type? (string)$title->Type:''; |
||||
$result['RecordInfo']['BibRelationships']['IsPartOfRelationships']['Titles'][]=array( |
||||
'TitleFull' => $titleFull, |
||||
'Type'=>$type |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($relationship->BibEntity->Numbering){ |
||||
foreach($relationship->BibEntity->Numbering->Number as $number){ |
||||
$type = (string)$number->Type; |
||||
$value= (string)$number->Value; |
||||
$result['RecordInfo']['BibRelationships']['IsPartOfRelationships']['numbering'][] = array( |
||||
'Type'=> $type, |
||||
'Value'=>$value |
||||
); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
$results[] = $result; |
||||
} |
||||
|
||||
return $results; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Parse the SimpleXml object when a Search API call was executed |
||||
* and find all facets |
||||
* |
||||
* @param none |
||||
* |
||||
* @return array An associative array of data |
||||
* @access private |
||||
*/ |
||||
private function buildFacets() |
||||
{ |
||||
$results = array(); |
||||
|
||||
if($this->response->SearchResult->AvailableFacets){ |
||||
$facets = $this->response->SearchResult->AvailableFacets->AvailableFacet; |
||||
foreach ($facets as $facet) { |
||||
$values = array(); |
||||
foreach ($facet->AvailableFacetValues->AvailableFacetValue as $value) { |
||||
|
||||
$values[] = array( |
||||
'Value' => (string) $value->Value, |
||||
'Action' => (string) $value->AddAction, |
||||
'Count' => (string) $value->Count |
||||
); |
||||
} |
||||
$id = (string) $facet->Id; |
||||
$label = (string) $facet->Label; |
||||
$results[] = array( |
||||
'Id' => $id, |
||||
'Label' => $label, |
||||
'Values' => $values |
||||
); |
||||
} |
||||
} |
||||
|
||||
return $results; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Parse the SimpleXml object when an Info API call was executed |
||||
* |
||||
* @param none |
||||
* |
||||
* @return array An associative array of data |
||||
* @access private |
||||
*/ |
||||
private function buildInfo() |
||||
{ |
||||
// Sort options |
||||
$sort = array(); |
||||
foreach ($this->response->AvailableSearchCriteria->AvailableSorts->AvailableSort as $element) { |
||||
$sort[] = array( |
||||
'Id' => (string) $element->Id, |
||||
'Label' => (string) $element->Label, |
||||
'Action' => (string) $element->AddAction |
||||
); |
||||
} |
||||
|
||||
// Search fields |
||||
$search = array(); |
||||
foreach ($this->response->AvailableSearchCriteria->AvailableSearchFields->AvailableSearchField as $element) { |
||||
$search[] = array( |
||||
'Label' => (string) $element->Label, |
||||
'Code' => (string) $element->FieldCode |
||||
); |
||||
} |
||||
|
||||
// Expanders |
||||
$expanders = array(); |
||||
foreach ($this->response->AvailableSearchCriteria->AvailableExpanders->AvailableExpander as $element) { |
||||
$expanders[] = array( |
||||
'Id' => (string) $element->Id, |
||||
'Label' => (string) $element->Label, |
||||
'Action' => (string) $element->AddAction |
||||
); |
||||
} |
||||
|
||||
// Limiters |
||||
$limiters = array(); |
||||
foreach ($this->response->AvailableSearchCriteria->AvailableLimiters->AvailableLimiter as $element) { |
||||
$values = array(); |
||||
if ($element->LimiterValues) { |
||||
$items = $element->LimiterValues->LimiterValue; |
||||
foreach($items as $item) { |
||||
$values[] = array( |
||||
'Value' => (string) $item->Value, |
||||
'Action' => (string) $item->AddAction |
||||
); |
||||
} |
||||
} |
||||
$limiters[] = array( |
||||
'Id' => (string) $element->Id, |
||||
'Label' => (string) $element->Label, |
||||
'Action' => (string) $element->AddAction, |
||||
'Type' => (string) $element->Type, |
||||
'values' => $values |
||||
); |
||||
} |
||||
|
||||
$result = array( |
||||
'sort' => $sort, |
||||
'search' => $search, |
||||
'expanders' => $expanders, |
||||
'limiters' => $limiters |
||||
); |
||||
|
||||
return $result; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Parse a SimpleXml object when a Retrieve API call was executed |
||||
* |
||||
* @param none |
||||
* |
||||
* @return array An associative array of data |
||||
* @access private |
||||
*/ |
||||
private function buildRetrieve() |
||||
{ |
||||
$record = $this->response->Record; |
||||
|
||||
if ($record) { |
||||
$record = $record[0]; // there is only one record |
||||
} |
||||
|
||||
$result = array(); |
||||
$result['AccessLevel'] = $record->Header -> AccessLevel?(string)$record->Header -> AccessLevel:''; |
||||
$result['pubType'] = $record -> Header-> PubType? (string)$record -> Header-> PubType:''; |
||||
$result['PubTypeId']=$record->Header->PubTypeId? (string) $record->Header->PubTypeId:''; |
||||
$result['DbId'] = $record->Header->DbId ? (string) $record->Header->DbId : ''; |
||||
$result['DbLabel'] = $record->Header->DbLabel ? (string) $record->Header->DbLabel:''; |
||||
$result['An'] = $record->Header->An ? (string) $record->Header->An : ''; |
||||
$result['PLink'] = $record->PLink ? (string) $record->PLink : ''; |
||||
$result['pdflink'] = $record->FullText->Links ? (string) $record->FullText->Links->Link->Url : ''; |
||||
$result['PDF'] = $record->FullText->Links ? (string) $record->FullText->Links->Link->Type : ''; |
||||
$value = $record->FullText->Text->Value ? (string) $record->FullText->Text->Value : ''; |
||||
$result['htmllink'] = $this->toHTML($value,$group = ''); |
||||
$result['HTML'] = $record->FullText->Text->Availability? (string) $record->FullText->Text->Availability : ''; |
||||
if (!empty($record->ImageInfo->CoverArt)) { |
||||
foreach ($record->ImageInfo->CoverArt as $image) { |
||||
$size = (string) $image->Size; |
||||
$target = (string) $image->Target; |
||||
$result['ImageInfo'][$size] = $target; |
||||
} |
||||
} else { |
||||
$result['ImageInfo'] = ''; |
||||
} |
||||
$result['FullText'] = $record->FullText ? (string) $record->FullText : ''; |
||||
|
||||
if ($record->CustomLinks) { |
||||
$result['CustomLinks'] = array(); |
||||
foreach ($record->CustomLinks->CustomLink as $customLink) { |
||||
$category = $customLink->Category ? (string) $customLink->Category : ''; |
||||
$icon = $customLink->Icon ? (string) $customLink->Icon : ''; |
||||
$mouseOverText = $customLink->MouseOverText ? (string) $customLink->MouseOverText : ''; |
||||
$name = $customLink->Name ? (string) $customLink->Name : ''; |
||||
$text = $customLink->Text ? (string) $customLink->Text : ''; |
||||
$url = $customLink->Url ? (string) $customLink->Url : ''; |
||||
$result['CustomLinks'][] = array( |
||||
'Category' => $category, |
||||
'Icon' => $icon, |
||||
'MouseOverText' => $mouseOverText, |
||||
'Name' => $name, |
||||
'Text' => $text, |
||||
'Url' => $url |
||||
); |
||||
} |
||||
} |
||||
|
||||
if ($record->FullText->CustomLinks) { |
||||
$result['FullTextCustomLinks'] = array(); |
||||
foreach ($record->FullText->CustomLinks->CustomLink as $customLink) { |
||||
$category = $customLink->Category ? (string) $customLink->Category : ''; |
||||
$icon = $customLink->Icon ? (string) $customLink->Icon : ''; |
||||
$mouseOverText = $customLink->MouseOverText ? (string) $customLink->MouseOverText : ''; |
||||
$name = $customLink->Name ? (string) $customLink->Name : ''; |
||||
$text = $customLink->Text ? (string) $customLink->Text : ''; |
||||
$url = $customLink->Url ? (string) $customLink->Url : ''; |
||||
$result['CustomLinks'][] = array( |
||||
'Category' => $category, |
||||
'Icon' => $icon, |
||||
'MouseOverText' => $mouseOverText, |
||||
'Name' => $name, |
||||
'Text' => $text, |
||||
'Url' => $url |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($record->Items) { |
||||
$result['Items'] = array(); |
||||
foreach ($record->Items->Item as $item) { |
||||
$label = $item->Label ? (string) $item->Label : ''; |
||||
$group = $item->Group ? (string) $item->Group : ''; |
||||
$data = $item->Data ? (string) $item->Data : ''; |
||||
$result['Items'][] = array( |
||||
'Label' => $label, |
||||
'Group' => $group, |
||||
'Data' => $this->retrieveHTML($data, $group) |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($record->RecordInfo){ |
||||
$result['RecordInfo'] = array(); |
||||
$result['RecordInfo']['BibEntity']=array( |
||||
'Identifiers'=>array(), |
||||
'Languages'=>array(), |
||||
'PhysicalDescription'=>array(), |
||||
'Subjects'=>array(), |
||||
'Titles'=>array() |
||||
); |
||||
|
||||
if($record->RecordInfo->BibRecord->BibEntity->Identifiers){ |
||||
foreach($record->RecordInfo->BibRecord->BibEntity->Identifiers->Identfier as $identifier){ |
||||
$type = $identifier->Type? (string) $identifier->Type:''; |
||||
$value = $identifier->Value? (string) $identifier->Value:''; |
||||
$result['RecordInfo']['BibEntity']['Identifiers'][]= array( |
||||
'Type'=>$type, |
||||
'Value'=>$value |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($record->RecordInfo->BibRecord->BibEntity->Languages){ |
||||
foreach($record->RecordInfo->BibRecord->BibEntity->Languages->Language as $language){ |
||||
$code = $language->Code? (string)$language->Code:''; |
||||
$text = $language->Text? (string)$language->Text:''; |
||||
$result['RecordInfo']['BibEntity']['Languages'][]= array( |
||||
'Code'=>$code, |
||||
'Text'=>$text |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($record->RecordInfo->BibRecord->BibEntity->PhysicalDescription){ |
||||
$pageCount = $record->RecordInfo->BibRecord->BibEntity->PhysicalDescription->Pagination->PageCount? (string) $record->RecordInfo->BibRecord->BibEntity->PhysicalDescription->Pagination->PageCount:''; |
||||
$startPage = $record->RecordInfo->BibRecord->BibEntity->PhysicalDescription->Pagination->StartPage? (string) $record->RecordInfo->BibRecord->BibEntity->PhysicalDescription->Pagination->StartPage:''; |
||||
$result['RecordInfo']['BibEntity']['PhysicalDescription']['Pagination'] = $pageCount; |
||||
$result['RecordInfo']['BibEntity']['PhysicalDescription']['StartPage'] = $startPage; |
||||
} |
||||
|
||||
if($record->RecordInfo->BibRecord->BibEntity->Subjects){ |
||||
foreach($record->RecordInfo->BibRecord->BibEntity->Subjects->Subject as $subject){ |
||||
$subjectFull = $subject->SubjectFull? (string)$subject->SubjectFull:''; |
||||
$type = $subject->Type? (string)$subject->Type:''; |
||||
$result['RecordInfo']['BibEntity']['Subjects'][]=array( |
||||
'SubjectFull'=>$subjectFull, |
||||
'Type'=>$type |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($record->RecordInfo->BibRecord->BibEntity->Titles){ |
||||
foreach($record->RecordInfo->BibRecord->BibEntity->Titles->Title as $title){ |
||||
$titleFull = $title->TitleFull? (string)$title->TitleFull:''; |
||||
$type = $title->Type? (string)$title->Type:''; |
||||
$result['RecordInfo']['BibEntity']['Titles'][]=array( |
||||
'TitleFull'=>$titleFull, |
||||
'Type'=>$type |
||||
); |
||||
} |
||||
} |
||||
|
||||
$result['RecordInfo']['BibRelationships']=array( |
||||
'HasContributorRelationships'=>array(), |
||||
'IsPartOfRelationships'=>array() |
||||
); |
||||
|
||||
if($record->RecordInfo->BibRecord->BibRelationships->HasContributorRelationships){ |
||||
foreach($record->RecordInfo->BibRecord->BibRelationships->HasContributorRelationships->HasContributor as $contributor){ |
||||
$nameFull = $contributor->PersonEntity->Name->NameFull? (string)$contributor->PersonEntity->Name->NameFull:''; |
||||
$result['RecordInfo']['BibRelationships']['HasContributorRelationships'][]=array( |
||||
'NameFull'=>$nameFull |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($record->RecordInfo->BibRecord->BibRelationships){ |
||||
foreach($record->RecordInfo->BibRecord->BibRelationships->IsPartOfRelationships->IsPartOf as $relationship){ |
||||
if($relationship->BibEntity->Dates){ |
||||
foreach($relationship->BibEntity->Dates->Date as $date){ |
||||
$d = $date->D? (string)$date->D:''; |
||||
$m = $date->M? (string)$date->M:''; |
||||
$type = $date->Type? (string)$date->Type:''; |
||||
$y = $date->Y? (string)$date->Y:''; |
||||
$result['RecordInfo']['BibRelationships']['IsPartOfRelationships']['date'][] = array( |
||||
'D'=> $d, |
||||
'M'=>$m, |
||||
'Type'=>$type, |
||||
'Y'=>$y |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($relationship->BibEntity->Identifiers){ |
||||
foreach($relationship->BibEntity->Identifiers->Identfier as $identifier){ |
||||
$type = $identifier->Type? (string) $identifier->Type :''; |
||||
$value = $identifier->Value? (string) $identifier->Value:''; |
||||
$result['RecordInfo']['BibRelationships']['IsPartOfRelationships']['Identifiers'][]=array( |
||||
'Type'=>$type, |
||||
'Value'=>$value |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($relationship->BibEntity->Numbering){ |
||||
foreach($relationship->BibEntity->Numbering->Number as $number){ |
||||
$type = (string)$number->Type; |
||||
$value= (string)$number->Value; |
||||
$result['RecordInfo']['BibRelationships']['IsPartOfRelationships']['numbering'][] = array( |
||||
'Type'=> $type, |
||||
'Value'=>$value |
||||
); |
||||
} |
||||
} |
||||
|
||||
if($relationship->BibEntity->Titles){ |
||||
foreach($relationship->BibEntity->Titles->Title as $title){ |
||||
$titleFull = $title->TitleFull? (string)$title->TitleFull:''; |
||||
$type = $title->Type? (string)$title->Type:''; |
||||
$result['RecordInfo']['BibRelationships']['IsPartOfRelationships']['Titles'][]=array( |
||||
'TitleFull' => $titleFull, |
||||
'Type'=>$type |
||||
); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
return $result; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Parse the "inner XML" of a SimpleXml element and |
||||
* return it as an HTML string |
||||
* |
||||
* @param SimpleXml $element A SimpleXml DOM |
||||
* |
||||
* @return string The HTML string |
||||
* @access protected |
||||
*/ |
||||
private function retrieveHTML($data, $group = '') |
||||
{ |
||||
//global $path; |
||||
// Any group can be added here, but we only use Au (Author) |
||||
// Other groups, not present here, won't be transformed to HTML links |
||||
$allowed_searchlink_groups = array('Au','Su'); |
||||
$allowed_link_groups = array('URL'); |
||||
// Map xml tags to the HTML tags |
||||
// This is just a small list, the total number of xml tags is far more greater |
||||
$xml_to_html_tags = array( |
||||
'<jsection' => '<section', |
||||
'</jsection' => '</section', |
||||
'<highlight' => '<span class="highlight"', |
||||
'<highligh' => '<span class="highlight"', // Temporary bug fix |
||||
'</highlight>' => '</span>', // Temporary bug fix |
||||
'</highligh' => '</span>', |
||||
'<text' => '<div', |
||||
'</text' => '</div', |
||||
'<title' => '<h2', |
||||
'</title' => '</h2', |
||||
'<anid' => '<p', |
||||
'</anid' => '</p', |
||||
'<aug' => '<strong', |
||||
'</aug' => '</strong', |
||||
'<hd' => '<h3', |
||||
'</hd' => '</h3', |
||||
'<linebr' => '<br', |
||||
'</linebr' => '', |
||||
'<olist' => '<ol', |
||||
'</olist' => '</ol', |
||||
'<reflink' => '<a', |
||||
'</reflink' => '</a', |
||||
'<blist' => '<p class="blist"', |
||||
'</blist' => '</p', |
||||
'<bibl' => '<a', |
||||
'</bibl' => '</a', |
||||
'<bibtext' => '<span', |
||||
'</bibtext' => '</span', |
||||
'<ref' => '<div class="ref"', |
||||
'</ref' => '</div', |
||||
'<ulink' => '<a', |
||||
'</ulink' => '</a', |
||||
'<superscript' => '<sup', |
||||
'</superscript'=> '</sup', |
||||
'<relatesTo' => '<sup', |
||||
'</relatesTo' => '</sup', |
||||
// A very basic security implementation, using a blackist instead of a whitelist as needed. |
||||
// But the total number of xml tags is so large that we won't build a whitelist right now |
||||
'<script' => '', |
||||
'</script' => '' |
||||
); |
||||
|
||||
// Map xml types to Search types used by the UI |
||||
$xml_to_search_types = array( |
||||
'Au' => 'Author', |
||||
'Su' => 'Subject' |
||||
); |
||||
|
||||
// The XML data is XML escaped, let's unescape html entities (e.g. < => <) |
||||
$data = html_entity_decode($data); |
||||
|
||||
// Start parsing the xml data |
||||
if (!empty($data)) { |
||||
// Replace the XML tags with HTML tags |
||||
$search = array_keys($xml_to_html_tags); |
||||
$replace = array_values($xml_to_html_tags); |
||||
$data = str_replace($search, $replace, $data); |
||||
|
||||
// Temporary : fix unclosed tags |
||||
$data = preg_replace('/<\/highlight/', '</span>', $data); |
||||
$data = preg_replace('/<\/span>>/', '</span>', $data); |
||||
$data = preg_replace('/<\/searchLink/', '</searchLink>', $data); |
||||
$data = preg_replace('/<\/searchLink>>/', '</searchLink>', $data); |
||||
|
||||
// Parse searchLinks |
||||
if (!empty($group) && in_array($group, $allowed_searchlink_groups)) { |
||||
$type = $xml_to_search_types[$group]; |
||||
$link_xml = '/<searchLink fieldCode="([^"]*)" term="([^"]*)">/'; |
||||
$link_html = "<a href=\"results.php?query=$2&fieldcode=$1\">"; //replaced $path with "result.php" |
||||
$data = preg_replace($link_xml, $link_html, $data); |
||||
$data = str_replace('</searchLink>', '</a>', $data); |
||||
$data = str_replace('*','',$data); |
||||
} |
||||
// Parse link |
||||
if (!empty($group) && in_array($group, $allowed_link_groups)) { |
||||
$link_xml = '/<link linkTarget="([^"]*)" linkTerm="([^"]*)" linkWindow="([^"]*)">/'; |
||||
$link_html = "<a name=\"$1\" href=\"$2\" target=\"$3\">"; //replaced $path with "result.php" |
||||
$data = preg_replace($link_xml, $link_html, $data); |
||||
$data = str_replace('</link>', '</a>', $data); |
||||
} |
||||
// Replace the rest of searchLinks with simple spans |
||||
$link_xml = '/<searchLink fieldCode="([^\"]*)" term="%22([^\"]*)%22">/'; |
||||
$link_html = '<span>'; |
||||
$data = preg_replace($link_xml, $link_html, $data); |
||||
$data = str_replace('</searchLink>', '</span>', $data); |
||||
// Parse bibliography (anchors and links) |
||||
$data = preg_replace('/<a idref="([^\"]*)"/', '<a href="#$1"', $data); |
||||
$data = preg_replace('/<a id="([^\"]*)" idref="([^\"]*)" type="([^\"]*)"/', '<a id="$1" href="#$2"', $data); |
||||
} |
||||
|
||||
return $data; |
||||
} |
||||
|
||||
|
||||
private function toHTML($data, $group = '') |
||||
{ |
||||
global $path; |
||||
// Any group can be added here, but we only use Au (Author) |
||||
// Other groups, not present here, won't be transformed to HTML links |
||||
$allowed_searchlink_groups = array('Au','Su'); |
||||
$allowed_link_groups = array('URL'); |
||||
// Map xml tags to the HTML tags |
||||
// This is just a small list, the total number of xml tags is far more greater |
||||
$xml_to_html_tags = array( |
||||
'<jsection' => '<section', |
||||
'</jsection' => '</section', |
||||
'<highlight' => '<span class="highlight"', |
||||
'<highligh' => '<span class="highlight"', // Temporary bug fix |
||||
'</highlight>' => '</span>', // Temporary bug fix |
||||
'</highligh' => '</span>', |
||||
'<text' => '<div', |
||||
'</text' => '</div', |
||||
'<title' => '<h2', |
||||
'</title' => '</h2', |
||||
'<anid' => '<p', |
||||
'</anid' => '</p', |
||||
'<aug' => '<strong', |
||||
'</aug' => '</strong', |
||||
'<hd' => '<h3', |
||||
'</hd' => '</h3', |
||||
'<linebr' => '<br', |
||||
'</linebr' => '', |
||||
'<olist' => '<ol', |
||||
'</olist' => '</ol', |
||||
'<reflink' => '<a', |
||||
'</reflink' => '</a', |
||||
'<blist' => '<p class="blist"', |
||||
'</blist' => '</p', |
||||
'<bibl' => '<a', |
||||
'</bibl' => '</a', |
||||
'<bibtext' => '<span', |
||||
'</bibtext' => '</span', |
||||
'<ref' => '<div class="ref"', |
||||
'</ref' => '</div', |
||||
'<ulink' => '<a', |
||||
'</ulink' => '</a', |
||||
'<superscript' => '<sup', |
||||
'</superscript'=> '</sup', |
||||
'<relatesTo' => '<sup', |
||||
'</relatesTo' => '</sup', |
||||
// A very basic security implementation, using a blackist instead of a whitelist as needed. |
||||
// But the total number of xml tags is so large that we won't build a whitelist right now |
||||
'<script' => '', |
||||
'</script' => '', |
||||
'<i>' => '', |
||||
'</i>' => '' |
||||
); |
||||
|
||||
// Map xml types to Search types used by the UI |
||||
$xml_to_search_types = array( |
||||
'Au' => 'Author', |
||||
'Su' => 'Subject' |
||||
); |
||||
|
||||
// The XML data is XML escaped, let's unescape html entities (e.g. < => <) |
||||
$data = html_entity_decode($data); |
||||
|
||||
// Start parsing the xml data |
||||
if (!empty($data)) { |
||||
// Replace the XML tags with HTML tags |
||||
$search = array_keys($xml_to_html_tags); |
||||
$replace = array_values($xml_to_html_tags); |
||||
$data = str_replace($search, $replace, $data); |
||||
|
||||
// Temporary : fix unclosed tags |
||||
$data = preg_replace('/<\/highlight/', '</span>', $data); |
||||
$data = preg_replace('/<\/span>>/', '</span>', $data); |
||||
$data = preg_replace('/<\/searchLink/', '</searchLink>', $data); |
||||
$data = preg_replace('/<\/searchLink>>/', '</searchLink>', $data); |
||||
|
||||
// Parse searchLinks |
||||
if (!empty($group) && in_array($group, $allowed_searchlink_groups)) { |
||||
$type = $xml_to_search_types[$group]; |
||||
$link_xml = '/<searchLink fieldCode="([^"]*)" term="([^"]*)">/'; |
||||
$link_html = "<a href=\"results.php?query=$2&fieldcode=$1\">"; //replaced $path with "result.php" |
||||
$data = preg_replace($link_xml, $link_html, $data); |
||||
$data = str_replace('</searchLink>', '</a>', $data); |
||||
$data = str_replace('<br />', '; ', $data); |
||||
$data = str_replace('*','',$data); |
||||
} |
||||
// Parse link |
||||
if (!empty($group) && in_array($group, $allowed_link_groups)) { |
||||
$link_xml = '/<link linkTarget="([^"]*)" linkTerm="([^"]*)" linkWindow="([^"]*)">/'; |
||||
$link_html = "<a name=\"$1\" href=\"$2\" target=\"$3\">"; //replaced $path with "result.php" |
||||
$data = preg_replace($link_xml, $link_html, $data); |
||||
$data = str_replace('</link>', '</a>', $data); |
||||
} |
||||
// Replace the rest of searchLinks with simple spans |
||||
$link_xml = '/<searchLink fieldCode="([^\"]*)" term="%22([^\"]*)%22">/'; |
||||
$link_html = '<span>'; |
||||
$data = preg_replace($link_xml, $link_html, $data); |
||||
$data = str_replace('</searchLink>', '</span>', $data); |
||||
// Parse bibliography (anchors and links) |
||||
$data = preg_replace('/<a idref="([^\"]*)"/', '<a href="#$1"', $data); |
||||
$data = preg_replace('/<a id="([^\"]*)" idref="([^\"]*)" type="([^\"]*)"/', '<a id="$1" href="#$2"', $data); |
||||
} |
||||
|
||||
return $data; |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
?> |
Loading…
Reference in new issue