Rui Francisco
11 years ago
18 changed files with 5396 additions and 0 deletions
Binary file not shown.
@ -0,0 +1,431 @@
|
||||
/* |
||||
* The styles for EBSCO module |
||||
*/ |
||||
@CHARSET "UTF-8"; |
||||
|
||||
/** General ***/ |
||||
|
||||
.floatleft { |
||||
float: left; |
||||
} |
||||
|
||||
.floatright { |
||||
float: right; |
||||
} |
||||
|
||||
.clear { |
||||
clear: both; |
||||
} |
||||
|
||||
.offscreen { |
||||
display: none; |
||||
} |
||||
|
||||
.spinner { |
||||
width: 16px; |
||||
height: 16px; |
||||
background: url("../images/ajax_loading.gif") no-repeat left top; |
||||
display: none; |
||||
} |
||||
|
||||
.highlight { |
||||
font-weight: bold; |
||||
} |
||||
|
||||
|
||||
/** Search list ***/ |
||||
|
||||
.ebsco .result { |
||||
width: 650px; |
||||
} |
||||
|
||||
.ebsco .record-number { |
||||
margin-right: 10px; |
||||
min-width: 10px; |
||||
} |
||||
|
||||
.ebsco .span-2 { |
||||
width: auto; |
||||
max-width: 70px; |
||||
margin-right: 10px; |
||||
float: left; |
||||
} |
||||
|
||||
.ebsco .span-9 { |
||||
float: none; |
||||
overflow: auto; |
||||
width: auto; |
||||
margin-right: 0; |
||||
} |
||||
|
||||
.ebsco .pagination { |
||||
margin-bottom: 0; |
||||
padding: 0.2em |
||||
} |
||||
|
||||
.ebsco p.submit { |
||||
padding: 10px 0; |
||||
} |
||||
|
||||
.ebsco .jumpMenu { |
||||
max-width: 130px; |
||||
} |
||||
|
||||
.ebsco ul.custom-links { |
||||
list-style-type: none; |
||||
margin: 0; |
||||
padding: 0; |
||||
} |
||||
|
||||
.ebsco ul.custom-links li { |
||||
display: inline-block; |
||||
padding-left: 0; |
||||
padding-right: 10px; |
||||
margin-left: 10px; |
||||
border-right: 1px solid #CCCCCC; |
||||
} |
||||
|
||||
.ebsco ul.custom-links li:first-child { |
||||
margin-left: 0; |
||||
} |
||||
|
||||
.ebsco ul.custom-links li:last-child { |
||||
padding-right: 0; |
||||
border-right: 0 none; |
||||
} |
||||
|
||||
|
||||
|
||||
/** Side facets **/ |
||||
|
||||
#block-ebsco-ebsco-facets h2 { |
||||
font-weight: bold; |
||||
} |
||||
|
||||
#block-ebsco-ebsco-facets { |
||||
padding: 5px !important; |
||||
} |
||||
|
||||
#block-ebsco-ebsco-facets dl { |
||||
margin: 5px 0; |
||||
padding: 0; |
||||
} |
||||
|
||||
#block-ebsco-ebsco-facets dl dt { |
||||
font-size: 115%; |
||||
padding: 5px; |
||||
background-color: #eeeeee; |
||||
} |
||||
|
||||
#block-ebsco-ebsco-facets dd { |
||||
font-weight: normal !important; |
||||
margin: 0; |
||||
padding: 5px !important; |
||||
border-bottom: 1px solid #dddddd; |
||||
} |
||||
|
||||
#block-ebsco-ebsco-facets dd.submit input { |
||||
margin: 0; |
||||
} |
||||
|
||||
#block-ebsco-ebsco-facets dl dd:last-child { |
||||
border-bottom: none; |
||||
} |
||||
|
||||
#block-ebsco-ebsco-facets dd label { |
||||
font-weight: normal; |
||||
font-family: Arial; |
||||
padding: 0 3px; |
||||
} |
||||
|
||||
#block-ebsco-ebsco-facets dd label { |
||||
display: inline; |
||||
} |
||||
|
||||
#block-ebsco-ebsco-facets dl.expandable:hover { |
||||
cursor: pointer; |
||||
} |
||||
|
||||
#block-ebsco-ebsco-facets dl.expandable:hover dt span { |
||||
color: #444444; |
||||
} |
||||
|
||||
#block-ebsco-ebsco-facets .narrow-list.filters { |
||||
background-color: orange; |
||||
} |
||||
|
||||
#block-ebsco-ebsco-facets .narrow-list.filters a { |
||||
color: white; |
||||
} |
||||
|
||||
|
||||
|
||||
/** Detailed view ***/ |
||||
|
||||
.ebsco-record .toolbar { |
||||
border-bottom: 1px solid #EEEEEE; |
||||
margin-bottom: 1em; |
||||
min-height: 2em; |
||||
padding-left: 1em; |
||||
} |
||||
|
||||
.ebsco-record.push-5 { |
||||
margin: 0; |
||||
} |
||||
|
||||
.ebsco-record .span-13 { |
||||
min-width: 540px; |
||||
max-width: 690px; |
||||
width: auto; |
||||
float: left; |
||||
} |
||||
|
||||
.ebsco-record .span-13 table { |
||||
margin-top: 0; |
||||
} |
||||
|
||||
.ebsco-record .span-13 table tr td { |
||||
word-break: break-all; |
||||
} |
||||
|
||||
.ebsco-record .span-4 { |
||||
max-width: 150px; |
||||
min-width: 80px; |
||||
width: auto; |
||||
margin: 0 0 0 10px; |
||||
text-align: center; |
||||
float: left; |
||||
} |
||||
|
||||
.ebsco-record .external-links { |
||||
border: 1px solid #eeeeee; |
||||
list-style-type: none; |
||||
margin: 10px 0; |
||||
padding: 0; |
||||
} |
||||
|
||||
.ebsco-record .external-links li { |
||||
display: inline-block; |
||||
padding-left: 0; |
||||
padding-right: 10px; |
||||
margin-left: 10px; |
||||
border-right: 1px solid #CCCCCC; |
||||
line-height: 32px; |
||||
margin: 5px; |
||||
} |
||||
|
||||
.ebsco-record .external-links li:last-child { |
||||
border-right: 0 none; |
||||
} |
||||
|
||||
.external-link img { |
||||
vertical-align: middle; |
||||
padding-right: 5px; |
||||
} |
||||
|
||||
.top-login-message { |
||||
margin-top:10px; |
||||
width: 100%; |
||||
text-align: center; |
||||
} |
||||
|
||||
.ebsco-record .record { |
||||
width: 100%; |
||||
padding: 0; |
||||
} |
||||
|
||||
.ebsco-record .book-jacket { |
||||
max-width: 150px; |
||||
} |
||||
|
||||
.ebsco-record .html { |
||||
background-color: white; |
||||
padding:10px 0; |
||||
border: 0; |
||||
} |
||||
|
||||
|
||||
/** Basic search form ***/ |
||||
|
||||
#ebsco-basic-search-form .form-item-lookfor, |
||||
#ebsco-basic-search-form .form-item-type { |
||||
display: inline !important; |
||||
} |
||||
|
||||
#ebsco-basic-search-form #edit-links { |
||||
display: inline; |
||||
margin: 0; |
||||
padding: 0; |
||||
border: none 0; |
||||
position: static; |
||||
} |
||||
|
||||
#ebsco-basic-search-form #edit-offscreen { |
||||
display: none; |
||||
} |
||||
|
||||
#ebsco-basic-search-form .form-item-remember label { |
||||
font-weight: bold; |
||||
} |
||||
|
||||
#ebsco-sort-form { |
||||
margin : 10px 0; |
||||
} |
||||
|
||||
#ebsco-sort-form > div { |
||||
border-bottom: 1px solid #CCCCCC; |
||||
} |
||||
|
||||
#ebsco-sort-form label, |
||||
#ebsco-sort-form .form-item { |
||||
display: inline-block !important; |
||||
} |
||||
|
||||
#ebsco-sort-form .form-item:first-child { |
||||
float: right; |
||||
} |
||||
|
||||
#ebsco-sort-form .form-item:last-child { |
||||
float: left; |
||||
} |
||||
|
||||
/** Advanced search form ***/ |
||||
|
||||
.ebsco-advanced ._advanced-row { |
||||
border: 0 none; |
||||
padding: 0; |
||||
margin: 10px; |
||||
top: 5px; |
||||
} |
||||
|
||||
.ebsco-advanced #edit-rows { |
||||
margin-bottom: 20px; |
||||
} |
||||
|
||||
.ebsco-advanced ._advanced-row .fieldset-wrapper { |
||||
margin: 0 !important; |
||||
padding: 0; |
||||
} |
||||
|
||||
.ebsco-advanced .form-item-group0-lookfor label { |
||||
display: inline-block; |
||||
text-align: right; |
||||
width: 100px; |
||||
} |
||||
.ebsco-advanced .form-type-radio label { |
||||
display: inline-block; |
||||
text-align: left; |
||||
width: 90%; |
||||
} |
||||
|
||||
.ebsco-advanced #edit-add-row { |
||||
border: 0 none; |
||||
padding: 0; |
||||
margin: 10px; |
||||
top: 5px; |
||||
} |
||||
|
||||
.ebsco-advanced #edit-add-row .fieldset-wrapper { |
||||
margin-top: 5px; |
||||
} |
||||
|
||||
.ebsco-advanced #edit-links { |
||||
margin-bottom: 20px; |
||||
text-align: center; |
||||
} |
||||
|
||||
.ebsco-advanced #edit-links .fieldset-wrapper { |
||||
margin-top: 10px; |
||||
} |
||||
|
||||
.ebsco-advanced #edit-limiters { |
||||
width: 99%; |
||||
} |
||||
|
||||
.ebsco-advanced #edit-modes { |
||||
width: 49%; |
||||
float: left; |
||||
} |
||||
|
||||
.ebsco-advanced #edit-modes { |
||||
width: 49%; |
||||
float: left; |
||||
} |
||||
|
||||
|
||||
.ebsco-advanced #edit-expanders { |
||||
width: 49%; |
||||
float: right; |
||||
} |
||||
|
||||
.ebsco-advanced #edit-limiters label { |
||||
font-weight: normal; |
||||
} |
||||
|
||||
.ebsco-advanced #edit-limiters .form-type-select label { |
||||
display: block; |
||||
} |
||||
|
||||
.ebsco-advanced #edit-limiters hr { |
||||
margin: 15px 0; |
||||
height: 1px; |
||||
background-color: #CCCCCC; |
||||
color: #CCCCCC; |
||||
border: 0 none; |
||||
} |
||||
|
||||
.dateSlider { |
||||
width: 150px; |
||||
display: inline-block !important; |
||||
margin: 0 10px; |
||||
} |
||||
|
||||
|
||||
/** Icons ***/ |
||||
|
||||
.icon { |
||||
background: url("../images/sprites_32.png") no-repeat top left; |
||||
height: 32px; |
||||
line-height: 32px; |
||||
display: inline-block; |
||||
padding: 0 0 0 36px !important; |
||||
} |
||||
|
||||
.icon.ebook { |
||||
background-position: 0 0; |
||||
} |
||||
|
||||
.icon.html { |
||||
background-position: 0 -42px; |
||||
} |
||||
|
||||
.icon.pdf { |
||||
background-position: 0 -84px; |
||||
} |
||||
|
||||
.icon13 { |
||||
background: url("../images/sprites_32.png") no-repeat top left; |
||||
padding-left: 18px !important; |
||||
width: 13px; |
||||
height: 13px; |
||||
} |
||||
|
||||
.icon13.collapsed { |
||||
background-position: 0 -126px; |
||||
} |
||||
|
||||
.icon13.expanded { |
||||
background-position: 0 -149px; |
||||
} |
||||
|
||||
.icon16 { |
||||
background: url("../images/sprites_32.png") no-repeat top left; |
||||
padding-left: 21px !important; |
||||
width: 16px; |
||||
height: 16px; |
||||
display: inline-block; |
||||
} |
||||
|
||||
.icon16.tick { |
||||
background-position: 0 -171px; |
||||
} |
@ -0,0 +1,8 @@
|
||||
name = EBSCO Discovery Service |
||||
description = Full-text articles and eBooks from EBSCOhost Discovery Service |
||||
core = 7.x |
||||
|
||||
configure = admin/config/search/ebsco |
||||
|
||||
stylesheets[screen][] = css/ebsco.css |
||||
scripts[] = js/ebsco.js |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 6.6 KiB |
@ -0,0 +1,186 @@
|
||||
/* |
||||
* The EBSCO module javascript |
||||
**/ |
||||
(function ($) { |
||||
$(document).ready(function () { |
||||
|
||||
//
|
||||
var updatePublishDateSlider = function () { |
||||
var from = parseInt($('#DT1').val()); |
||||
var min = 1000; |
||||
|
||||
if (!from || from < min) { |
||||
from = min; |
||||
} |
||||
|
||||
// and keep the max at 1 years from now
|
||||
var max = (new Date()).getFullYear() + 1; |
||||
var to = max; |
||||
|
||||
// update the slider with the new min/max/values
|
||||
$('#ebsco-advanced-search-sliderDT1').slider('option', { |
||||
min: min, max: max, values: [from, to] |
||||
}); |
||||
}; |
||||
|
||||
|
||||
/* |
||||
* Self executing function |
||||
**/ |
||||
var onLoad = function () { |
||||
// EBSCO/Search : Expand limiters
|
||||
$('._more_limiters').live('click', function (event) { |
||||
$("#moreLimiters").hide(); |
||||
$("#limitersHidden").removeClass("offscreen"); |
||||
}); |
||||
|
||||
// Search : Collapse limiters
|
||||
$('._less_limiters').live('click', function (event) { |
||||
$("#moreLimiters").show(); |
||||
$("#limitersHidden").addClass("offscreen"); |
||||
}); |
||||
|
||||
// EBSCO/Search : Collapse / expand facets
|
||||
$('.expandable').live('click', function (event) { |
||||
var span = $(this).find('dt span'), |
||||
id = $(this).attr('id').replace('facet-',''); |
||||
if (span.length > 0) { |
||||
if (span.hasClass('collapsed')) { |
||||
$('#narrowGroupHidden_' + id).show(); |
||||
span.removeClass('collapsed'); |
||||
span.addClass('expanded'); |
||||
} else if (span.hasClass('expanded')) { |
||||
$('#narrowGroupHidden_' + id).hide(); |
||||
span.removeClass('expanded'); |
||||
span.addClass('collapsed'); |
||||
} |
||||
} else if ($(this).attr('href')) { |
||||
var dl = $(this).parents('dl'), |
||||
id = dl.attr('id').replace('narrowGroupHidden_', ''), |
||||
span = $('#facet-' + id).find('dt span'); |
||||
dl.hide(); |
||||
span.removeClass('expanded'); |
||||
span.addClass('collapsed'); |
||||
} |
||||
}); |
||||
|
||||
// EBSCO/Search : Less facets
|
||||
$('._less_facets').live('click', function (event) { |
||||
var id = $(this).attr('id').replace('less-facets-',''); |
||||
var dl = $('#facet-' + id); |
||||
dl.trigger('click'); |
||||
}); |
||||
|
||||
// Search : Ajax request the Record action
|
||||
$('._record_link').live('click', function (event) { |
||||
var element = $(this); |
||||
var position = element.position(); |
||||
event.preventDefault(); |
||||
$('#spinner').show(); |
||||
$("#spinner").offset({left:event.pageX - 18,top:event.pageY - 18}); |
||||
|
||||
$.get(element.attr('href'), function (data) { |
||||
$('#main').html(data); |
||||
$('#spinner').hide(); |
||||
}); |
||||
}); |
||||
|
||||
// Advanced Search : Add a new search term
|
||||
$('._add_row').live('click', function (event) { |
||||
event.preventDefault(); |
||||
var newSearch = $('#advanced-row-template').html(); |
||||
var rows = $('._advanced-row'); |
||||
if (rows) { |
||||
// Find the index of the next row
|
||||
var index = rows.length - 1; // one row is the template itself, so don't count it
|
||||
// Replace NN string with the index number
|
||||
newSearch = newSearch.replace(/NN/g, index); |
||||
lastSearch = $('#edit-add-row'); |
||||
lastSearch.before(newSearch); |
||||
} |
||||
}); |
||||
|
||||
// Advanced Search : Delete an advanced search row
|
||||
$('._delete_row').live('click', function (event) { |
||||
event.preventDefault(); |
||||
$(this).parents('._advanced-row').remove(); |
||||
}); |
||||
|
||||
// Advanced Search : Reset the form fields to default values
|
||||
$('.ebsco-advanced input[name="reset"]').live('click', function (event) { |
||||
event.preventDefault(); |
||||
$('#ebsco-advanced-search-form').find('input, select').each(function (index) { |
||||
var type = this.type; |
||||
switch(type) { |
||||
case 'text': |
||||
$(this).val(''); |
||||
break; |
||||
case 'checkbox': |
||||
$(this).attr('checked', ''); |
||||
break; |
||||
case 'select-multiple': |
||||
$(this).children('option').each(function (index) { |
||||
$(this).attr('selected', ''); |
||||
}); |
||||
break; |
||||
case 'select-one': |
||||
$(this).children('option').each(function (index) { |
||||
$(this).attr('selected', ''); |
||||
}); |
||||
// for IE
|
||||
$(this).children('option:first').attr('selected', 'selected'); |
||||
break; |
||||
case 'radio': |
||||
$(this).attr('checked', ''); |
||||
$(this).parent().siblings().first().children('input:first').attr('checked', 'checked'); |
||||
break; |
||||
} |
||||
}); |
||||
}); |
||||
|
||||
// Auto submit the seelct boxes with '_jump_menu' class
|
||||
$('._jump_menu').live('change', function (event) { |
||||
var name = $(this).attr('id').replace('ebsco-', ''), |
||||
value = $(this).attr('value'), |
||||
url = $('#ebsco-sort-form').attr('action'); |
||||
url += "&" + name + "=" + value; |
||||
window.location.href = url; |
||||
}); |
||||
|
||||
// Retain search filters checkbox functionality
|
||||
$('#edit-remember').live('click', function (event) { |
||||
$("#ebsco-basic-search-form :input[type='checkbox'][name^='filter[']").attr('checked', $(this).attr('checked')); |
||||
});
|
||||
|
||||
// Advanced Search : handle 'Date Published from' limiter
|
||||
// Create the UI slider (if slider function is defined)
|
||||
if(typeof $("#ebsco-advanced-search-sliderDT1").slider == 'function') { |
||||
|
||||
$('#ebsco-advanced-search-sliderDT1').slider({ |
||||
range: true, |
||||
min: 0, max: 9999, values: [0, 9999], |
||||
slide: function (event, ui) { |
||||
$('#DT1').val(ui.values[0]); |
||||
if(ui.values[0] == 1000) { |
||||
$('#ebsco-advanced-search-limiterDT1').val(''); |
||||
} else { |
||||
$('#ebsco-advanced-search-limiterDT1').val('addlimiter(DT1:' + ui.values[0] + '-1/2013-1)'); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
// initialize the slider with the original values
|
||||
// in the text boxes
|
||||
updatePublishDateSlider(); |
||||
|
||||
// when user enters values into the boxes
|
||||
// the slider needs to be updated too
|
||||
$('#DT1').change(function(){ |
||||
updatePublishDateSlider(); |
||||
}); |
||||
} |
||||
}(); |
||||
|
||||
|
||||
}); |
||||
})(jQuery); |
@ -0,0 +1,629 @@
|
||||
<?php |
||||
|
||||
/** |
||||
* EBSCO EDS API class |
||||
* |
||||
* PHP version 5 |
||||
* |
||||
*/ |
||||
|
||||
require_once 'EBSCOConnector.php'; |
||||
require_once 'EBSCOResponse.php'; |
||||
|
||||
|
||||
/** |
||||
* 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; |
||||
|
||||
|
||||
/** |
||||
* Configuration options |
||||
*/ |
||||
private $config; |
||||
|
||||
|
||||
/** |
||||
* VuFind search types mapped to EBSCO search types |
||||
* used for urls in search results / detailed result |
||||
* @global array |
||||
*/ |
||||
private static $search_tags = array( |
||||
'' => '', |
||||
'AllFields' => '', |
||||
'Abstract' => 'AB', |
||||
'Author' => 'AU', |
||||
'Source' => 'SO', |
||||
'Subject' => 'SU', |
||||
'Title' => 'TI' |
||||
); |
||||
|
||||
|
||||
/** |
||||
* EBSCO sort options |
||||
* @global array |
||||
*/ |
||||
private static $sort_options = array( |
||||
'relevance', |
||||
'date', |
||||
'date2', |
||||
'source' |
||||
); |
||||
|
||||
|
||||
/** |
||||
* VuFind sort types mapped to EBSCO sort types |
||||
* used for urls in Search results / Detailed view |
||||
* @global array |
||||
*/ |
||||
private static $mapped_sort_options = array( |
||||
'' => 'relevance', |
||||
'relevance' => 'relevance', |
||||
'subject' => 'date', |
||||
'date' => 'date2', |
||||
'date_asc' => 'date2', |
||||
'date_desc' => 'date', |
||||
'callnumber' => 'date', |
||||
'author' => 'author', |
||||
'title' => 'date' |
||||
); |
||||
|
||||
|
||||
/** |
||||
* Constructor |
||||
* |
||||
* |
||||
* @param array config |
||||
* |
||||
* @access public |
||||
*/ |
||||
public function __construct($config) |
||||
{ |
||||
$this->config = $config; |
||||
} |
||||
|
||||
/** |
||||
* Setter / Getter for authentication token |
||||
* |
||||
* @param string The authentication token |
||||
* |
||||
* @return string or none |
||||
* @access public |
||||
*/ |
||||
public function authenticationToken($token = null) |
||||
{ |
||||
if (empty($token)) { |
||||
$token = $this->readSession('authenticationToken'); |
||||
return !empty($token) ? $token : $this->authenticationToken; |
||||
} else { |
||||
$this->authenticationToken = $token; |
||||
$this->writeSession('authenticationToken', $token); |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Setter / Getter for session token |
||||
* |
||||
* @param string The session token |
||||
* |
||||
* @return string or none |
||||
* @access public |
||||
*/ |
||||
public function sessionToken($token = null) |
||||
{ |
||||
if (empty($token)) { |
||||
$token = $this->readSession('sessionToken'); |
||||
return !empty($token) ? $token : $this->sessionToken; |
||||
} else { |
||||
$this->sessionToken = $token; |
||||
$this->writeSession('sessionToken', $token); |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Getter for isGuest |
||||
* |
||||
* @param string 'y' or 'n' |
||||
* |
||||
* @return string or none |
||||
* @access public |
||||
*/ |
||||
public function isGuest($boolean = null) |
||||
{ |
||||
if (empty($boolean)) { |
||||
return $this->readSession('isGuest'); |
||||
} else { |
||||
$this->writeSession('isGuest', $boolean); |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Create a new EBSCOConnector object or reuse an existing one |
||||
* |
||||
* @param none |
||||
* |
||||
* @return EBSCOConnector object |
||||
* @access public |
||||
*/ |
||||
public function connector() |
||||
{ |
||||
if (empty($this->connector)) { |
||||
$this->connector = new EBSCOConnector($this->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 of the HTTP request |
||||
* @param integer $attempts The number of retries |
||||
* |
||||
* @return object SimpleXml DOM or PEAR Error |
||||
* @access protected |
||||
*/ |
||||
protected function request($action, $params = null, $attempts = 5) |
||||
{ |
||||
$authenticationToken = $this->authenticationToken(); |
||||
$sessionToken = $this->sessionToken(); |
||||
|
||||
// If authentication token is missing then the session token is missing too, so get both tokens |
||||
// If session token is missing then the authentication token may be invalid, so get both tokens |
||||
if (empty($authenticationToken) || empty($sessionToken)) { |
||||
$result = $this->apiAuthenticationAndSessionToken(); |
||||
if ($this->isError($result)) { |
||||
// Any error should terminate the request immediately |
||||
// in order to prevent infinite recursion |
||||
return $result; |
||||
} |
||||
} |
||||
|
||||
// Any change of the isGuest should request a new session |
||||
// (and don't terminate the current request if there was an error during the session request |
||||
// since it's not that important) |
||||
if ($this->isGuest() != $this->connector()->isGuest()) { |
||||
$this->apiSessionToken(); |
||||
} |
||||
|
||||
$headers = array( |
||||
'x-authenticationToken' => $this->authenticationToken(), |
||||
'x-sessionToken' => $this->sessionToken() |
||||
); |
||||
|
||||
$response = call_user_func_array(array($this->connector(), "request{$action}"), array($params, $headers)); |
||||
if ($this->isError($response)) { |
||||
// Retry the request if there were authentication errors |
||||
$code = $response->getCode(); |
||||
switch ($code) { |
||||
// If authentication token is invalid then the session token is invalid too, so get both tokens |
||||
// If session token is invalid then the authentication token may be invalid too, so get both tokens |
||||
case EBSCOConnector::EDS_AUTH_TOKEN_INVALID: |
||||
$result = $this->apiAuthenticationToken(); |
||||
if ($this->isError($result)) { |
||||
// Any error should terminate the request immediately |
||||
// in order to prevent infinite recursion |
||||
return $result; |
||||
} |
||||
if ($attempts > 0) { |
||||
$result = $this->request($action, $params, --$attempts); |
||||
} |
||||
break; |
||||
case EBSCOConnector::EDS_SESSION_TOKEN_INVALID: |
||||
$result = $this->apiAuthenticationAndSessionToken(); |
||||
if ($this->isError($result)) { |
||||
// Any error should terminate the request immediately |
||||
// in order to prevent infinite recursion |
||||
return $result; |
||||
} |
||||
if ($attempts > 0) { |
||||
$result = $this->request($action, $params, --$attempts); |
||||
} |
||||
break; |
||||
default: |
||||
$result = $this->handleError($response); |
||||
break; |
||||
} |
||||
} else { |
||||
$result = $this->response($response)->result(); |
||||
} |
||||
|
||||
return $result; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Wrapper for authentication API call |
||||
* |
||||
* @param none |
||||
* |
||||
* @access public |
||||
*/ |
||||
public function apiAuthenticationToken() |
||||
{ |
||||
$response = $this->connector()->requestAuthenticationToken(); |
||||
|
||||
if ($this->isError($response)) { |
||||
return $response; |
||||
} else { |
||||
$result = $this->response($response)->result(); |
||||
if (isset($result['authenticationToken'])) { |
||||
$this->authenticationToken($result['authenticationToken']); |
||||
return $result['authenticationToken']; |
||||
} else { |
||||
return new EBSCOException("No authentication token was found in the response."); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Wrapper for session API call |
||||
* |
||||
* @param none |
||||
* |
||||
* @access public |
||||
*/ |
||||
public function apiSessionToken() |
||||
{ |
||||
// Add authentication tokens to headers |
||||
$headers = array( |
||||
'x-authenticationToken' => $this->authenticationToken() |
||||
); |
||||
|
||||
$response = $this->connector()->requestSessionToken($headers); |
||||
|
||||
// Raise the exception so that any code running this method should exit immediately |
||||
if ($this->isError($response)) { |
||||
return $response; |
||||
} else { |
||||
$result = $this->response($response)->result(); |
||||
if (is_string($result)) { |
||||
$this->sessionToken($result); |
||||
return $result; |
||||
} else { |
||||
return new EBSCOException("No session token was found in the response."); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Initialize the authentication and session tokens |
||||
* |
||||
* @param none |
||||
* |
||||
* @access public |
||||
*/ |
||||
public function apiAuthenticationAndSessionToken() |
||||
{ |
||||
$authenticationToken = $this->apiAuthenticationToken(); |
||||
if ($this->isError($authenticationToken)) { |
||||
// An authentication error should terminate the request immediately |
||||
return $authenticationToken; |
||||
} |
||||
|
||||
$sessionToken = $this->apiSessionToken(); |
||||
if ($this->isError($sessionToken)) { |
||||
// A session error should terminate the request immediately |
||||
return $sessionToken; |
||||
} |
||||
|
||||
// We don't have to return anything, both tokens can be accessed using the getters |
||||
return true; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Wrapper for search API call |
||||
* |
||||
* @param array $search The search terms |
||||
* @param array $filters The facet filters |
||||
* @param string $start The page to start with |
||||
* @param string $limit The number of records to return |
||||
* @param string $sortBy The value to be used by for sorting |
||||
* @param string $amount The amount of data to be returned |
||||
* @param string $mode The search mode |
||||
* |
||||
* @throws object PEAR Error |
||||
* @return array An array of query results |
||||
* @access public |
||||
*/ |
||||
public function apiSearch($search, $filters, |
||||
$start = 1, $limit = 10, $sortBy = 'relevance', $amount = 'detailed', $mode = 'all' |
||||
) { |
||||
$query = array(); |
||||
|
||||
// Basic search |
||||
if(!empty($search['lookfor'])) { |
||||
$lookfor = $search['lookfor']; |
||||
$type = isset($search['index']) && !empty($search['index']) ? $search['index'] : 'AllFields'; |
||||
|
||||
// escape some characters from lookfor term |
||||
$term = str_replace(array(',', ':', '(', ')'), array('\,', '\:', '\(', '\)'), $lookfor); |
||||
// replace multiple consecutive empty spaces with one empty space |
||||
$term = preg_replace("/\s+/", ' ', $term); |
||||
|
||||
// search terms |
||||
// Complex search term |
||||
if (preg_match('/(.*) (AND|OR) (.*)/i', $term)) { |
||||
$query['query'] = $term; |
||||
} else { |
||||
$tag = self::$search_tags[$type]; |
||||
$op = 'AND'; |
||||
$query_str = implode(',', array($op, $tag)); |
||||
$query_str = implode(($tag ? ':' : ''), array($query_str, $term)); |
||||
$query['query-1'] = $query_str; |
||||
} |
||||
|
||||
// Advanced search |
||||
} else if(!empty($search['group'])) { |
||||
|
||||
$counter = 1; |
||||
foreach ($search['group'] as $group) { |
||||
$type = $group['type']; |
||||
if (isset($group['lookfor'])) { |
||||
$term = $group['lookfor']; |
||||
$op = $group['bool']; |
||||
$tag = $type && isset(self::$search_tags[$type]) ? self::$search_tags[$type] : ''; |
||||
|
||||
// escape some characters from lookfor term |
||||
$term = str_replace(array(',', ':', '(', ')'), array('\,', '\:', '\(', '\)'), $term); |
||||
// replace multiple consecutive empty spaces with one empty space |
||||
$term = preg_replace("/\s+/", ' ', $term); |
||||
if (!empty($term)) { |
||||
$query_str = implode(',', array($op, $tag)); |
||||
$query_str = implode(($tag ? ':' : ''), array($query_str, $term)); |
||||
$query["query-$counter"] = $query_str; |
||||
$counter++; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// No search term, return an empty array |
||||
} else { |
||||
$results = array( |
||||
'recordCount' => 0, |
||||
'numFound' => 0, |
||||
'start' => 0, |
||||
'documents' => array(), |
||||
'facets' => array() |
||||
); |
||||
return $results; |
||||
} |
||||
|
||||
// Add filters |
||||
$limiters = array(); $expanders = array(); $facets = array(); |
||||
foreach ($filters as $filter) { |
||||
if (preg_match('/addlimiter/', $filter)) { |
||||
list($action, $str) = explode('(', $filter, 2); |
||||
$field_and_value = substr($str, 0, -1); // e.g. FT:y or GZ:Student Research, Projects and Publications |
||||
list($field, $value) = explode(':', $field_and_value, 2); |
||||
$limiters[$field][] = $value; |
||||
} else if (preg_match('/addexpander/', $filter)) { |
||||
list($action, $str) = explode('(', $filter, 2); |
||||
$field = substr($str, 0, -1); // expanders don't have value |
||||
$expanders[] = $field; |
||||
} else if (preg_match('/addfacetfilter/', $filter)) { |
||||
list($action, $str) = explode('(', $filter, 2); |
||||
$field_and_value = substr($str, 0, -1); // e.g. ZG:FRANCE |
||||
list($field, $value) = explode(':', $field_and_value, 2); |
||||
$facets[$field][] = $field_and_value; |
||||
} |
||||
} |
||||
if (!empty($limiters)) { |
||||
foreach($limiters as $field => $limiter) { |
||||
$query['limiter'][] = $field . ':' . implode(',', $limiter); // e.g. LA99:English,French,German |
||||
} |
||||
} |
||||
if (!empty($expanders)) { |
||||
$query['expander'] = implode(',', $expanders); // e.g. fulltext, thesaurus |
||||
} |
||||
if (!empty($facets)) { |
||||
$groupId = 1; |
||||
foreach($facets as $field => $facet) { |
||||
$query['facetfilter'][] = $groupId . ',' . implode(',', $facet); // e.g. 1,DE:Math,DE:History |
||||
$groupId += 1; |
||||
} |
||||
} |
||||
|
||||
// Add the sort option |
||||
$sortBy = in_array($sortBy, self::$sort_options) ? $sortBy : self::$mapped_sort_options[$sortBy]; |
||||
|
||||
// Add the HTTP query params |
||||
$params = array( |
||||
// Specifies the sort. Valid options are: |
||||
// relevance, date, date2 |
||||
// date = Date descending |
||||
// date2 = Date ascending |
||||
'sort' => $sortBy, |
||||
// Specifies the search mode. Valid options are: |
||||
// bool, any, all, smart |
||||
'searchmode' => $mode, |
||||
// Specifies the amount of data to return with the response |
||||
// Valid options are: |
||||
// title: Title only |
||||
// brief: Title + Source, Subjects |
||||
// detailed: Brief + full abstract |
||||
'view' => $amount, |
||||
/// Specifies whether or not to include facets |
||||
'includefacets' => 'y', |
||||
'resultsperpage' => $limit, |
||||
'pagenumber' => $start, |
||||
// Specifies whether or not to include highlighting in the search results |
||||
'highlight' => 'y' |
||||
); |
||||
|
||||
$params = array_merge($params, $query); |
||||
|
||||
$result = $this->request('Search', $params); |
||||
return $result; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 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) |
||||
{ |
||||
// Add the HTTP query params |
||||
$params = array( |
||||
'an' => $an, |
||||
'dbid' => $db, |
||||
'highlight' => 'y' |
||||
); |
||||
|
||||
$result = $this->request('Retrieve', $params); |
||||
return $result; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Wrapper for info API call |
||||
* |
||||
* @throws object PEAR Error |
||||
* @return array An associative array of data |
||||
* @access public |
||||
*/ |
||||
public function apiInfo() |
||||
{ |
||||
if ($result = $this->readSession('info')) { |
||||
return $result; |
||||
} |
||||
|
||||
$result = $this->request('Info'); |
||||
if(!$this->isError($result)) { |
||||
$this->writeSession('info', $result); |
||||
} |
||||
return $result; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Handle a PEAR_Error. Return : |
||||
* - if the error is critical : an associative array with the current error message |
||||
* - if the error is not critical : the error message |
||||
* |
||||
* @param Pear_Error $exception |
||||
* |
||||
* @return array or the Pear_Error exception |
||||
* @access protected |
||||
*/ |
||||
private function handleError($error) { |
||||
$errorCode = $error->getCode(); |
||||
switch($errorCode) { |
||||
// This kind of error was generated by user , so display it to user |
||||
case EBSCOConnector::EDS_INVALID_ARGUMENT_VALUE: |
||||
// Any other errors are system errors, don't display them to user |
||||
default: |
||||
$errorMessage = 'An error occurred when getting the data.'; |
||||
break; |
||||
} |
||||
$result = array( |
||||
'errors' => $errorMessage, |
||||
'recordCount' => 0, |
||||
'numFound' => 0, |
||||
'start' => 0, |
||||
'documents' => array(), |
||||
'facets' => array() |
||||
); |
||||
return $result; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Store the given object into session |
||||
* |
||||
* @param string $key The key used for reading the value |
||||
* @param object $value The object stored in session |
||||
* |
||||
* @return none |
||||
* @access protected |
||||
*/ |
||||
protected function writeSession($key, $value) |
||||
{ |
||||
if(!empty($key) && !empty($value)) { |
||||
$_SESSION['EBSCO'][$key] = $value; |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Read from session the object having the given key |
||||
* |
||||
* @param string $key The key used for reading the object |
||||
* |
||||
* @return object |
||||
* @access protected |
||||
*/ |
||||
protected function readSession($key) |
||||
{ |
||||
$value = isset($_SESSION['EBSCO'][$key]) ? $_SESSION['EBSCO'][$key] : ''; |
||||
return $value; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Check if given object is an EBSCOException object |
||||
* |
||||
* @param object $object |
||||
* |
||||
* @return boolean |
||||
* @access protected |
||||
*/ |
||||
protected function isError($object) |
||||
{ |
||||
return is_a($object, 'EBSCOException'); |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
?> |
@ -0,0 +1,432 @@
|
||||
<?php |
||||
|
||||
/** |
||||
* EBSCOException class |
||||
* Used when EBSCO API calls return error messages |
||||
*/ |
||||
class EBSCOException extends Exception |
||||
{ |
||||
const CRITICAL_ERROR = 1; |
||||
|
||||
// Make message argument mandatory |
||||
public function __construct($message, $code = self::CRITICAL_ERROR, Exception $previous = null) { |
||||
parent::__construct($message, $code, $previous); |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
class EBSCOConnector |
||||
{ |
||||
/** |
||||
* Error codes defined by EDS API |
||||
*/ |
||||
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; |
||||
const EDS_INVALID_EXPANDER_ERROR = 123; |
||||
const EDS_INVALID_SEARCH_MODE_ERROR = 124; |
||||
const EDS_INVALID_LIMITER_ERROR = 125; |
||||
const EDS_INVALID_LIMITER_VALUE_ERROR = 126; |
||||
const EDS_UNSUPPORTED_PROFILE_ERROR = 127; |
||||
const EDS_PROFILE_NOT_SUPPORTED_ERROR = 128; |
||||
const EDS_INVALID_CONTENT_PROVIDER_ERROR = 129; |
||||
const EDS_INVALID_SOURCE_TYPE_ERROR = 130; |
||||
const EDS_XSLT_ERROR = 131; |
||||
const EDS_RECORD_NOT_FOUND_ERROR = 132; |
||||
const EDS_SIMULTANEOUS_USER_LIMIT_ERROR = 133; |
||||
const EDS_NO_GUEST_ACCESS_ERROR = 134; |
||||
const EDS_DBID_NOT_IN_PROFILE_ERROR = 135; |
||||
const EDS_INVALID_SEARCH_VIEW_ERROR = 136; |
||||
const EDS_RETRIEVING_FULL_TEXT_ERROR = 137; |
||||
|
||||
|
||||
/** |
||||
* HTTP status codes constants |
||||
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html |
||||
* |
||||
* @global integer HTTP_OK The request has succeeded |
||||
* @global integer HTTP_NOT_FOUND The server has not found anything matching the Request-URI |
||||
*/ |
||||
const HTTP_OK = 200; |
||||
const HTTP_BAD_REQUEST = 400; |
||||
const HTTP_NOT_FOUND = 404; |
||||
const HTTP_INTERNAL_SERVER_ERROR = 500; |
||||
|
||||
|
||||
/** |
||||
* The HTTP_Request object used for API transactions |
||||
* @global object HTTP_Request |
||||
*/ |
||||
private $client; |
||||
|
||||
|
||||
/** |
||||
* The URL of the EBSCO API server |
||||
* @global string |
||||
*/ |
||||
private static $end_point = 'http://eds-api.ebscohost.com/EDSAPI/rest'; |
||||
|
||||
|
||||
/** |
||||
* The URL of the EBSCO API server |
||||
* @global string |
||||
*/ |
||||
private static $authentication_end_point = 'https://eds-api.ebscohost.com/AuthService/rest'; |
||||
|
||||
|
||||
/** |
||||
* The password used for API transactions |
||||
* @global string |
||||
*/ |
||||
private $password; |
||||
|
||||
|
||||
/** |
||||
* The user id used for API transactions |
||||
* @global string |
||||
*/ |
||||
private $userId; |
||||
|
||||
|
||||
/** |
||||
* The profile ID used for API transactions |
||||
* @global string |
||||
*/ |
||||
private $profileId; |
||||
|
||||
|
||||
/** |
||||
* The interface ID used for API transactions |
||||
* @global string |
||||
*/ |
||||
private $interfaceId; |
||||
|
||||
|
||||
/** |
||||
* The customer ID used for API transactions |
||||
* @global string |
||||
*/ |
||||
private $orgId; |
||||
|
||||
|
||||
/** |
||||
* The isGuest used for API transactions |
||||
* @global string 'y' or 'n' |
||||
*/ |
||||
private $isGuest; |
||||
|
||||
|
||||
/* |
||||
* You can log HTTP_Request requests using this option |
||||
* @global bool logAPIRequests |
||||
*/ |
||||
private $logAPIRequests; |
||||
|
||||
|
||||
/** |
||||
* The logger object |
||||
* @global object Logger |
||||
*/ |
||||
private $logger; |
||||
|
||||
|
||||
/** |
||||
* Constructor |
||||
* |
||||
* Sets up the EBSCO API settings |
||||
* |
||||
* @param none |
||||
* |
||||
* @access public |
||||
*/ |
||||
public function __construct($config) |
||||
{ |
||||
$this->password = $config['password']; |
||||
$this->userId = $config['user']; |
||||
$this->interfaceId = $config['interface']; |
||||
$this->profileId = $config['profile']; |
||||
$this->orgId = $config['organization']; |
||||
$this->isGuest = user_is_logged_in() ? 'n' : 'y'; |
||||
$this->logAPIRequests = ($config['log'] == 1); |
||||
if ($this->logAPIRequests) { |
||||
$writer = new Zend_Log_Writer_Stream('php://output'); |
||||
$this->logger = new Zend_Log($writer); |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Public getter for private isGuest |
||||
* |
||||
* @param none |
||||
* |
||||
* @return string isGuest |
||||
* @access public |
||||
*/ |
||||
public function isGuest() |
||||
{ |
||||
return $this->isGuest; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Request the authentication token |
||||
* |
||||
* @param none |
||||
* |
||||
* @return object SimpleXml or PEAR_Error |
||||
* @access public |
||||
*/ |
||||
public function requestAuthenticationToken() |
||||
{ |
||||
$url = self::$authentication_end_point . '/UIDAuth'; |
||||
|
||||
// Add the body of the request |
||||
$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; |
||||
|
||||
$response = $this->request($url, $params, array(), 'POST'); |
||||
return $response; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Request the session token |
||||
* |
||||
* @param array $headers Authentication token |
||||
* |
||||
* @return object SimpleXml or PEAR_Error |
||||
* @access public |
||||
*/ |
||||
public function requestSessionToken($headers) |
||||
{ |
||||
$url = self::$end_point . '/CreateSession'; |
||||
|
||||
// Add the HTTP query params |
||||
$params = array( |
||||
'profile' => $this->profileId, |
||||
'org' => $this->orgId, |
||||
'guest' => $this->isGuest |
||||
); |
||||
|
||||
$response = $this->request($url, $params, $headers); |
||||
return $response; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Request the search records |
||||
* |
||||
* @param array $params Search specific parameters |
||||
* @param array $headers Authentication and session tokens |
||||
* |
||||
* @return object SimpleXml or PEAR_Error |
||||
* @access public |
||||
*/ |
||||
public function requestSearch($params, $headers) |
||||
{ |
||||
$url = self::$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 object SimpleXml or PEAR_Error |
||||
* @access public |
||||
*/ |
||||
public function requestRetrieve($params, $headers) |
||||
{ |
||||
$url = self::$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 object SimpleXml or PEAR_Error |
||||
* @access public |
||||
*/ |
||||
public function requestInfo($params, $headers) |
||||
{ |
||||
$url = self::$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 or PEAR_Error |
||||
* @access protected |
||||
*/ |
||||
protected function request($url, $params, $headers = array(), $method = 'GET') |
||||
{ |
||||
$xml = false; |
||||
$return = false; |
||||
$data = null; |
||||
|
||||
if (!empty($params)) { |
||||
// Arrays of parameters are used only for GET requests |
||||
if (is_array($params)) { |
||||
$query = http_build_query($params, '', '&'); |
||||
$query = preg_replace('/\%5B\d+\%5D/', '', $query); |
||||
$url = $url . '?' . $query; |
||||
// String parameters are used only for POST requests |
||||
} else { |
||||
$data = $params; |
||||
$headers = array_merge( |
||||
array('content-type' => 'text/xml'), |
||||
$headers |
||||
); |
||||
} |
||||
} |
||||
|
||||
$options = array( |
||||
'headers' => $headers, |
||||
'method' => $method, |
||||
'data' => $data |
||||
); |
||||
|
||||
// Send the request |
||||
try { |
||||
$response = drupal_http_request($url, $options); |
||||
//print_r($response); |
||||
$code = $response->code; |
||||
switch ($code) { |
||||
case self::HTTP_OK: |
||||
$xml_str = $response->data; |
||||
try { |
||||
$xml = simplexml_load_string($xml_str); |
||||
$return = $xml; |
||||
} catch(Exception $e) { |
||||
$return = new EBSCOException($xml); |
||||
} |
||||
break; |
||||
|
||||
case self::HTTP_BAD_REQUEST: |
||||
$xml_str = $response->data; |
||||
try { |
||||
$xml = simplexml_load_string($xml_str); |
||||
|
||||
// If the response is an API error |
||||
$isError = isset($xml->ErrorNumber) || isset($xml->ErrorCode); |
||||
if ($isError) { |
||||
$error = ''; $code = 0; |
||||
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; |
||||
} |
||||
$return = new EBSCOException($error, $code); |
||||
} else { |
||||
$return = new EBSCOException("HTTP {$code} : The request could not be understood |
||||
by the server due to malformed syntax. Modify your search before retrying."); |
||||
} |
||||
} catch (Exception $e) { |
||||
$return = new EBSCOException($xml); |
||||
} |
||||
break; |
||||
|
||||
case self::HTTP_NOT_FOUND: |
||||
$return = new EBSCOException("HTTP {$code} : 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: |
||||
$return = new EBSCOException("HTTP {$code} : The server encountered an unexpected condition |
||||
which prevented it from fulfilling the request."); |
||||
break; |
||||
|
||||
default: |
||||
$return = new EBSCOException("HTTP {$code} : Unexpected HTTP error."); |
||||
break; |
||||
} |
||||
} catch (Exception $e) { |
||||
$return = new EBSCOException($response); |
||||
} |
||||
|
||||
// Log any error |
||||
/*if ($this->logAPIRequests) { |
||||
// $client = both the HTTP request and response |
||||
// $response = only the HTTP response |
||||
$message = $this->toString($client); // or $this->toString($response) |
||||
$this->logger->log($message, Zend_Log::ERR); |
||||
}*/ |
||||
|
||||
return $return; |
||||
} |
||||
|
||||
|
||||
/* |
||||
* Capture the output of print_r into a string |
||||
* |
||||
* @param object Any object |
||||
* @access private |
||||
*/ |
||||
private function toString($object) |
||||
{ |
||||
ob_start(); |
||||
print_r($object); |
||||
return ob_get_clean(); |
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
|
||||
?> |
@ -0,0 +1,788 @@
|
||||
<?php |
||||
|
||||
/** |
||||
* The EBSCO Document model class |
||||
* |
||||
* It provides all the methods and properties needed for : |
||||
* - setting up and performing API calls |
||||
* - displaying results in UI |
||||
* - displaying statistics about the search, etc |
||||
* |
||||
* PHP version 5 |
||||
* |
||||
*/ |
||||
|
||||
require_once 'EBSCOAPI.php'; |
||||
require_once 'EBSCORecord.php'; |
||||
|
||||
|
||||
class EBSCODocument |
||||
{ |
||||
/** |
||||
* The EBSCOAPI object that performs the API calls |
||||
* @global object EBSCOAPI |
||||
*/ |
||||
private $eds = null; |
||||
|
||||
/** |
||||
* The associative array of current request parameters |
||||
* @global array |
||||
*/ |
||||
private $params = array(); |
||||
|
||||
/** |
||||
* The associative array of EBSCO results returned by a Search API call |
||||
* #global array |
||||
*/ |
||||
private $results = array(); |
||||
|
||||
/** |
||||
* The associative array of data returned by a Retrieve API call |
||||
* @global array |
||||
*/ |
||||
private $result = array(); |
||||
|
||||
/** |
||||
* The array of data returned by an Info API call |
||||
* @global array |
||||
*/ |
||||
private $info = array(); |
||||
|
||||
/** |
||||
* The EBSCORecord model returned by a Retrieve API call |
||||
* #global object EBSCORecord |
||||
*/ |
||||
private $record = null; |
||||
|
||||
/** |
||||
* The array of EBSCORecord models returned by a Search API call |
||||
* #global array of EBSCORecord objects |
||||
*/ |
||||
private $records = array(); |
||||
|
||||
/** |
||||
* The array of filters currently applied |
||||
* @global array |
||||
*/ |
||||
private $filters = array(); |
||||
|
||||
/** |
||||
* Maximum number of results returned by Search API call |
||||
* @global integer |
||||
*/ |
||||
private $limit = 10; |
||||
|
||||
/** |
||||
* Maximum number of links displayed by the pagination |
||||
* @global integer |
||||
*/ |
||||
private static $page_links = 10; |
||||
|
||||
/** |
||||
* Limit options |
||||
* global array |
||||
*/ |
||||
private static $limit_options = array( |
||||
10 => 10, |
||||
20 => 20, |
||||
30 => 30, |
||||
40 => 40, |
||||
50 => 50 |
||||
); |
||||
|
||||
/** |
||||
* Sort options |
||||
* global array |
||||
*/ |
||||
private static $sort_options = array( |
||||
'relevance' => 'Relevance', |
||||
'date_desc' => 'Date Descending', |
||||
'date_asc' => 'Date Ascending' |
||||
); |
||||
|
||||
/** |
||||
* Amount options |
||||
* global array |
||||
*/ |
||||
private static $amount_options = array( |
||||
'detailed' => 'Detailed', |
||||
'brief' => 'Brief', |
||||
'title' => 'Title Only' |
||||
); |
||||
|
||||
/** |
||||
* Bool options |
||||
* global array |
||||
*/ |
||||
private static $bool_options = array( |
||||
'AND' => 'All terms', |
||||
'OR' => 'Any terms', |
||||
'NOT' => 'No terms' |
||||
); |
||||
|
||||
/** |
||||
* Search mode options |
||||
* global array |
||||
*/ |
||||
private static $mode_options = array( |
||||
'all' => 'All search terms', |
||||
'bool' => 'Boolean / Phrase', |
||||
'any' => 'Any search terms', |
||||
'smart' => 'SmartText Searching' |
||||
); |
||||
|
||||
/** |
||||
* Basic search type options |
||||
* global array |
||||
*/ |
||||
private static $basic_search_type_options = array( |
||||
'AllFields' => 'All Text', |
||||
'Title' => 'Title', |
||||
'Author' => 'Author', |
||||
'Subject' => 'Subject terms', |
||||
'Source' => 'Source', |
||||
'Abstract' => 'Abstract' |
||||
); |
||||
|
||||
/** |
||||
* Advanced search type options |
||||
* global array |
||||
*/ |
||||
private static $advanced_search_type_options = array( |
||||
'AllFields' => 'All Text', |
||||
'Title' => 'Title', |
||||
'Author' => 'Author', |
||||
'Subject' => 'Subject terms' |
||||
); |
||||
|
||||
|
||||
/** |
||||
* Constructor. |
||||
* |
||||
* @param array $data Raw data from the EBSCO search representing the record. |
||||
*/ |
||||
public function __construct($params = null) |
||||
{ |
||||
$this->eds = new EBSCOAPI(array( |
||||
'password' => variable_get('ebsco_password'), |
||||
'user' => variable_get('ebsco_user'), |
||||
'profile' => variable_get('ebsco_profile'), |
||||
'interface' => variable_get('ebsco_interface'), |
||||
'organization' => variable_get('ebsco_organization'), |
||||
'guest' => variable_get('ebsco_guest'), |
||||
'log' => variable_get('ebsco_log') |
||||
)); |
||||
|
||||
$this->params = $params ? $params : $_REQUEST; |
||||
$this->limit = variable_get('ebsco_default_limit') ? variable_get('ebsco_default_limit') : $this->limit; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Perform the API Info call |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function info() |
||||
{ |
||||
$this->info = $this->eds->apiInfo(); |
||||
return $this->info; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Perform the API Retrieve call |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function retrieve() |
||||
{ |
||||
list($an, $db) = isset($this->params['id']) ? explode('|', $this->params['id'], 2) : array(null, null); |
||||
$this->result = $this->eds->apiRetrieve($an, $db); |
||||
|
||||
return $this->result; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Perform the API Search call |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function search() |
||||
{ |
||||
$search = array(); |
||||
|
||||
if (isset($this->params['lookfor']) && isset($this->params['type'])) { |
||||
$search = array( |
||||
'lookfor' => $this->params['lookfor'], |
||||
'index' => $this->params['type'] |
||||
); |
||||
} else if (isset($this->params['group'])) { |
||||
$search = $this->params; |
||||
} else { |
||||
return array(); |
||||
} |
||||
|
||||
$filter = isset($this->params['filter']) ? $this->params['filter'] : array(); |
||||
$page = isset($this->params['page']) ? $this->params['page'] + 1 : 1; |
||||
$limit = $this->limit; |
||||
$sort = isset($this->params['sort']) ? $this->params['sort'] : 'relevance'; |
||||
$amount = isset($this->params['amount']) ? $this->params['amount'] : 'detailed'; |
||||
$mode = isset($this->params['mode']) ? $this->params['mode'] : 'all'; |
||||
|
||||
$this->results = $this->eds->apiSearch($search, $filter, $page, $limit, $sort, $amount, $mode); |
||||
|
||||
if (isset($this->results['start'])) { |
||||
$this->results['start'] = $limit * ($page - 1); |
||||
} |
||||
|
||||
return $this->results; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the EBSCORecord model for the result |
||||
* |
||||
** @return array |
||||
*/ |
||||
public function record() |
||||
{ |
||||
if (empty($this->record) && !(empty($this->result))) { |
||||
$this->record = new EBSCORecord($this->result); |
||||
} |
||||
|
||||
return $this->record; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the EBSCORecord models array from results array |
||||
* |
||||
** @return array |
||||
*/ |
||||
public function records() |
||||
{ |
||||
if (empty($this->records) && !(empty($this->results))) { |
||||
foreach($this->results['documents'] as $result) { |
||||
$this->records[] = new EBSCORecord($result); |
||||
} |
||||
} |
||||
|
||||
return $this->records; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the pagination HTML string |
||||
* |
||||
** @return HTML string |
||||
*/ |
||||
public function pager() |
||||
{ |
||||
$pager = null; |
||||
if ($this->has_records()) { |
||||
pager_default_initialize($this->record_count() / $this->limit, 1); |
||||
$pager = theme('pager', array('tags' => null, 'quantity' => self::$page_links)); |
||||
$pager = preg_replace('/<li class="pager-last last">(.*)<\/li>/', '', $pager); |
||||
} |
||||
return $pager; |
||||
} |
||||
|
||||
|
||||
/******************************************************** |
||||
* |
||||
* Getters (class methods) |
||||
* |
||||
********************************************************/ |
||||
|
||||
|
||||
/** |
||||
* Getter for sort options |
||||
* @return array |
||||
*/ |
||||
public static function limit_options() |
||||
{ |
||||
return self::$limit_options; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Getter for sort options |
||||
* @return array |
||||
*/ |
||||
public static function sort_options() |
||||
{ |
||||
return self::$sort_options; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Getter for amount options |
||||
* @return array |
||||
*/ |
||||
public static function amount_options() |
||||
{ |
||||
return self::$amount_options; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Getter for boolean options |
||||
* @return array |
||||
*/ |
||||
public static function bool_options() |
||||
{ |
||||
return self::$bool_options; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Getter for search mode options |
||||
* @return array |
||||
*/ |
||||
public static function mode_options() |
||||
{ |
||||
return self::$mode_options; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Getter for Basic search type options |
||||
* @return array |
||||
*/ |
||||
public static function basic_search_type_options() |
||||
{ |
||||
return self::$basic_search_type_options; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Getter for Advanced search type options |
||||
* @return array |
||||
*/ |
||||
public static function advanced_search_type_options() |
||||
{ |
||||
return self::$advanced_search_type_options; |
||||
} |
||||
|
||||
|
||||
/******************************************************** |
||||
* |
||||
* Helper methods |
||||
* |
||||
********************************************************/ |
||||
|
||||
|
||||
/** |
||||
* Get the expanders. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function expanders() |
||||
{ |
||||
$actions = array(); |
||||
$filters = $this->filters(); |
||||
foreach($filters as $filter) { |
||||
$actions[] = $filter['action']; |
||||
} |
||||
|
||||
$expanders = isset($this->info['expanders']) ? $this->info['expanders'] : array(); |
||||
foreach($expanders as $key => $expander) { |
||||
if (in_array($expander['Action'], $actions)) { |
||||
$expanders[$key]['selected'] = true; |
||||
} |
||||
} |
||||
|
||||
return $expanders; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the facets. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function facets() |
||||
{ |
||||
$actions = array(); |
||||
foreach($this->filters as $filter) { |
||||
$actions[] = $filter['action']; |
||||
} |
||||
|
||||
$facets = isset($this->results['facets']) ? $this->results['facets'] : array(); |
||||
foreach($facets as $key => $cluster) { |
||||
foreach($cluster['Values'] as $k => $facet) { |
||||
$is_applied = false; |
||||
if (in_array($facet['Action'], $actions)) { |
||||
$is_applied = true; |
||||
} |
||||
$facets[$key]['Values'][$k]['applied'] = $is_applied; |
||||
} |
||||
} |
||||
|
||||
return $facets; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the filters. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function filters() |
||||
{ |
||||
if (!empty($_REQUEST['filter'])) { |
||||
$labels = array(); |
||||
foreach($this->info['limiters'] as $limiter) { |
||||
$labels[$limiter['Id']] = $limiter['Label']; |
||||
} |
||||
$this->filters = array(); |
||||
foreach($_REQUEST['filter'] as $filter) { |
||||
if (!empty($filter)) { |
||||
$temp = str_replace(array('addfacetfilter(', 'addlimiter(', 'addexpander('), array('', '', ''), $filter); |
||||
if (substr($temp, -1, 1) == ')') { |
||||
$temp = substr($temp, 0, -1); |
||||
} |
||||
// Do not display addfacetfilter, addlimiter or addexpander strings |
||||
if (preg_match('/\:/', $filter)) { |
||||
list($field, $value) = explode(':', $temp, 2); |
||||
$displayField = isset($labels[$field]) ? $labels[$field] : $field; |
||||
$displayValue = $value == 'y' ? 'yes' : $value; |
||||
} else if (preg_match('/addexpander/', $filter)) { |
||||
$field = $temp; |
||||
$value = 'y'; |
||||
$displayField = isset($labels[$field]) ? $labels[$field] : $field; |
||||
$displayValue = 'yes'; |
||||
} else { |
||||
$field = $value = $displayField = $displayValue = $filter; |
||||
} |
||||
|
||||
$this->filters[] = array( |
||||
'field' => $field, |
||||
'value' => $value, |
||||
'action' => $filter, |
||||
'displayField' => $displayField, |
||||
'displayValue' => $displayValue, |
||||
); |
||||
} |
||||
} |
||||
} |
||||
return $this->filters; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the limiters. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function limiters() |
||||
{ |
||||
$actions = array(); $ids = array(); |
||||
$filters = $this->filters(); |
||||
foreach($filters as $filter) { |
||||
$actions[] = $filter['action']; |
||||
$ids[] = $filter['field']; |
||||
} |
||||
|
||||
$limiters = isset($this->info['limiters']) ? $this->info['limiters'] : array(); |
||||
foreach($limiters as $key => $cluster) { |
||||
// multi select limiter |
||||
if (!empty($cluster['Values'])) { |
||||
foreach($cluster['Values'] as $limiter) { |
||||
$action = $limiter['Action']; |
||||
if (in_array($action, $actions)) { |
||||
$limiters[$key]['selected'][] = $limiter['Action']; |
||||
} |
||||
} |
||||
// date limiter |
||||
} else if ($cluster['Type'] == 'ymrange') { |
||||
$id = $cluster['Id']; |
||||
if (($k = array_search($id, $ids)) !== false) { |
||||
$limiters[$key]['selected'] = $filters[$k]['action']; |
||||
} |
||||
// other limiters |
||||
} else { |
||||
$action = str_replace('value', 'y', $cluster['Action']); |
||||
if (in_array($action, $actions)) { |
||||
$limiters[$key]['selected'] = true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
return $limiters; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the total number of records. |
||||
* |
||||
* @return integer |
||||
*/ |
||||
public function record_count() |
||||
{ |
||||
return !empty($this->results) ? $this->results['recordCount'] : 0; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the number of end record. |
||||
* |
||||
* @return integer |
||||
*/ |
||||
public function record_end() |
||||
{ |
||||
$count = !empty($this->results) ? count($this->results['documents']) : 0; |
||||
$start = !empty($this->results) ? $this->results['start'] : 0; |
||||
return $start + $count; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the number of start record. |
||||
* |
||||
* @return integer |
||||
*/ |
||||
public function record_start() |
||||
{ |
||||
return !empty($this->results) ? $this->results['start'] + 1 : 0; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the search time |
||||
* |
||||
* @return decimal number |
||||
*/ |
||||
public function search_time() |
||||
{ |
||||
return !empty($this->results) && |
||||
isset($this->results['searchTime']) ? $this->results['searchTime'] : 0; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the search view : basic or advanced |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function search_view() |
||||
{ |
||||
if (isset($_REQUEST['group'])) { |
||||
return 'advanced'; |
||||
} else { |
||||
return 'basic'; |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Hidden params used by UpdateForm |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function search_params() |
||||
{ |
||||
$params = $this->link_search_params(); |
||||
// filter the params that have same values as sidebar checkboxes, otherwise they will produce duplicates |
||||
$not_allowed_values = array( |
||||
'addexpander(thesaurus)', |
||||
'addexpander(fulltext)', |
||||
'addlimiter(FT:y)', |
||||
'addlimiter(RV:y)', |
||||
'addlimiter(SO:y)' |
||||
); |
||||
|
||||
$params = $this->array_filter_recursive($params, function($item) use($not_allowed_values) { |
||||
return !($item && in_array($item, $not_allowed_values)); |
||||
}); |
||||
|
||||
return array_filter($params); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Hidden params used by UpdateForm |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function link_search_params() |
||||
{ |
||||
// filter the page parameter |
||||
$not_allowed_keys = array('page', 'ui', 'has_js', 'op', 'submit', 'form_id', 'form_build_id'); |
||||
|
||||
$query=""; |
||||
if(isset($_SERVER['QUERY_STRING'])) |
||||
{$query = urldecode($_SERVER['QUERY_STRING']);} |
||||
parse_str($query, $params); |
||||
|
||||
$params = $this->array_unset_recursive($params, $not_allowed_keys); |
||||
|
||||
return $params; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Check if there are records in results array |
||||
* |
||||
** @return boolean |
||||
*/ |
||||
public function has_records() |
||||
{ |
||||
return !empty($this->results) && !empty($this->results['documents']); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Create the last search data |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function search_create($query = null) |
||||
{ |
||||
$last_search = array(); |
||||
if (!empty($this->results)) { |
||||
$results_identifiers = array(); |
||||
foreach($this->results['documents'] as $result) { |
||||
$results_identifiers[] = $result['id']; |
||||
} |
||||
$last_search['query'] = $query ? $query : $_SERVER['QUERY_STRING']; |
||||
$last_search['records'] = serialize($results_identifiers); |
||||
$last_search['count'] = $this->record_count(); |
||||
} |
||||
|
||||
return $last_search; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Save last search data in session |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function search_write($query = null) |
||||
{ |
||||
$_SESSION['EBSCO']['last-search'] = $this->search_create($query); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Load last search data from session |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function search_read($id = null, $op = null) |
||||
{ |
||||
$params = array(); |
||||
$lastSearch = $_SESSION['EBSCO']['last-search']; |
||||
if ($lastSearch) { |
||||
$lastSearch['records'] = unserialize($lastSearch['records']); |
||||
if ($id) { |
||||
parse_str($lastSearch['query'], $params); |
||||
$params['page'] = (int) (isset($params['page']) ? $params['page'] : 0); |
||||
$index = array_search($id, $lastSearch['records']); |
||||
|
||||
// if this is not the first scroll and if this is not a page refresh |
||||
if (isset($lastSearch['current']) && $lastSearch['current'] != $id) { |
||||
// if we change page |
||||
if (($op == 'Next' && $index % $this->limit === 0) || |
||||
($op == 'Previous' && $index % $this->limit === 9)) { |
||||
$params['page'] = ($op == 'Next') ? $params['page'] + 1 : $params['page'] - 1; |
||||
$query = drupal_http_build_query($params); |
||||
$lastSearch['query'] = $_SESSION['EBSCO']['last-search']['query'] = $query; |
||||
} |
||||
} |
||||
$start = $params['page']; |
||||
|
||||
if (count($lastSearch['records']) > 10) { |
||||
$records = array_slice($lastSearch['records'], $index - $index % $this->limit, $this->limit); |
||||
} else { |
||||
$records = $lastSearch['records']; |
||||
} |
||||
|
||||
if (!isset($lastSearch['records'][$index + 1])) { |
||||
$params['page'] += 1; |
||||
$driver = new EBSCODocument($params); |
||||
$driver->search(); |
||||
$query = drupal_http_build_query($params); |
||||
$newSearch = $driver->search_create($query); |
||||
$newSearch['records'] = unserialize($newSearch['records']); |
||||
$lastSearch['records'] = array_merge($lastSearch['records'], $newSearch['records']); |
||||
$_SESSION['EBSCO']['last-search']['records'] = serialize($lastSearch['records']); |
||||
if ($op == 'Next') { |
||||
$lastSearch['previous'] = isset($records[8]) ? $records[8] : ''; |
||||
} |
||||
$lastSearch['next'] = isset($newSearch['records'][0]) ? $newSearch['records'][0] : ''; |
||||
} else { |
||||
$lastSearch['next'] = $lastSearch['records'][$index + 1]; |
||||
} |
||||
|
||||
if (!isset($lastSearch['records'][$index - 1])) { |
||||
if ($params['page'] > 0) { |
||||
$params['page'] -= 1; |
||||
$driver = new EBSCODocument($params); |
||||
$driver->search(); |
||||
$query = drupal_http_build_query($params); |
||||
$newSearch = $driver->search_create($query); |
||||
$newSearch['records'] = unserialize($newSearch['records']); |
||||
$lastSearch['records'] = array_merge($lastSearch['records'], $newSearch['records']); |
||||
$_SESSION['EBSCO']['last-search']['records'] = serialize($lastSearch['records']); |
||||
$lastSearch['previous'] = isset($newSearch['records'][9]) ? $newSearch['records'][9] : ''; |
||||
if ($op == 'Previous') { |
||||
$lastSearch['next'] = isset($records[1]) ? $records[1] : ''; |
||||
} |
||||
} else { |
||||
$lastSearch['previous'] = ''; |
||||
} |
||||
} else { |
||||
$lastSearch['previous'] = $lastSearch['records'][$index - 1]; |
||||
} |
||||
|
||||
$lastSearch['current_index'] = $start * $this->limit + $index % $this->limit + 1; |
||||
$lastSearch['current'] = $id; |
||||
} |
||||
} |
||||
|
||||
$_SESSION['EBSCO']['last-search']['current'] = $id; |
||||
return $lastSearch; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* A recursive array_filter |
||||
* |
||||
* @return array |
||||
*/ |
||||
private function array_filter_recursive($input, $callback = null) |
||||
{ |
||||
foreach ($input as &$value) { |
||||
if (is_array($value)) { |
||||
$value = $this->array_filter_recursive($value, $callback); |
||||
} |
||||
} |
||||
return array_filter($input, $callback); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Recursive filter an array using the given $keys |
||||
* |
||||
* @return array |
||||
*/ |
||||
private function array_unset_recursive($input, $keys) { |
||||
foreach($keys as $key) { |
||||
if (isset($input[$key])) { |
||||
unset($input[$key]); |
||||
} |
||||
} |
||||
|
||||
if (is_array($input)) { |
||||
foreach ($input as $key => $value) { |
||||
$input[$key] = is_array($value) ? $this->array_unset_recursive($value, $keys) : $value; |
||||
} |
||||
} |
||||
|
||||
return array_filter($input); |
||||
} |
||||
} |
@ -0,0 +1,398 @@
|
||||
<?php |
||||
/** |
||||
* The EBSCO record object |
||||
* |
||||
* PHP version 5 |
||||
* |
||||
*/ |
||||
|
||||
class EBSCORecord |
||||
{ |
||||
/** |
||||
* The array of data |
||||
* @global array |
||||
*/ |
||||
private $data = array(); |
||||
|
||||
/** |
||||
* The result id (the EBSCO counter) of the record |
||||
* @global integer |
||||
*/ |
||||
public $result_id = null; |
||||
|
||||
/** |
||||
* The id of the record |
||||
* @global integer |
||||
*/ |
||||
public $record_id = null; |
||||
|
||||
/** |
||||
* The summary of the record. |
||||
* @global string |
||||
*/ |
||||
public $summary = null; |
||||
|
||||
/** |
||||
* The authors of the record. |
||||
* @global string |
||||
*/ |
||||
public $authors = null; |
||||
|
||||
/** |
||||
* The subjects of the record. |
||||
* @global string |
||||
*/ |
||||
public $subjects = null; |
||||
|
||||
/** |
||||
* The custom links provided for the record. |
||||
* @global array |
||||
*/ |
||||
public $custom_links = array(); |
||||
|
||||
/** |
||||
* The database label of the record. |
||||
* @global string |
||||
*/ |
||||
public $db_label = null; |
||||
|
||||
/** |
||||
* The full-text availability of the record. |
||||
* @global boolean |
||||
*/ |
||||
public $full_text_availability = null; |
||||
|
||||
/** |
||||
* The full text of the record. |
||||
* @global string |
||||
*/ |
||||
public $full_text = null; |
||||
|
||||
/** |
||||
* The PDF availability of the record. |
||||
* @global boolean |
||||
*/ |
||||
public $pdf_availability = null; |
||||
|
||||
/** |
||||
* The items of the record. |
||||
* @global array |
||||
*/ |
||||
public $items = array(); |
||||
|
||||
/** |
||||
* The external link of the record. |
||||
* @global string |
||||
*/ |
||||
public $p_link = null; |
||||
|
||||
/** |
||||
* The external link to the PDF version of the record. |
||||
* @global string |
||||
*/ |
||||
public $pdf_link = null; |
||||
|
||||
/** |
||||
* The publication type link of the record. |
||||
* @global string |
||||
*/ |
||||
public $publication_type = null; |
||||
|
||||
/** |
||||
* The external thumbnails links of the record. |
||||
* @global string |
||||
*/ |
||||
public $small_thumb_link = null; |
||||
public $medium_thumb_link = null; |
||||
|
||||
/** |
||||
* The title of the record. |
||||
* @global string |
||||
*/ |
||||
public $title = null; |
||||
|
||||
/** |
||||
* The source of the record. |
||||
* @global string |
||||
*/ |
||||
public $source = null; |
||||
|
||||
/** |
||||
* The access level of the record. |
||||
* @global string |
||||
*/ |
||||
public $access_level = null; |
||||
|
||||
|
||||
/** |
||||
* Constructor. |
||||
* |
||||
* @param array $data Raw data from the EBSCO search representing the record. |
||||
*/ |
||||
public function __construct($data = array()) |
||||
{ |
||||
$this->data = $data; |
||||
$this->record_id = $this->record_id(); |
||||
$this->result_id = $this->result_id(); |
||||
$this->title = $this->title(); |
||||
$this->summary = $this->summary(); |
||||
$this->authors = $this->authors(); |
||||
$this->subjects = $this->subjects(); |
||||
$this->custom_links = $this->custom_links(); |
||||
$this->db_label = $this->db_label(); |
||||
$this->full_text_availability = $this->full_text_availability(); |
||||
$this->full_text = $this->full_text(); |
||||
$this->items = $this->items(); |
||||
$this->p_link = $this->p_link(); |
||||
$this->publication_type = $this->publication_type(); |
||||
$this->pdf_availability = $this->pdf_availability(); |
||||
$this->pdf_link = $this->pdf_link(); |
||||
$this->small_thumb_link = $this->thumb_link(); |
||||
$this->medium_thumb_link = $this->thumb_link('medium'); |
||||
$this->source = $this->source(); |
||||
$this->access_level = $this->access_level(); |
||||
} |
||||
|
||||
|
||||
/******************************************************** |
||||
* |
||||
* Getters |
||||
* |
||||
********************************************************/ |
||||
|
||||
|
||||
/** |
||||
* Get the summary of the record. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function access_level() |
||||
{ |
||||
return isset($this->data['AccessLevel']) ? |
||||
$this->data['AccessLevel'] : ''; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the summary of the record. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function summary() |
||||
{ |
||||
return isset($this->data['Items']['Abstract']) ? |
||||
$this->data['Items']['Abstract']['Data'] : ''; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the authors of the record. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function authors() |
||||
{ |
||||
return isset($this->data['Items']['Author']) ? |
||||
$this->data['Items']['Author']['Data'] : ''; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the custom links of the record. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function custom_links() |
||||
{ |
||||
return isset($this->data['CustomLinks']) ? |
||||
$this->data['CustomLinks'] : array(); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the database label of the record. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function db_label() |
||||
{ |
||||
return isset($this->data['DbLabel']) ? |
||||
$this->data['DbLabel'] : ''; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the full text availability of the record. |
||||
* |
||||
* @return boolean |
||||
*/ |
||||
public function full_text() |
||||
{ |
||||
return isset($this->data['FullText']) && |
||||
isset($this->data['FullText']['Value']) ? $this->data['FullText']['Value'] : ''; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the full text availability of the record. |
||||
* |
||||
* @return boolean |
||||
*/ |
||||
public function full_text_availability() |
||||
{ |
||||
return isset($this->data['FullText']) && |
||||
$this->data['FullText']['Availability']; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the items of the record. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function items() |
||||
{ |
||||
return isset($this->data['Items']) ? $this->data['Items'] : array(); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the external url of the record. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function p_link() |
||||
{ |
||||
return isset($this->data['PLink']) ? $this->data['PLink'] : ''; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the publication type of the record. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function publication_type() |
||||
{ |
||||
return isset($this->data['PubType']) ? $this->data['PubType'] : ''; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the PDF availability of the record. |
||||
* |
||||
* @return boolean |
||||
*/ |
||||
public function pdf_availability() |
||||
{ |
||||
return isset($this->data['FullText']) && |
||||
isset($this->data['FullText']['Links']) && |
||||
isset($this->data['FullText']['Links']['pdflink']) && |
||||
$this->data['FullText']['Links']['pdflink']; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the PDF url of the record. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function pdf_link() |
||||
{ |
||||
return isset($this->data['FullText']) && |
||||
isset($this->data['FullText']['Links']) && |
||||
isset($this->data['FullText']['Links']['pdflink']) ? |
||||
$this->data['FullText']['Links']['pdflink'] : |
||||
''; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the result id of the record. |
||||
* |
||||
* @return integer |
||||
*/ |
||||
public function result_id() |
||||
{ |
||||
return isset($this->data['ResultId']) ? |
||||
$this->data['ResultId'] : ''; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the subject data of the record. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function subjects() |
||||
{ |
||||
return isset($this->data['Items']['Subject']) ? |
||||
$this->data['Items']['Subject']['Data'] : ''; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Return a URL to a thumbnail preview of the record, if available; false |
||||
* otherwise. |
||||
* |
||||
* @param string $size Size of thumbnail (small, medium or large -- small is |
||||
* default). |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function thumb_link($size = 'small') |
||||
{ |
||||
$imageInfo = isset($this->data['ImageInfo']) ? $this->data['ImageInfo'] : ''; |
||||
if ($imageInfo && isset($imageInfo['thumb'])) { |
||||
switch ($size) { |
||||
case 'large': |
||||
case 'medium': |
||||
return $imageInfo['medium']; |
||||
break; |
||||
|
||||
case 'small': |
||||
default: |
||||
return $imageInfo['thumb']; |
||||
break; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the title of the record. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function title() |
||||
{ |
||||
return isset($this->data['Items']['Title']) ? |
||||
$this->data['Items']['Title']['Data'] : ''; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the source of the record. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function source() |
||||
{ |
||||
return isset($this->data['Items']['TitleSource']) ? |
||||
$this->data['Items']['TitleSource']['Data'] : ''; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Return the identifier of this record within the EBSCO databases |
||||
* |
||||
* @return string Unique identifier. |
||||
*/ |
||||
public function record_id() |
||||
{ |
||||
return isset($this->data['id']) ? |
||||
$this->data['id'] : ''; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,547 @@
|
||||
<?php |
||||
|
||||
|
||||
/** |
||||
* EBSCO Response class |
||||
* |
||||
* PHP version 5 |
||||
* |
||||
*/ |
||||
|
||||
require_once 'sanitizer.class.php'; |
||||
|
||||
|
||||
/** |
||||
* EBSCOResponse class |
||||
*/ |
||||
class EBSCOResponse |
||||
{ |
||||
|
||||
/** |
||||
* A SimpleXml object |
||||
* @global object |
||||
*/ |
||||
private $response; |
||||
|
||||
|
||||
/** |
||||
* Constructor |
||||
* |
||||
* Sets up the EBSCO Response |
||||
* |
||||
* @param none |
||||
* |
||||
* @access public |
||||
*/ |
||||
public function __construct($response) |
||||
{ |
||||
$this->response = $response; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Returns the XML as an associative array of data |
||||
* |
||||
* @param none |
||||
* |
||||
* @return array An associative array of data |
||||
* @access public |
||||
*/ |
||||
public function result() |
||||
{ |
||||
if (!empty($this->response->AuthToken)) { |
||||
return $this->buildAuthenticationToken(); |
||||
} else if (!empty($this->response->SessionToken)) { |
||||
return (string) $this->response->SessionToken; |
||||
} 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(); |
||||
} else { // Should not happen, it may be an exception |
||||
return $this->response; |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 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 |
||||
); |
||||
|
||||
return $result; |
||||
} |
||||
|
||||
/** |
||||
* Parse a SimpleXml object and |
||||
* return it as an associative array |
||||
* |
||||
* @param none |
||||
* |
||||
* @return array An associative array of data |
||||
* @access private |
||||
*/ |
||||
private function buildSearch() |
||||
{ |
||||
$hits = (integer) $this->response->SearchResult->Statistics->TotalHits; |
||||
$searchTime = (integer) $this->response->SearchResult->Statistics->TotalSearchTime / 1000; |
||||
$records = array(); |
||||
$facets = array(); |
||||
if ($hits > 0) { |
||||
$records = $this->buildRecords(); |
||||
$facets = $this->buildFacets(); |
||||
} |
||||
|
||||
$results = array( |
||||
'recordCount' => $hits, |
||||
'searchTime' => $searchTime, |
||||
'numFound' => $hits, |
||||
'start' => 0, |
||||
'documents' => $records, |
||||
'facets' => $facets |
||||
); |
||||
|
||||
return $results; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Parse a SimpleXml object and |
||||
* return it as an associative array |
||||
* |
||||
* @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['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['PubType'] = $record->Header->PubType ? (string) $record->Header->PubType : ''; |
||||
$result['AccessLevel'] = $record->Header->AccessLevel ? (string) $record->Header->AccessLevel : ''; |
||||
$result['id'] = $result['An'] . '|' . $result['DbId']; |
||||
$result['PLink'] = $record->PLink ? (string) $record->PLink : ''; |
||||
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'] = ''; |
||||
} |
||||
|
||||
if ($record->FullText) { |
||||
$availability = (integer) $record->FullText->Text->Availability == 1; |
||||
$links = array(); |
||||
//RF 2012-12-18 |
||||
if (isset($record->FullText->Links)) |
||||
{ |
||||
foreach ($record->FullText->Links->Link as $link) { |
||||
$type = (string) $link->Type; |
||||
$url = (string) $link->Url; |
||||
// If we have an empty url when type is pdflink then just return something so |
||||
// that the UI check for empty string will pass. |
||||
$url = empty($url) && $type == 'pdflink' ? 'http://content.ebscohost.com' : $url; |
||||
$links[$type] = $url; |
||||
} |
||||
} |
||||
$result['FullText'] = array( |
||||
'Availability' => $availability, |
||||
'Links' => $links |
||||
); |
||||
} |
||||
|
||||
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->Items) { |
||||
$result['Items'] = array(); |
||||
foreach ($record->Items->Item as $item) { |
||||
$name = $item->Name ? (string) $item->Name : ''; |
||||
$label = $item->Label ? (string) $item->Label : ''; |
||||
$group = $item->Group ? (string) $item->Group : ''; |
||||
$data = $item->Data ? (string) $item->Data : ''; |
||||
$result['Items'][$name] = array( |
||||
'Name' => $name, |
||||
'Label' => $label, |
||||
'Group' => $group, |
||||
'Data' => $this->toHTML($data, $group) |
||||
); |
||||
} |
||||
} |
||||
|
||||
$results[] = $result; |
||||
} |
||||
|
||||
return $results; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Parse a SimpleXml object and |
||||
* return it as an associative array |
||||
* |
||||
* @param none |
||||
* |
||||
* @return array An associative array of data |
||||
* @access private |
||||
*/ |
||||
private function buildFacets() |
||||
{ |
||||
$results = array(); |
||||
|
||||
$facets = $this->response->SearchResult->AvailableFacets->AvailableFacet; |
||||
foreach ($facets as $facet) { |
||||
$values = array(); |
||||
foreach ($facet->AvailableFacetValues->AvailableFacetValue as $value) { |
||||
$this_value = (string) $value->Value; |
||||
$this_value = str_replace(array('\(','\)'), array('(', ')'), $this_value); |
||||
$this_action = (string) $value->AddAction; |
||||
$this_action = str_replace(array('\(','\)'), array('(', ')'), $this_action); |
||||
$values[] = array( |
||||
'Value' => $this_value, |
||||
'Action' => $this_action, |
||||
'Count' => (string) $value->Count |
||||
); |
||||
} |
||||
$id = (string) $facet->Id; |
||||
$label = (string) $facet->Label; |
||||
if (!empty($label)) { |
||||
$results[] = array( |
||||
'Id' => $id, |
||||
'Label' => $label, |
||||
'Values' => $values, |
||||
'isApplied' => false |
||||
); |
||||
} |
||||
} |
||||
|
||||
return $results; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Parse a SimpleXml object and |
||||
* return it as an associative array |
||||
* |
||||
* @param none |
||||
* |
||||
* @return array An associative array of data |
||||
* @access private |
||||
*/ |
||||
private function buildInfo() |
||||
{ |
||||
// Sort options |
||||
$elements = $this->response->AvailableSearchCriteria->AvailableSorts->AvailableSort; |
||||
$sort = array(); |
||||
foreach ($elements as $element) { |
||||
$sort[] = array( |
||||
'Id' => (string) $element->Id, |
||||
'Label' => (string) $element->Label, |
||||
'Action' => (string) $element->AddAction |
||||
); |
||||
} |
||||
|
||||
// Search fields |
||||
$elements = $this->response->AvailableSearchCriteria->AvailableSearchFields->AvailableSearchField; |
||||
$tags = array(); |
||||
foreach ($elements as $element) { |
||||
$tags[] = array( |
||||
'Label' => (string) $element->Label, |
||||
'Code' => (string) $element->FieldCode |
||||
); |
||||
} |
||||
|
||||
// Expanders |
||||
$elements = $this->response->AvailableSearchCriteria->AvailableExpanders->AvailableExpander; |
||||
$expanders = array(); |
||||
foreach ($elements as $element) { |
||||
$expanders[] = array( |
||||
'Id' => (string) $element->Id, |
||||
'Label' => (string) $element->Label, |
||||
'Action' => (string) $element->AddAction, |
||||
'selected' => false // Added because of the checkboxes |
||||
); |
||||
} |
||||
|
||||
// Limiters |
||||
$elements = $this->response->AvailableSearchCriteria->AvailableLimiters->AvailableLimiter; |
||||
$limiters = array(); |
||||
$values = array(); |
||||
foreach ($elements as $element) { |
||||
if ($element->LimiterValues) { |
||||
$items = $element->LimiterValues->LimiterValue; |
||||
foreach($items as $item) { |
||||
$values[] = array( |
||||
'Value' => (string) $item->Value, |
||||
'Action' => (string) $item->AddAction, |
||||
'selected' => false // Added because of the checkboxes |
||||
); |
||||
} |
||||
} |
||||
$limiters[] = array( |
||||
'Id' => (string) $element->Id, |
||||
'Label' => (string) $element->Label, |
||||
'Action' => (string) $element->AddAction, |
||||
'Type' => (string) $element->Type, |
||||
'Values' => $values, |
||||
'selected' => false |
||||
); |
||||
} |
||||
|
||||
$result = array( |
||||
'sort' => $sort, |
||||
'tags' => $tags, |
||||
'expanders' => $expanders, |
||||
'limiters' => $limiters |
||||
); |
||||
|
||||
return $result; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Parse a SimpleXml object and |
||||
* return it as an associative array |
||||
* |
||||
* @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['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['id'] = $result['An'] . '|' . $result['DbId']; |
||||
$result['PubType'] = $record->Header->PubType ? (string) $record->Header->PubType : ''; |
||||
$result['AccessLevel'] = $record->Header->AccessLevel ? (string) $record->Header->AccessLevel : ''; |
||||
$result['PLink'] = $record->PLink ? (string) $record->PLink : ''; |
||||
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'] = ''; |
||||
} |
||||
if ($record->FullText) { |
||||
$availability = (integer) ($record->FullText->Text->Availability) == 1; |
||||
$links = array(); |
||||
foreach ($record->FullText->Links->Link as $link) { |
||||
$type = (string) $link->Type; |
||||
$url = (string) $link->Url; |
||||
// If we have an empty url when type is pdflink then just return something so |
||||
// that the UI check for empty string will pass. |
||||
$url = empty($url) && $type == 'pdflink' ? 'http://content.ebscohost.com' : $url; |
||||
$links[$type] = $url; |
||||
} |
||||
$value = $this->toHTML($record->FullText->Text->Value); |
||||
$result['FullText'] = array( |
||||
'Availability' => $availability, |
||||
'Links' => $links, |
||||
'Value' => $value |
||||
); |
||||
} |
||||
|
||||
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->Items) { |
||||
$result['Items'] = array(); |
||||
foreach ($record->Items->Item as $item) { |
||||
$name = $item->Name ? (string) $item->Name : ''; |
||||
$label = $item->Label ? (string) $item->Label : ''; |
||||
$group = $item->Group ? (string) $item->Group : ''; |
||||
$data = $item->Data ? (string) $item->Data : ''; |
||||
$result['Items'][$name] = array( |
||||
'Name' => $name, |
||||
'Label' => $label, |
||||
'Group' => $group, |
||||
'Data' => $this->toHTML($data, $group) |
||||
); |
||||
} |
||||
} |
||||
|
||||
return $result; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Parse a SimpleXml element and |
||||
* return it's inner XML as an HTML string |
||||
* |
||||
* @param SimpleXml $element A SimpleXml DOM |
||||
* |
||||
* @return string The HTML string |
||||
* @access protected |
||||
*/ |
||||
private function toHTML($data, $group = null) |
||||
{ |
||||
// 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'); |
||||
|
||||
// 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' => '<p class="aug"', |
||||
'</aug' => '</p', |
||||
'<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' |
||||
); |
||||
|
||||
// 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)) { |
||||
$group = strtolower($group); |
||||
if (in_array($group, $allowed_searchlink_groups)) { |
||||
$type = $xml_to_search_types[$group]; |
||||
$path = url('ebsco/results', array('query' => array('type' => $type))); |
||||
$link_xml = '/<searchLink fieldCode="([^\"]*)" term="%22([^\"]*)%22">/'; |
||||
$link_html = "<a href=\"{$path}&lookfor=$2\">"; |
||||
$data = preg_replace($link_xml, $link_html, $data); |
||||
$data = str_replace('</searchLink>', '</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); |
||||
} |
||||
|
||||
$sanitizer = new HTML_Sanitizer; |
||||
$data = $sanitizer->sanitize($data); |
||||
|
||||
return $data; |
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
?> |
@ -0,0 +1,444 @@
|
||||
<?php // $Id$
|
||||
|
||||
// vim: expandtab sw=4 ts=4 sts=4: |
||||
|
||||
# ***** BEGIN LICENSE BLOCK ***** |
||||
# This file is part of HTML Sanitizer. |
||||
# Copyright (c) 2005-2011 Frederic Minne <zefredz@gmail.com>. |
||||
# All rights reserved. |
||||
# |
||||
# HTML Sanitizer is free software; you can redistribute it and/or modify |
||||
# it under the terms of the GNU Lesser General Public License as published by |
||||
# the Free Software Foundation; either version 3 of the License, or |
||||
# (at your option) any later version. |
||||
# |
||||
# HTML Sanitizer 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 Lesser General Public License |
||||
# along with HTML Sanitizer; if not, see <http://www.gnu.org/licenses/>. |
||||
# |
||||
# ***** END LICENSE BLOCK ***** |
||||
|
||||
/** |
||||
* Sanitize HTML contents : |
||||
* Remove dangerous tags and attributes that can lead to security issues like |
||||
* XSS or HTTP response splitting |
||||
* |
||||
* @author Frederic Minne <zefredz@gmail.com> |
||||
* @copyright Copyright © 2005-2011, Frederic Minne |
||||
* @license http://www.gnu.org/licenses/lgpl.txt GNU Lesser General Public License version 3 or later |
||||
* @version 1.1 |
||||
*/ |
||||
class HTML_Sanitizer |
||||
{ |
||||
// Private fields |
||||
private $_allowedTags; |
||||
private $_allowJavascriptEvents; |
||||
private $_allowJavascriptInUrls; |
||||
private $_allowObjects; |
||||
private $_allowScript; |
||||
private $_allowStyle; |
||||
private $_additionalTags; |
||||
|
||||
/** |
||||
* Constructor |
||||
*/ |
||||
public function __construct() |
||||
{ |
||||
$this->resetAll(); |
||||
} |
||||
|
||||
/** |
||||
* (re)set all options to default value |
||||
*/ |
||||
public function resetAll() |
||||
{ |
||||
$this->_allowDOMEvents = false; |
||||
$this->_allowJavascriptInUrls = false; |
||||
$this->_allowStyle = false; |
||||
$this->_allowScript = false; |
||||
$this->_allowObjects = false; |
||||
$this->_allowStyle = false; |
||||
|
||||
$this->_allowedTags = '<a><br><b><h1><h2><h3><h4><h5><h6>' |
||||
. '<img><li><ol><p><strong><table><tr><td><th><u><ul><thead>' |
||||
. '<tbody><tfoot><em><dd><dt><dl><span><div><del><add><i><hr>' |
||||
. '<pre><br><blockquote><address><code><caption><abbr><acronym>' |
||||
. '<cite><dfn><q><ins><sup><sub><kbd><samp><var><tt><small><big>' |
||||
; |
||||
|
||||
$this->_additionalTags = ''; |
||||
} |
||||
|
||||
/** |
||||
* Add additional tags to allowed tags |
||||
* @param string |
||||
* @access public |
||||
*/ |
||||
public function addAdditionalTags( $tags ) |
||||
{ |
||||
$this->_additionalTags .= $tags; |
||||
} |
||||
|
||||
/** |
||||
* Allow iframes |
||||
* @access public |
||||
*/ |
||||
public function allowIframes() |
||||
{ |
||||
$this->addAdditionalTags( '<iframe>' ); |
||||
} |
||||
|
||||
/** |
||||
* Allow HTML5 media tags |
||||
* @access public |
||||
*/ |
||||
public function allowHtml5Media() |
||||
{ |
||||
$this->addAdditionalTags( '<canvas><video><audio>' ); |
||||
} |
||||
|
||||
/** |
||||
* Allow object, embed, applet and param tags in html |
||||
* @access public |
||||
*/ |
||||
public function allowObjects() |
||||
{ |
||||
$this->_allowObjects = true; |
||||
} |
||||
|
||||
/** |
||||
* Allow DOM event on DOM elements |
||||
* @access public |
||||
*/ |
||||
public function allowDOMEvents() |
||||
{ |
||||
$this->_allowDOMEvents = true; |
||||
} |
||||
|
||||
/** |
||||
* Allow script tags |
||||
* @access public |
||||
*/ |
||||
public function allowScript() |
||||
{ |
||||
$this->_allowScript = true; |
||||
} |
||||
|
||||
/** |
||||
* Allow the use of javascript: in urls |
||||
* @access public |
||||
*/ |
||||
public function allowJavascriptInUrls() |
||||
{ |
||||
$this->_allowJavascriptInUrls = true; |
||||
} |
||||
|
||||
/** |
||||
* Allow style tags and attributes |
||||
* @access public |
||||
*/ |
||||
public function allowStyle() |
||||
{ |
||||
$this->_allowStyle = true; |
||||
} |
||||
|
||||
/** |
||||
* Helper to allow all javascript related tags and attributes |
||||
* @access public |
||||
*/ |
||||
public function allowAllJavascript() |
||||
{ |
||||
$this->allowDOMEvents(); |
||||
$this->allowScript(); |
||||
$this->allowJavascriptInUrls(); |
||||
} |
||||
|
||||
/** |
||||
* Allow all tags and attributes |
||||
* @access public |
||||
*/ |
||||
public function allowAll() |
||||
{ |
||||
$this->allowAllJavascript(); |
||||
$this->allowObjects(); |
||||
$this->allowStyle(); |
||||
$this->allowIframes(); |
||||
$this->allowHtml5Media(); |
||||
} |
||||
|
||||
/** |
||||
* Filter URLs to avoid HTTP response splitting attacks |
||||
* @access public |
||||
* @param string url |
||||
* @return string filtered url |
||||
*/ |
||||
public function filterHTTPResponseSplitting( $url ) |
||||
{ |
||||
$dangerousCharactersPattern = '~(\r\n|\r|\n|%0a|%0d|%0D|%0A)~'; |
||||
return preg_replace( $dangerousCharactersPattern, '', $url ); |
||||
} |
||||
|
||||
/** |
||||
* Remove potential javascript in urls |
||||
* @access public |
||||
* @param string url |
||||
* @return string filtered url |
||||
*/ |
||||
public function removeJavascriptURL( $str ) |
||||
{ |
||||
$HTML_Sanitizer_stripJavascriptURL = 'javascript:[^"]+'; |
||||
|
||||
$str = preg_replace("/$HTML_Sanitizer_stripJavascriptURL/i" |
||||
, '__forbidden__' |
||||
, $str ); |
||||
|
||||
return $str; |
||||
} |
||||
|
||||
/** |
||||
* Remove potential flaws in urls |
||||
* @access private |
||||
* @param string url |
||||
* @return string filtered url |
||||
*/ |
||||
private function sanitizeURL( $url ) |
||||
{ |
||||
if ( ! $this->_allowJavascriptInUrls ) |
||||
{ |
||||
$url = $this->removeJavascriptURL( $url ); |
||||
} |
||||
|
||||
$url = $this->filterHTTPResponseSplitting( $url ); |
||||
|
||||
return $url; |
||||
} |
||||
|
||||
/** |
||||
* Callback for PCRE |
||||
* @access private |
||||
* @param matches array |
||||
* @return string |
||||
* @see sanitizeURL |
||||
*/ |
||||
private function _sanitizeURLCallback( $matches ) |
||||
{ |
||||
return 'href="'.$this->sanitizeURL( $matches[1] ).'"'; |
||||
} |
||||
|
||||
/** |
||||
* Remove potential flaws in href attributes |
||||
* @access private |
||||
* @param string html tag |
||||
* @return string filtered html tag |
||||
*/ |
||||
private function sanitizeHref( $str ) |
||||
{ |
||||
$HTML_Sanitizer_URL = 'href="([^"]+)"'; |
||||
|
||||
return preg_replace_callback("/$HTML_Sanitizer_URL/i" |
||||
, array( &$this, '_sanitizeURLCallback' ) |
||||
, $str ); |
||||
} |
||||
|
||||
/** |
||||
* Callback for PCRE |
||||
* @access private |
||||
* @param matches array |
||||
* @return string |
||||
* @see sanitizeURL |
||||
*/ |
||||
private function _sanitizeSrcCallback( $matches ) |
||||
{ |
||||
return 'src="'.$this->sanitizeURL( $matches[1] ).'"'; |
||||
} |
||||
|
||||
/** |
||||
* Remove potential flaws in href attributes |
||||
* @access private |
||||
* @param string html tag |
||||
* @return string filtered html tag |
||||
*/ |
||||
private function sanitizeSrc( $str ) |
||||
{ |
||||
$HTML_Sanitizer_URL = 'src="([^"]+)"'; |
||||
|
||||
return preg_replace_callback("/$HTML_Sanitizer_URL/i" |
||||
, array( &$this, '_sanitizeSrcCallback' ) |
||||
, $str ); |
||||
} |
||||
|
||||
/** |
||||
* Remove dangerous attributes from html tags |
||||
* @access private |
||||
* @param string html tag |
||||
* @return string filtered html tag |
||||
*/ |
||||
private function removeEvilAttributes( $str ) |
||||
{ |
||||
if ( ! $this->_allowDOMEvents ) |
||||
{ |
||||
$str = preg_replace_callback('/<(.*?)>/i' |
||||
, array( &$this, '_removeDOMEventsCallback' ) |
||||
, $str ); |
||||
} |
||||
|
||||
if ( ! $this->_allowStyle ) |
||||
{ |
||||
$str = preg_replace_callback('/<(.*?)>/i' |
||||
, array( &$this, '_removeStyleCallback' ) |
||||
, $str ); |
||||
} |
||||
|
||||
return $str; |
||||
} |
||||
|
||||
/** |
||||
* Remove DOM events attributes from html tags |
||||
* @access private |
||||
* @param string html tag |
||||
* @return string filtered html tag |
||||
*/ |
||||
private function removeDOMEvents( $str ) |
||||
{ |
||||
$str = preg_replace ( '/\s*=\s*/', '=', $str ); |
||||
|
||||
$HTML_Sanitizer_stripAttrib = '(onclick|ondblclick|onmousedown|' |
||||
. 'onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|' |
||||
. 'onkeyup|onfocus|onblur|onabort|onerror|onload)' |
||||
; |
||||
|
||||
$str = stripslashes( preg_replace("/$HTML_Sanitizer_stripAttrib/i" |
||||
, 'forbidden' |
||||
, $str ) ); |
||||
|
||||
return $str; |
||||
} |
||||
|
||||
/** |
||||
* Callback for PCRE |
||||
* @access private |
||||
* @param matches array |
||||
* @return string |
||||
* @see removeDOMEvents |
||||
*/ |
||||
private function _removeDOMEventsCallback( $matches ) |
||||
{ |
||||
return '<' . $this->removeDOMEvents( $matches[1] ) . '>'; |
||||
} |
||||
|
||||
/** |
||||
* Remove style attributes from html tags |
||||
* @access private |
||||
* @param string html tag |
||||
* @return string filtered html tag |
||||
*/ |
||||
private function removeStyle( $str ) |
||||
{ |
||||
$str = preg_replace ( '/\s*=\s*/', '=', $str ); |
||||
|
||||
$HTML_Sanitizer_stripAttrib = '(style)' |
||||
; |
||||
|
||||
$str = stripslashes( preg_replace("/$HTML_Sanitizer_stripAttrib/i" |
||||
, 'forbidden' |
||||
, $str ) ); |
||||
|
||||
return $str; |
||||
} |
||||
|
||||
/** |
||||
* Callback for PCRE |
||||
* @access private |
||||
* @param matches array |
||||
* @return string |
||||
* @see removeStyle |
||||
*/ |
||||
private function _removeStyleCallback( $matches ) |
||||
{ |
||||
return '<' . $this->removeStyle( $matches[1] ) . '>'; |
||||
} |
||||
|
||||
/** |
||||
* Remove dangerous HTML tags |
||||
* @access private |
||||
* @param string html code |
||||
* @return string filtered url |
||||
*/ |
||||
private function removeEvilTags( $str ) |
||||
{ |
||||
$allowedTags = $this->_allowedTags; |
||||
|
||||
if ( $this->_allowScript ) |
||||
{ |
||||
$allowedTags .= '<script>'; |
||||
} |
||||
|
||||
if ( $this->_allowStyle ) |
||||
{ |
||||
$allowedTags .= '<style>'; |
||||
} |
||||
|
||||
if ( $this->_allowObjects ) |
||||
{ |
||||
$allowedTags .= '<object><embed><applet><param>'; |
||||
} |
||||
|
||||
$allowedTags .= $this->_additionalTags; |
||||
|
||||
$str = strip_tags($str, $allowedTags ); |
||||
|
||||
return $str; |
||||
} |
||||
|
||||
/** |
||||
* Sanitize HTML |
||||
* remove dangerous tags and attributes |
||||
* clean urls |
||||
* @access public |
||||
* @param string html code |
||||
* @return string sanitized html code |
||||
*/ |
||||
public function sanitize( $html ) |
||||
{ |
||||
$html = $this->removeEvilTags( $html ); |
||||
|
||||
$html = $this->removeEvilAttributes( $html ); |
||||
|
||||
$html = $this->sanitizeHref( $html ); |
||||
|
||||
$html = $this->sanitizeSrc( $html ); |
||||
|
||||
return $html; |
||||
} |
||||
} |
||||
|
||||
function html_sanitize( $str ) |
||||
{ |
||||
static $san = null; |
||||
|
||||
if ( empty( $san ) ) |
||||
{ |
||||
$san = new HTML_Sanitizer; |
||||
} |
||||
|
||||
return $san->sanitize( $str ); |
||||
} |
||||
|
||||
function html_loose_sanitize( $str ) |
||||
{ |
||||
static $san = null; |
||||
|
||||
if ( empty( $san ) ) |
||||
{ |
||||
$san = new HTML_Sanitizer; |
||||
$san->allowAll(); |
||||
} |
||||
|
||||
return $san->sanitize( $str ); |
||||
|
||||
} |
||||
|
@ -0,0 +1,44 @@
|
||||
<?php |
||||
|
||||
/** |
||||
* @file |
||||
* Displays the advanced search form. |
||||
* |
||||
* @see template_preprocess_ebsco_advanced_search() |
||||
*/ |
||||
?> |
||||
|
||||
<div class="container-inline ebsco-advanced"> |
||||
<?php print $search_form; ?> |
||||
</div> |
||||
|
||||
<div class="offscreen" id="advanced-row-template"> |
||||
<fieldset id="edit-groupNN" class="form-wrapper _advanced-row"> |
||||
<div class="fieldset-wrapper"> |
||||
<div class="form-item form-type-select form-item-groupNN-bool"> |
||||
<select id="ebsco-advanced-search-boolNN" name="groupNN[bool]" class="form-select"> |
||||
<option value="AND" selected="selected">All terms</option> |
||||
<option value="OR">Any terms</option> |
||||
<option value="NOT">No terms</option> |
||||
</select> |
||||
</div> |
||||
<div class="form-item form-type-textfield form-item-groupNN-lookfor"> |
||||
<input title="Enter the terms you wish to search for." type="text" id="ebsco-advanced-search-lookforNN" name="groupNN[lookfor]" value="" size="30" maxlength="128" class="form-text" /> |
||||
</div> |
||||
<div class="form-item form-type-select form-item-groupNN-type"> |
||||
<label for="ebsco-advanced-search-type1">in</label> |
||||
<select id="ebsco-advanced-search-typeNN" name="groupNN[type]" class="form-select"> |
||||
<option value="AllFields" selected="selected">All Text</option> |
||||
<option value="Title">Title</option> |
||||
<option value="Author">Author</option> |
||||
<option value="Subject">Subject terms</option> |
||||
</select> |
||||
</div> |
||||
<div class="delete-search"> |
||||
<a href="#" class="delete _delete_row" id="delete_search_link_NN"> |
||||
<?php print t('Remove Search Field'); ?> |
||||
</a> |
||||
</div> |
||||
</div> |
||||
</fieldset> |
||||
</div> |
@ -0,0 +1,27 @@
|
||||
<?php |
||||
|
||||
/** |
||||
* @file |
||||
* Displays the basic search form block. |
||||
* |
||||
* @see template_preprocess_ebsco_basic_search() |
||||
*/ |
||||
?> |
||||
|
||||
<div class="container-inline"> |
||||
<?php if ($search_view == 'basic'): ?> |
||||
<?php print $search_form; ?> |
||||
<?php elseif ($search_view == 'advanced'): ?> |
||||
<a href="<?php print url('ebsco/advanced', array('query' => array('edit' => 1))); ?>" class="small">
|
||||
<?php print t('Edit this Advanced Search'); ?> |
||||
</a> | |
||||
<a href="<?php print url('ebsco/advanced'); ?>" class="small">
|
||||
<?php print t('Start a new Advanced Search'); ?> |
||||
</a> | |
||||
<a href="<?php print url('ebsco/results'); ?>" class="small">
|
||||
<?php print t('Start a new Basic Search'); ?> |
||||
</a> |
||||
<br/> |
||||
<?php print t('Your search terms'); ?> : <strong><?php print check_plain($lookfor); ?></strong>
|
||||
<?php endif; ?> |
||||
</div> |
@ -0,0 +1,134 @@
|
||||
<?php |
||||
|
||||
/** |
||||
* @file |
||||
* Default theme implementation for displaying an EBSCO result. |
||||
* |
||||
* @see template_preprocess_ebsco_result() |
||||
*/ |
||||
?> |
||||
|
||||
<?php if ($record): ?> |
||||
|
||||
<?php |
||||
$id = check_plain($record->record_id()); |
||||
$fulltextUrl = url('ebsco/fulltext', array('query' => array('id' => $id))); |
||||
$pdfUrl = url('ebsco/pdf', array('query' => array('id' => $id))); |
||||
?> |
||||
|
||||
<div class="ebsco-record"> |
||||
<h1><?php print $record->title; ?></h1>
|
||||
|
||||
<div class="record-toolbar"> |
||||
<?php if ($last_search): ?> |
||||
<div class="floatright"> |
||||
<?php if ($last_search['previous']): ?> |
||||
<a href="<?php print url('ebsco/result', array('query' => array('id' => $last_search['previous'], 'op' => 'Previous'))); ?>" class="_record_link">
|
||||
« <?php print t('Previous'); ?> |
||||
</a> |
||||
<?php endif; ?> |
||||
#<?php print $last_search['current_index']; ?> of <?php print $last_search['count']; ?> |
||||
<?php if ($last_search['next']): ?> |
||||
<a href="<?php print url('ebsco/result', array('query' => array('id' => $last_search['next'], 'op' => 'Next'))); ?>" class="_record_link">
|
||||
<?php print t('Next'); ?> »
|
||||
</a> |
||||
<?php endif; ?> |
||||
</div> |
||||
<div class="floatleft"> |
||||
<a href="<?php print "?{$last_search['query']}"; ?>">
|
||||
« <?php print t('Back to Results list'); ?> |
||||
</a> |
||||
</div> |
||||
<div class="clear"></div> |
||||
<?php endif; ?> |
||||
</div> |
||||
|
||||
<div class="span-5"> |
||||
<ul class="external-links"> |
||||
<?php if($record->p_link): ?> |
||||
<li> |
||||
<a href="<?php print $record->p_link; ?>">
|
||||
<?php print t('View in EDS'); ?> |
||||
</a> |
||||
</li> |
||||
<?php endif; ?> |
||||
<?php if ($record->pdf_link): ?> |
||||
<li> |
||||
<a href="<?php print $pdfUrl; ?>" class="icon pdf fulltext">
|
||||
<?php print t('PDF full text'); ?> |
||||
</a> |
||||
</li> |
||||
<?php endif; ?> |
||||
<?php if ($record->full_text_availability): ?> |
||||
<li> |
||||
<a href="<?php if (!user_is_logged_in()) { print $fulltextUrl; } ?>#html" class="icon html fulltext">
|
||||
<?php print t('HTML full text'); ?> |
||||
</a> |
||||
</li> |
||||
<?php endif; ?> |
||||
<?php if (!empty($record->custom_links)): ?> |
||||
<?php foreach ($record->custom_links as $link): ?> |
||||
<li> |
||||
<a href="<?php print $link['Url']; ?>" target="_blank" title="<?php print $link['MouseOverText']; ?>" class="external-link">
|
||||
<?php if ($link['Icon']): ?><img src="<?php print $link['Icon']?>" /><?php endif; ?><?php print $link['Name']; ?> |
||||
</a> |
||||
</li> |
||||
<?php endforeach; ?> |
||||
<?php endif; ?> |
||||
</ul> |
||||
</div> |
||||
|
||||
<div class="span-13"> |
||||
<table cellpadding="2" cellspacing="0" border="0" class="citation" summary="<?php print t('Bibliographic Details'); ?>">
|
||||
<?php foreach ($record->items as $item): ?> |
||||
<?php if (!empty($item['Data'])): ?> |
||||
<tr valign="top"> |
||||
<th width="150"><?php print t($item['Label']); ?>:</th>
|
||||
<td><?php print auto_link($item['Data']); ?></td>
|
||||
</tr> |
||||
<?php endif; ?> |
||||
<?php endforeach; ?> |
||||
|
||||
<?php if ($record->db_label): ?> |
||||
<tr valign="top"> |
||||
<th width="150"><?php print t('Database'); ?>:</th>
|
||||
<td><?php print check_plain($record->db_label); ?></td>
|
||||
</tr> |
||||
<?php endif; ?> |
||||
|
||||
<?php if ($record->full_text): ?> |
||||
<tr id="html" valign="top"> |
||||
<td colspan="2" class="html"> |
||||
<?php print $record->full_text; ?> |
||||
</td> |
||||
</tr> |
||||
<?php elseif ($record->access_level && !user_is_logged_in()): ?> |
||||
<tr id="html" valign="top"> |
||||
<td colspan="2" class="html"> |
||||
<p> |
||||
<?php print t('The full text cannot be displayed to guests.'); ?> |
||||
<br /> |
||||
<?php $link = '<a href="' . url('user') . '">' . t('Login') . '</a>'; ?> |
||||
<strong><?php print sprintf(t('%s for full access.'), $link); ?></strong>
|
||||
</p> |
||||
</td> |
||||
</tr> |
||||
<?php endif; ?> |
||||
</table> |
||||
</div> |
||||
|
||||
<div class="span-4"> |
||||
<?php if ($record->medium_thumb_link): ?> |
||||
<img src="<?php print check_url($record->medium_thumb_link); ?>" class="book-jacket" alt="<?php print t('Book jacket')?>"/>
|
||||
<?php endif; ?> |
||||
<?php if ($record->publication_type): ?> |
||||
<p><?php print check_plain($record->publication_type); ?></p>
|
||||
<?php endif; ?> |
||||
</div> |
||||
|
||||
<div class="clear"></div> |
||||
|
||||
</div> |
||||
<?php endif; ?> |
||||
|
||||
<div id="spinner" class="spinner"></div> |
@ -0,0 +1,143 @@
|
||||
<?php |
||||
|
||||
/** |
||||
* @file |
||||
* Default theme implementation for displaying EBSCO results. |
||||
* |
||||
* @see template_preprocess_ebsco_results() |
||||
*/ |
||||
?> |
||||
|
||||
<?php if ($records): ?> |
||||
|
||||
<?php print t('Showing'); ?> |
||||
<strong><?php print $record_start; ?></strong> - <strong><?php print $record_end; ?></strong>
|
||||
<?php print t('of'); ?> <strong><?php print $record_count; ?></strong>
|
||||
<?php if ($search_view == 'basic'): ?> |
||||
<?php print t('for search')?>: <strong>'<?php print check_plain($lookfor); ?>'</strong>
|
||||
<?php endif; ?> |
||||
<?php if ($search_time): ?> |
||||
, <?php print t('query time'); ?>: <?php print check_plain(round($search_time, 2)); ?>s
|
||||
<?php endif; ?> |
||||
|
||||
<?php print $sort_form; ?> |
||||
<?php print $pager; ?> |
||||
|
||||
<?php if (!user_is_logged_in()): ?> |
||||
<?php $link = '<a href="' . url('user') . '">' . t('Login') . '</a>'; ?> |
||||
<p class="top-login-message"> |
||||
<?php print sprintf(t('Hello, Guest. %s for full access.'), $link); ?> |
||||
</p> |
||||
<?php endif; ?> |
||||
|
||||
<ol class="search-results ebsco"> |
||||
<?php foreach ($records as $record): ?> |
||||
<?php |
||||
$id = check_plain($record->record_id()); |
||||
$recordUrl = url('ebsco/result', array('query' => array('id' => $id))); |
||||
$fulltextUrl = url('ebsco/fulltext', array('query' => array('id' => $id))); |
||||
$pdfUrl = url('ebsco/pdf', array('query' => array('id' => $id))); |
||||
?> |
||||
<li> |
||||
<div class="record-number floatleft"> |
||||
<?php print $record->result_id; ?> |
||||
</div> |
||||
|
||||
<div class="result floatleft"> |
||||
<div class="span-2"> |
||||
<?php if ($record->small_thumb_link): ?> |
||||
<a href="<?php print $recordUrl; ?>" class="_record_link">
|
||||
<img src="<?php print $record->small_thumb_link; ?>" class="book-jacket" alt="<?php print t('Book jacket'); ?>"/>
|
||||
</a> |
||||
<?php endif; ?> |
||||
</div> |
||||
|
||||
<div class="span-9"> |
||||
<div class="result-line1"> |
||||
<?php if ($record->access_level == '1'): ?> |
||||
<p> |
||||
<?php |
||||
$label = '<strong>' . check_plain($record->db_label) . '</strong>'; |
||||
$link = '<a href="' . url('user') . '">' . t('Login') . '</a>'; |
||||
?> |
||||
<?php print sprintf(t('This result from %s cannot be displayed to guests.'), $label); ?> |
||||
<br /> |
||||
<strong><?php print sprintf(t('%s for full access.'), $link); ?></strong>
|
||||
</p> |
||||
<?php elseif ($record->title): ?> |
||||
<a href="<?php print $recordUrl; ?>" class="title _record_link">
|
||||
<?php print $record->title; ?> |
||||
</a> |
||||
<?php endif; ?> |
||||
</div> |
||||
|
||||
<div class="result-line2"> |
||||
<?php if (!empty($record->authors)): ?> |
||||
<p> |
||||
<?php print t('by'); ?> |
||||
<?php print $record->authors; ?> |
||||
</p> |
||||
<?php endif; ?> |
||||
|
||||
<?php if (!empty($record->source)): ?> |
||||
<p> |
||||
<?php print t('Published in'); ?> |
||||
<?php print $record->source; ?> |
||||
</p> |
||||
<?php endif; ?> |
||||
</div> |
||||
|
||||
<div class="result-line3"> |
||||
<?php if (!empty($record->summary)): ?> |
||||
<cite><?php print $record->summary; ?></cite>
|
||||
<br /> |
||||
<?php endif; ?> |
||||
|
||||
<?php if (!empty($record->subjects)): ?> |
||||
<strong><?php print t('Subjects'); ?></strong>:
|
||||
<span class="quotestart"><?php print str_replace('<br />', ', ', $record->subjects); ?></span>
|
||||
<?php endif; ?> |
||||
</div> |
||||
|
||||
<?php if (!empty($record->custom_links)): ?> |
||||
<div class="result-line4"> |
||||
<ul class="custom-links"> |
||||
<?php foreach ($record->custom_links as $link): ?> |
||||
<li> |
||||
<a href="<?php print $link['Url']; ?>" target="_blank" title="<?php print $link['MouseOverText']; ?>" class="external-link">
|
||||
<?php if ($link['Icon']): ?><img src="<?php print $link['Icon']?>" /><?php endif; ?><?php print $link['Name']; ?> |
||||
</a> |
||||
</li> |
||||
<?php endforeach; ?> |
||||
</ul> |
||||
</div> |
||||
<?php endif; ?> |
||||
|
||||
<div class="result-line5"> |
||||
<?php if ($record->full_text_availability): ?> |
||||
<a href="<?php print $fulltextUrl; ?>#html" class="icon html fulltext _record_link">
|
||||
<?php print t('HTML full text'); ?> |
||||
</a> |
||||
|
||||
<?php endif; ?> |
||||
|
||||
<?php if ($record->pdf_availability): ?> |
||||
<a href="<?php print $pdfUrl; ?>" class="icon pdf fulltext">
|
||||
<?php print t('PDF full text'); ?> |
||||
</a> |
||||
<?php endif; ?> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div class="clear"></div> |
||||
</li> |
||||
<?php endforeach; ?> |
||||
</ol> |
||||
<?php print $pager; ?> |
||||
|
||||
<?php elseif (!empty($lookfor)) : ?> |
||||
<h2><?php print t('Your search did not match any resources.');?></h2>
|
||||
<?php print search_help('search#noresults', drupal_help_arg()); ?> |
||||
<?php endif; ?> |
||||
|
||||
<div id="spinner" class="spinner"></div> |
@ -0,0 +1,149 @@
|
||||
<?php |
||||
|
||||
/** |
||||
* @file |
||||
* Display the sidebar block with facets filters |
||||
* |
||||
* @see template_preprocess_ebsco_side_facets() |
||||
*/ |
||||
?> |
||||
|
||||
<?php |
||||
$limiters = array_slice($limiters, 0, 3); |
||||
?> |
||||
|
||||
<div class="sidegroup"> |
||||
<?php if ($record_count >= 0): ?> |
||||
<h2><?php print t('Narrow Search')?></h2>
|
||||
<form name="updateForm" action="<?php print url('ebsco/results'); ?>" method="get">
|
||||
<?php if ($search_params): ?> |
||||
<span> |
||||
<?php foreach($search_params as $k1 => $v1): ?> |
||||
<?php if (is_array($v1)): ?> |
||||
<?php foreach($v1 as $k2 => $v2): ?> |
||||
<?php if (is_array($v2)): ?> |
||||
<?php foreach($v2 as $k3 => $v3): ?> |
||||
<input type="hidden" name="<?php print $k1; ?>[<?php print $k2; ?>][<?php print $k3; ?>]" value="<?php print check_plain($v3); ?>" />
|
||||
<?php endforeach; ?> |
||||
<?php else: ?> |
||||
<input type="hidden" name="<?php print $k1; ?>[<?php print $k2; ?>]" value="<?php print check_plain($v2); ?>" />
|
||||
<?php endif; ?> |
||||
<?php endforeach; ?> |
||||
<?php else: ?> |
||||
<input type="hidden" name="<?php print $k1; ?>" value="<?php print check_plain($v1); ?>" />
|
||||
<?php endif; ?> |
||||
<?php endforeach; ?> |
||||
</span> |
||||
<?php endif; ?> |
||||
|
||||
<?php if (!empty($filters)): ?> |
||||
<dl class="narrow-list navmenu filters"> |
||||
<dt><?php print t('Remove Filters'); ?></dt>
|
||||
<?php foreach ($filters as $filter): ?> |
||||
<?php |
||||
$removeLink = remove_filter_link($filter); |
||||
?> |
||||
<dd> |
||||
<a href="<?php print $removeLink; ?>" class="icon13 expanded">
|
||||
<?php print t($filter['displayField']); ?>: <?php print t($filter['displayValue']); ?> |
||||
</a> |
||||
</dd> |
||||
<?php endforeach; ?> |
||||
</dl> |
||||
<?php endif; ?> |
||||
|
||||
<dl class="narrow-list navmenu"> |
||||
<dt><?php print t('Limit Results'); ?></dt>
|
||||
<?php foreach ($limiters as $limiter): ?> |
||||
<dd> |
||||
<?php if ($limiter['Type'] == 'multiselectvalue'): ?> |
||||
<label for="<?php print check_plain($limiter['Id']); ?>">
|
||||
<?php print t($limiter['Label']); ?> |
||||
</label><br /> |
||||
<select name="filter[]" multiple="multiple" id="<?php print check_plain($limiter['Id']); ?>">
|
||||
<option value=""><?php print t('All'); ?></option>
|
||||
<?php foreach ($limiter['Values'] as $option): ?> |
||||
<option value="<?php print check_plain($option['Action']); ?>"<?php $option['selected'] ? ' selected="selected"' : ''; ?>>
|
||||
<?php print check_plain($option['Value']); ?> |
||||
</option> |
||||
<?php endforeach; ?> |
||||
</select> |
||||
<?php else: ?> |
||||
<input type="checkbox" name="filter[]" value="<?php print check_plain(str_replace('value', 'y', $limiter['Action'])); ?>"
|
||||
<?php print $limiter['selected'] ? ' checked="checked"' : ''; ?> id="<?php print check_plain($limiter['Id']); ?>"
|
||||
/> |
||||
<label for="<?php print check_plain($limiter['Id']); ?>">
|
||||
<?php print check_plain(t($limiter['Label'])); ?> |
||||
</label> |
||||
<?php endif; ?> |
||||
</dd> |
||||
<?php endforeach; ?> |
||||
</dl> |
||||
|
||||
<dl class="narrow-list navmenu"> |
||||
<?php if ($expanders): ?> |
||||
<dt><?php print t('Expand Results'); ?></dt>
|
||||
<?php endif; ?> |
||||
|
||||
<?php foreach($expanders as $expander): ?> |
||||
<dd> |
||||
<input type="checkbox" name="filter[]" value="<?php print check_plain($expander['Action']); ?>"
|
||||
<?php print $expander['selected'] ? ' checked="checked"' : ''; ?> id="<?php print check_plain($expander['Id']); ?>"
|
||||
/> |
||||
<label for="<?php print check_plain($expander['Id']); ?>">
|
||||
<?php print check_plain(t($expander['Label'])); ?> |
||||
</label> |
||||
</dd> |
||||
<?php endforeach; ?> |
||||
|
||||
<dd class="submit"> |
||||
<input type="submit" name="submit" class="form-submit" value="<?php print t('Update'); ?>" />
|
||||
</dd> |
||||
</dl> |
||||
|
||||
<?php if (!empty($facets)): ?> |
||||
<?php foreach ($facets as $title => $cluster): ?> |
||||
<dl id="facet-<?php print check_plain(t($title)); ?>" class="narrow-list navmenu expandable">
|
||||
<dt> |
||||
<span class="icon13 collapsed"> |
||||
<?php print check_plain(t($cluster['Label'])); ?> |
||||
</span> |
||||
</dt> |
||||
</dl> |
||||
|
||||
<dl class="narrow-list navmenu offscreen" id="narrowGroupHidden_<?php print check_plain($title); ?>">
|
||||
<?php foreach ($cluster['Values'] as $index => $facet): ?> |
||||
<?php if ($facet['applied']): ?> |
||||
<dd> |
||||
<?php print check_plain($facet['Value']); ?> |
||||
<span class="icon16 tick"></span> |
||||
</dd> |
||||
<?php else: ?> |
||||
<dd> |
||||
<input type="checkbox" name="filter[]" value="<?php print check_plain($facet['Action']); ?>"
|
||||
id="filter<?php print check_plain($index); ?>"
|
||||
/> |
||||
<label for="filter<?php print check_plain($index); ?>">
|
||||
<a href="<?php print url('ebsco/results', array('query' => array_merge($link_search_params, array('filter[]' => $facet['Action'])))); ?>">
|
||||
<?php print check_plain($facet['Value']); ?> |
||||
</a> |
||||
(<?php print check_plain($facet['Count']); ?>)
|
||||
</label> |
||||
</dd> |
||||
<?php endif; ?> |
||||
<?php endforeach; ?> |
||||
|
||||
<dd> |
||||
<p class="submit"> |
||||
<input type="submit" class="form-submit" name="submit" value="<?php print t('Update'); ?>" />
|
||||
</p> |
||||
<a href="javascript:void(0)" class="expandable"> |
||||
<?php print t('Less'); ?> ...
|
||||
</a> |
||||
</dd> |
||||
</dl> |
||||
<?php endforeach; ?> |
||||
<?php endif; ?> |
||||
</form> |
||||
<?php endif; ?> |
||||
</div> |
Loading…
Reference in new issue