Last active
August 29, 2015 14:15
-
-
Save mjlassila/98dc2bdc4d6dc0880221 to your computer and use it in GitHub Desktop.
Local modifications for VoyagerRestful Finna/Vufind -driver
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- For including in RecordDrivers/Index/holdings.tpl --> | |
{if $row.order_update_date} | |
<tr> | |
<td class="copyTitle">{translate text="Order information"}: </td> | |
<td colspan="4"> | |
{translate text=$row.order_status|escape} | |
{$row.order_update_date|escape} | |
</td> | |
</tr> | |
{/if} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- START of modified: RecordDrivers/Index/holdings.tpl --> | |
<div class="holdingsHeader clearfix"> | |
{if is_array($recordFormat)} | |
{assign var=format value=$recordFormat.0} | |
{else} | |
{assign var=format value=$recordFormat} | |
{/if} | |
<div class="holdingsHoldingURLs"> | |
{if (!empty($holdingURLs) || $holdingsOpenURL)} | |
<h5>{translate text="available_online"}</h5> | |
<ul class="holdingsOnline"> | |
{if !empty($holdingURLs)} | |
{foreach from=$holdingURLs item=desc key=currentUrl name=loop} | |
<li><a href="{$currentUrl|proxify|escape}" target="_blank">{$desc|translate_prefix:'link_'|escape}</a></li> | |
{/foreach} | |
{/if} | |
{if $holdingsOpenURL} | |
{include file="Search/openurl.tpl" openUrl=$holdingsOpenURL} | |
{/if} | |
</ul> | |
{/if} | |
</div> | |
<div class="holdingsHeaderLinks"> | |
{if $id|substr:0:7 == 'helmet.'} | |
<span class="native_link"> | |
<a href="http://haku.helmet.fi/iii/encore/record/C|R{$id|substr:7|escape}" target="_blank">{translate text='Holdings details from'} HelMet</a><br/> | |
</span> | |
{/if} | |
</div> | |
{if $patronFunctions} | |
<div class="holdingsPlaceHold"> | |
{assign var="ublink" value=false} | |
{foreach from=$holdings item=holding} | |
{if !$ublink} | |
{foreach from=$holding item=row} | |
{if !$ublink && $row.UBRequestLink} | |
<a class="UBRequestPlace checkUBRequest button buttonFinna" href="{$row.UBRequestLink|escape}"><span>{translate text="ub_request_check"}</span></a> | |
{assign var="ublink" value=true} | |
{/if} | |
{/foreach} | |
{/if} | |
{/foreach} | |
{if !$hideLogin && $offlineMode != "ils-offline"} | |
{if ($driverMode && !empty($holdings)) || $titleDriverMode} | |
{if $showLoginMsg || $showTitleLoginMsg} | |
{translate text="hold_login"} <a class="button buttonFinna" href="{$path}/MyResearch/Home?followup=true&followupModule=Record&followupAction={$id|escape}">{translate text="Login"}</a> | |
{/if} | |
{if count($catalogAccounts) > 1} | |
{include file="MyResearch/select-card.tpl"} | |
{/if} | |
{if $user && !$user->cat_username} | |
<a class="button buttonFinna" href="{$path}/MyResearch/Profile">{translate text="Add an account to place holds"}</a> | |
{/if} | |
{/if} | |
{/if} | |
{if $holdingTitleHold && $holdingTitleHold != 'block'} | |
<a class="button buttonFinna holdPlace" href="{$holdingTitleHold|escape}">{translate text="title_hold_place"}</a> | |
{/if} | |
{if $catalogAccounts && !$ublink && !$holdingTitleHold} | |
<span>{translate text="title_cant_place_hold"}</span> | |
{/if} | |
{if $holdingTitleHold == 'block'} | |
{translate text="hold_error_blocked"} | |
{/if} | |
</div> | |
{/if} | |
</div> | |
{if $driver != 'AxiellWebServices'} | |
<div class="holdingsContainerHeader"> | |
{if $coreMergedRecordData.dedup_data} | |
<div class="menuHolder"> | |
<select id="dedupRecordHoldingsMenu" name="deduprecordHoldingsMenu" class="dropdown jumpMenuURL"> | |
{foreach from=$coreMergedRecordData.dedup_data key=source item=dedupData name=loop} | |
<option value="{$url}/Record/{$dedupData.id|escape:"url"}#holdingstab"{if $dedupData.id == $id} selected="selected"{/if}>{translate text=$source prefix='source_'}</option> | |
{/foreach} | |
</select> | |
</div> | |
{else} | |
<h5>{translate text=$source prefix='source_'}</h5> | |
{/if} | |
</div> | |
<div class="holdingsContainer clearfix driver-{$driver}"> | |
{if !$holdings} | |
<h5>{translate text="No holdings information available"}</h5> | |
{else} | |
<div> | |
{* Display link to access rights for records from fennica, viola and vaari *} | |
{if $coreSource == 'fennica' || $coreSource == 'viola' || $coreSource == 'vaari'} | |
<p class="accessRights"><a href=" | |
{if $coreSource == 'fennica' || $coreSource == 'viola'}{if $userLang == 'fi'}http://www.kansalliskirjasto.fi/kokoelmatjapalvelut/lainaus/kansalliskokoelmankaytosta.html{elseif $userLang == 'sv'}http://www.nationalbiblioteket.fi/tjanster/lainaus/kansalliskokoelmankaytosta.html{else}http://www.nationallibrary.fi/services/lainaus/kansalliskokoelmankaytosta.html{/if} | |
{elseif $coreSource == 'vaari'}http://www.varastokirjasto.fi/{if $userLang == 'fi'}kaukolainaus/varastokirjaston-palvelut-henkiloasiakkaille/{elseif $userLang == 'sv'}utlaning/service-for-privatkunder/{else}loans-and-requests/ill-services-for-private-customers/{/if} | |
{/if} | |
" target="_blank">{translate text="Record access rights"}</a></p> | |
{/if} | |
</div> | |
{/if} | |
{foreach from=$holdings item=holding key=location name=holdings} | |
{assign var=prevGroupId value=''} | |
{assign var="copyCount" value="0"} | |
{foreach from=$holding item=row name=items} | |
{assign var="itemsIteration" value=$smarty.foreach.items.iteration} | |
{if isset($row.mfhd_id)} | |
{assign var="holdingsGroupId" value=$row.mfhd_id} | |
{else} | |
{if isset($row.callnumber)} | |
{assign var="holdingsGroupId" value=$row.callnumber|replace:'.':'_'} | |
{else} | |
{assign var="holdingsGroupId" value=$location|replace:'.':'_'} | |
{/if} | |
{/if} | |
{if $prevGroupId != $holdingsGroupId} | |
{assign var="showCopyTitle" value=1} | |
{if $prevGroupId} | |
<tr class="avail"><td>{$availCount}</td></tr> | |
</table> | |
{/if} | |
{assign var=prevGroupId value=$holdingsGroupId} | |
<table class="holdingsContainerHolding {if $smarty.foreach.items.first && $smarty.foreach.holdings.iteration <=5}active{/if}" id="holding_{$prevGroupId}_{$itemsIteration}" cellpadding="2" cellspacing="0" border="0" class="citation" summary="{translate text='Holdings details from'} {translate text=$location}"> | |
<tr class="holdingsContainerHeading"> | |
<th colspan="2" class="location"><span class="arrowIndicator"></span>{$location|translate|escape}</th> | |
<th colspan="2" class="holdingDetails"> | |
<span class="availability">{translate text="Available"}</span> | |
</th> | |
<th class="locationLink"> | |
{if $locationServiceUrl} | |
<a class="openLocationService" href="{$locationServiceUrl}&callno={$row.callnumber|escape:'url'}"> | |
{$row.callnumber|truncate:21:"...":true|escape}</a><a class="openLocationServiceQR" href="{$locationServiceUrl}&callno={$row.callnumber|escape:'url'}"><i class="icon-qrcode"></i></a> | |
{else} | |
{$row.callnumber|escape} | |
{/if} | |
</th> | |
</tr> | |
<tr class="mobileLocation"> | |
<td colspan="5" class="locationLink"> | |
{if $locationServiceUrl} | |
<a class="openLocationService" href="{$locationServiceUrl}&callno={$row.callnumber|escape:'url'}"> | |
{$row.callnumber|truncate:21:"..."|escape}</a><a class="openLocationServiceQR" href="{$locationServiceUrl}&callno={$row.callnumber|escape:'url'}"><i class="icon-qrcode"></i></a> | |
{else} | |
{$row.callnumber|escape} | |
{/if} | |
</td> | |
</tr> | |
{assign var="availCount" value=0} | |
{if $row.summary} | |
<tr class="rowSummary format-{$format}"> | |
<td class="copyTitle">{translate text="Volume Holdings"}: </td> | |
<td colspan="4"> | |
{foreach from=$row.summary item=summary} | |
{$summary|replace:'((':'('|replace:'))':')'|escape}<br> | |
{/foreach} | |
</td> | |
</tr> | |
{/if} | |
{if $row.purchase_history} | |
<tr> | |
<td class="copyTitle">{translate text="Most Recent Received Issues"}: </td> | |
<td colspan="4"> | |
{foreach from=$row.purchase_history item=data} | |
{$data.issue|escape}<br> | |
{/foreach} | |
</td> | |
</tr> | |
{/if} | |
{if $row.notes} | |
<tr> | |
<td class="copyTitle">{translate text="Notes"}: </td> | |
<td colspan="4"> | |
{foreach from=$row.notes item=data} | |
{$data|escape}<br> | |
{/foreach} | |
</td> | |
</tr> | |
{/if} | |
{if $row.order_update_date} | |
<tr class="orderinfo"> | |
<td class="copyTitle">{translate text="Order information"}: </td> | |
<td colspan="4"> | |
{translate text=$row.order_status|escape} | |
{$row.order_update_date|escape} | |
</td> | |
</tr> | |
{/if} | |
{if $row.supplements} | |
<tr> | |
<td class="copyTitle">{translate text="Supplements"}: </td> | |
<td colspan="4"> | |
{foreach from=$row.supplements item=supplement} | |
{$supplement|escape}<br> | |
{/foreach} | |
</td> | |
</tr> | |
{/if} | |
{if $row.indexes} | |
<tr> | |
<td class="copyTitle">{translate text="Indexes"}: </td> | |
<td colspan="4"> | |
{foreach from=$row.indexes item=index} | |
{$index|escape}<br> | |
{/foreach} | |
</td> | |
</tr> | |
{/if} | |
{/if} | |
{if $row.item_id} | |
{if $copyCount == 12}<tr class="toggleCopyDetails"><td class="copyTitle"></td><td colspan="2"><strong><a href="#">{translate text="More Results"}</a></strong></td></tr>{/if} | |
<tr class="copyDetails {if $showCopyTitle}{counter start=0 assign=copyCount}first{/if} {if $copyCount >= 12}hidden{/if}"> | |
{counter assign=copyCount} | |
{if $showCopyTitle}<td class="copyTitle">{translate text="Copies"}{assign var="showCopyTitle" value=0}</td> | |
{else}<td></td>{/if} | |
<td class="copyNumber"> | |
{if $row.itemSummary} | |
{$row.itemSummary} | |
{else} | |
{if $row.number|trim == false}{translate text="Copy"}{/if} | |
{$row.number|escape} | |
{/if} | |
</td> | |
<td colspan="3" class="copyInfo"> | |
{if $row.reserve == "Y"} | |
{translate text="On Reserve - Ask at Circulation Desk"} | |
{elseif $row.use_unknown_message} | |
<span class="unknown">{translate text="status_unknown_message"}</span> | |
{else} | |
{if $patronFunctions} | |
{if $row.availability} | |
{assign var=availCount value=$availCount+1} | |
{* Begin Available Items (Holds) *} | |
<span class="available">{translate text="Available"}</span> | |
{if $row.link} | |
<a class="holdPlace{if $row.check} checkRequest{/if}" href="{$row.link|escape}"><span>{if !$row.check}{translate text="Place a Hold"}{else}{translate text="Check Hold"}{/if}</span></a> | |
{/if} | |
{if $row.callSlipLink} | |
<a class="callSlipPlace{if $row.checkCallSlip} checkCallSlipRequest{/if}" href="{$row.callSlipLink|escape}"><span>{if !$row.checkCallSlip}{translate text="call_slip_place_text"}{else}{translate text="Check Call Slip Request"}{/if}</span></a> | |
{/if} | |
{else} | |
{* Begin Unavailable Items (Recalls) *} | |
{if is_null($row.availability)} | |
<span class="availabilityUnknown" data-status="{$row.status}">{translate text=$row.status prefix='status_'}</span> | |
{else} | |
<span class="checkedout">{translate text=$row.status prefix='status_'}</span> | |
{/if} | |
{if $row.returnDate} <span class="statusExtra"><span class="returnDate">{$row.returnDate|escape}</span></span> | |
{/if} | |
{if $row.duedate} | |
{* N.B. The "returnDate duedate" classes on the next line are needed for the JS below to work properly *} | |
<span class="statusExtra">{translate text="Due"}: <span class="returnDate duedate">{$row.duedate|escape}</span></span> | |
{/if} | |
{if $row.requests_placed > 0} | |
<span>{translate text="Requests"}: {$row.requests_placed|escape}</span> | |
{/if} | |
{if $row.link} | |
<a class="holdPlace{if $row.check} checkRequest{/if}" href="{$row.link|escape}"><span>{if !$row.check}{translate text="Recall This"}{else}{translate text="Check Recall"}{/if}</span></a> | |
{/if} | |
{/if} | |
{/if} | |
{/if} | |
</td> | |
</tr> | |
{/if} | |
{/foreach} | |
<tr class="avail"><td>{$availCount}</td></tr> | |
</table> | |
{/foreach} | |
</div> | |
{else} | |
<div class="holdingsContainerHeader"> | |
<h5>{translate text=$source prefix='source_'} | |
{if $holdings} | |
<div class="holdRequestTotals"> | |
<span class="requestCount">{translate text="Request queue"}: {$requestCount}</span> | |
<span class="holdCount">{translate text="Total number of items"}: {$holdCount}</span> | |
</div> | |
{/if} | |
</h5> | |
</div> | |
<div class="holdingsContainer clearfix driver-{$driver}"> | |
{if !$holdings} | |
<h5>{translate text="No holdings information available"}</h5> | |
{else} | |
<div> | |
{* Display link to access rights for records from fennica, viola and vaari *} | |
{if $coreSource == 'fennica' || $coreSource == 'viola' || $coreSource == 'vaari'} | |
<p class="accessRights"><a href=" | |
{if $coreSource == 'fennica' || $coreSource == 'viola'}{if $userLang == 'fi'}http://www.kansalliskirjasto.fi/kokoelmatjapalvelut/lainaus/kansalliskokoelmankaytosta.html{elseif $userLang == 'sv'}http://www.nationalbiblioteket.fi/tjanster/lainaus/kansalliskokoelmankaytosta.html{else}http://www.nationallibrary.fi/services/lainaus/kansalliskokoelmankaytosta.html{/if} | |
{elseif $coreSource == 'vaari'}http://www.varastokirjasto.fi/{if $userLang == 'fi'}kaukolainaus/varastokirjaston-palvelut-henkiloasiakkaille/{elseif $userLang == 'sv'}utlaning/service-for-privatkunder/{else}loans-and-requests/ill-services-for-private-customers/{/if} | |
{/if} | |
" target="_blank">{translate text="Record access rights"}</a></p> | |
{/if} | |
</div> | |
{/if} | |
{foreach from=$holdings item=location name=locations} | |
{if $location.0.status.text == "Available"} | |
{assign var="availableLoc" value="1"} | |
{else} | |
{assign var="availableLoc" value="0"} | |
{/if} | |
{assign var="status" value=$location.0.status.text} | |
<table class="holdingsContainerHolding {if $smarty.foreach.locations.first}active{/if}"> | |
<tr class="holdingsContainerHeading"> | |
<th class="location" colspan="2"><span class="arrowIndicator"></span>{$location.0.title}</th> | |
<th class="holdingDetails" colspan="2"> | |
<span class="availability {if $availableLoc || $location.0.status.text=="On Reference Desk"}available{else}checkedout{/if}"> | |
{if $availableLoc} | |
{translate text="axiell_available_from"} {$location.0.status.availableCount} {translate text="axiell_branches"} | |
{elseif $status=="Closest due"} | |
{translate text=$status} {$location.0.status.closestDueDate} | |
{else} | |
{translate text="status_`$status`"} | |
{/if} | |
</span> | |
</th> | |
<th class="locationLink">{$location.0.callnumber} | |
{if $location.0.journal && $location.0.is_holdable && $user && $user->cat_username && $location.0.reservableIdLink} | |
{if $holdingTitleHold != 'block'} | |
<a class="button buttonFinna holdPlace" href="{$location.0.reservableIdLink|escape}">{translate text="title_hold_place"}</a> | |
{elseif $holdingTitleHold == 'block'} | |
{translate text="hold_error_blocked"} | |
{/if} | |
{/if} | |
</th> | |
</tr> | |
{foreach from=$location.0.holdings item=holding name=holding} | |
<tr class="copyDetails {if $smarty.foreach.holding.first}first{/if}"> | |
{if $smarty.foreach.holding.first} | |
<td class="copyTitle">{translate text="Library unit"}</td> | |
{else} | |
<td></td> | |
{/if} | |
<td class="copyNumber">{if $location.0.journal}{$holding.organisation}, {/if}{$holding.branch}, {$holding.department}{if $holding.location}, {$holding.location}{/if}</td> | |
<td class="copyInfo" colspan="2"> | |
<span class="{if $holding.availability || $holding.status=="On Reference Desk"}available{else}checkedout{/if}"> | |
{if $holding.availability} | |
{capture assign="avail" name="avail"}{translate text="axiell_available"}{/capture}{$avail|@ucfirst} | |
{else} | |
{translate text="status_`$holding.status`"} | |
{/if} | |
</span> | |
{if $holding.duedate != '' && !$holding.availability} | |
<span class="statusExtra">{translate text="Due Date"}: <span class="returnDate">{$holding.duedate}</span></span> | |
{elseif $holding.ordered > 0} | |
<span class="statusExtra">{translate text="status_Ordered"}: {$holding.ordered}</span> | |
{/if} | |
</td> | |
<td class="availableOfTotal">{translate text="Available items"}: {$holding.available} / {$holding.total}</td> | |
</tr> | |
{/foreach} | |
</table> | |
{/foreach} | |
</div> | |
{/if} | |
{literal} | |
<script type="text/javascript"> | |
$(document).ready(function() { | |
// IE8 compatible Date.now() | |
Date.now = Date.now || function() { return +new Date; }; | |
/* Open volume details by clicking on the heading */ | |
$('.holdingsContainerHeading').click(function() { | |
$(this).closest('table').toggleClass('active'); | |
}) | |
/* Show more/less copy information */ | |
$('.toggleCopyDetails a').click(function(e) { | |
e.preventDefault(); | |
$(this).toggleClass('active'); | |
var $parentTr = $(this).closest('tr'), | |
$copyDetails = $parentTr.siblings('.copyDetails'), | |
openText = '{/literal}{translate text="More Results"}{literal}', | |
closeText = '{/literal}{translate text="Fewer Results"}{literal}'; | |
// Change .hidden to .visible | |
$copyDetails.each(function() { | |
if ($(this).is('.hidden')) { | |
$(this).removeClass('hidden').addClass('visible'); | |
} else if ($(this).is('.visible')) { | |
$(this).removeClass('visible').addClass('hidden'); | |
} | |
}); | |
// Move the toggler and change its content accordingly | |
if ($(this).is('.active')) { | |
$(this).text(closeText); | |
$parentTr.insertAfter($copyDetails.last()); | |
} else { | |
$(this).text(openText); | |
} | |
}); | |
{/literal}{if $driver != 'AxiellWebServices'}{literal} | |
/* Show copy details in the heading */ | |
$('.holdingsContainerHolding').each(function() { | |
var availableCount = $(this).find('.avail td').text(); | |
var orderinfoCount = $(this).find('.orderinfo').length; | |
$headingAvail = $(this).find('.holdingsContainerHeading .availability'); | |
iBlock = {'display': 'inline-block'}, | |
msg = '{/literal}{translate text="status_No_status_information"}{literal}', | |
in_order = '{/literal}{translate text="status_In Process"}{literal}' | |
due = '{/literal}{translate text="Closest due"}{literal}'; | |
/* If there are available copies, show the number */ | |
if (availableCount > 0) { | |
$headingAvail.addClass('available'); | |
$headingAvail.text(availableCount + ' ' + $headingAvail.text().toLowerCase()).show(); | |
} | |
else { /* If no available copies, get return dates */ | |
var prevDate, firstDate, firstDateText; | |
$(this).find('.copyDetails .returnDate.duedate').each(function() { | |
var returnDateSplit = $(this).text().split('.'); /* Split the date and build it anew */ | |
var returnDate = new Date(returnDateSplit[2], returnDateSplit[1] - 1, returnDateSplit[0]); | |
if (typeof prevDate == 'undefined' || returnDate < prevDate) { | |
firstDate = returnDate; /* Get the closest date to today */ | |
} | |
prevDate = firstDate; | |
}) | |
/* If a return date exists */ | |
if (typeof firstDate != 'undefined') { | |
var $dateTarget = $(this).find('.holdingDetails .returnDate'); | |
$headingAvail.addClass('checkedout').text(due + ' ' + ' ' + firstDate.getDate() + '.' + | |
(firstDate.getMonth() + 1) + '.' +firstDate.getFullYear()).css(iBlock); | |
} else { /* Without a date, only show the checkedout message */ | |
var uniqueStatuses = []; | |
var fullStatus = ''; | |
$(this).find('.checkedout').each(function(index, elem) { | |
var status = $(elem).text(); | |
if ((jQuery.inArray(status, uniqueStatuses)) == -1) { | |
uniqueStatuses.push(status); | |
fullStatus += status + ' '; | |
} | |
}); | |
if (fullStatus !== '') { | |
$headingAvail.addClass('checkedout').text(fullStatus).css(iBlock); | |
} | |
if (orderinfoCount >=1) { /* If no message found, print the default one */ | |
$headingAvail.addClass('unknown').text(in_order).css(iBlock); | |
} | |
else { /* If no message found, print the default one */ | |
$headingAvail.addClass('unknown').text(msg).css(iBlock); | |
} | |
} | |
} | |
}); | |
{/literal}{/if}{literal} | |
$('a.holdPlace,a.callSlipPlace,a.UBRequestPlace').click(function() { | |
var id = {/literal}'{$id}'{literal}; | |
var href = $(this).attr('href'); | |
var hashPos = href.indexOf('#'); | |
if (hashPos >= 0) { | |
href = href.substring(0, hashPos); | |
} | |
var $dialog = getPageInLightbox(href + '&lightbox=1', $(this).text(), 'Record', '', id); | |
return false; | |
}); | |
createDropdowns(); | |
initDropdowns(); | |
initJumpMenus(); | |
}); | |
</script> | |
{/literal} | |
<!-- END of modified: RecordDrivers/Index/holdings.tpl --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Voyager ILS Driver modifications for displaying purchase order information | |
* | |
* @category VuFind | |
* @package ILS_Drivers | |
* @author Andrew S. Nagy <vufind-tech@lists.sourceforge.net> | |
* @author Demian Katz <demian.katz@villanova.edu> | |
* @author Matti Lassila | |
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License | |
* @link http://vufind.org/wiki/building_an_ils_driver Wiki | |
*/ | |
require_once 'VoyagerRestful.php'; | |
class VoyagerRestfulLocal extends VoyagerRestful | |
{ | |
/** | |
* Protected support method for getHolding. | |
* Modified for including purchase order | |
* information. | |
* | |
* @param array $id A Bibliographic id | |
* | |
* @return array Keyed data for use in an sql query | |
* @access protected | |
*/ | |
protected function getHoldingNoItemsSQL($id) | |
{ | |
// Check how many line items are available | |
// If there are more than one, do not query | |
// acquisition information as most likely | |
// these are serials. | |
$sql = "SELECT COUNT(*) AS CNT FROM " | |
.$this->dbName.".LINE_ITEM " | |
."INNER JOIN ".$this->dbName.".BIB_TEXT ON ".$this->dbName.".BIB_TEXT.BIB_ID = ".$this->dbName.".LINE_ITEM.BIB_ID " | |
."WHERE ".$this->dbName.".BIB_TEXT.BIB_FORMAT LIKE 'am' AND ".$this->dbName.".LINE_ITEM.BIB_ID=".$id; | |
try { | |
$sqlStmt = $this->db->prepare($sql); | |
$sqlStmt->execute(); | |
} catch (PDOException $e) { | |
return new PEAR_Error($e->getMessage()); | |
} | |
$result = $sqlStmt->fetchAll(); | |
$lineItemCount = $result[0]["CNT"]; | |
// Only one line item available; so likely it is a book. | |
if ($lineItemCount == 1) { | |
$sqlExpressions = array("BIB_MFHD.BIB_ID", "null as ITEM_BARCODE", "null as ITEM_ID", | |
"MFHD_DATA.RECORD_SEGMENT", "null as ITEM_ENUM", | |
"'N' as ON_RESERVE", "1 as ITEM_SEQUENCE_NUMBER", | |
"'No information available' as status", | |
"NVL(LOCATION.LOCATION_DISPLAY_NAME, " . | |
"LOCATION.LOCATION_NAME) as location", | |
"null as TEMP_LOCATION", | |
"null as PERM_LOCATION", | |
"MFHD_MASTER.DISPLAY_CALL_NO as callnumber", | |
"MFHD_MASTER.MFHD_ID", | |
"null as duedate", | |
"LINE_ITEM.QUANTITY as quantity", | |
"LINE_ITEM_COPY_STATUS.STATUS_DATE as order_update_date", | |
"LINE_ITEM_STATUS.LINE_ITEM_STATUS_DESC", | |
"PURCHASE_ORDER.PO_TYPE", | |
$this->getItemSortSequenceSQL('LOCATION.LOCATION_ID'), | |
"null as ITEM_TYPE_ID", | |
"null as TEMP_ITEM_TYPE_ID" | |
); | |
// From | |
$sqlFrom = array($this->dbName.".BIB_MFHD", $this->dbName.".LOCATION", | |
$this->dbName.".MFHD_MASTER", $this->dbName.".MFHD_DATA", | |
$this->dbName.".LINE_ITEM",$this->dbName. ".PURCHASE_ORDER", | |
$this->dbName.".PO_STATUS",$this->dbName.".LINE_ITEM_STATUS", | |
$this->dbName.".LINE_ITEM_COPY_STATUS" | |
); | |
// Where | |
$sqlWhere = array("BIB_MFHD.BIB_ID = :id", | |
"LINE_ITEM.BIB_ID = :id", | |
"LOCATION.LOCATION_ID = MFHD_MASTER.LOCATION_ID", | |
"MFHD_MASTER.MFHD_ID = BIB_MFHD.MFHD_ID", | |
"MFHD_DATA.MFHD_ID = BIB_MFHD.MFHD_ID", | |
"MFHD_MASTER.SUPPRESS_IN_OPAC='N'", | |
"PURCHASE_ORDER.PO_ID = LINE_ITEM.PO_ID", | |
"LINE_ITEM.LINE_ITEM_ID=LINE_ITEM_COPY_STATUS.LINE_ITEM_ID", | |
"LINE_ITEM_STATUS.LINE_ITEM_STATUS = LINE_ITEM_COPY_STATUS.LINE_ITEM_STATUS", | |
"NOT EXISTS (SELECT MFHD_ID FROM {$this->dbName}.MFHD_ITEM WHERE MFHD_ITEM.MFHD_ID=MFHD_MASTER.MFHD_ID)" | |
); | |
// Order | |
$sqlOrder = array("MFHD_DATA.MFHD_ID", "MFHD_DATA.SEQNUM"); | |
// Bind | |
$sqlBind = array(':id' => $id); | |
} | |
// Do not query acquisition information for serials. | |
else { | |
$sqlExpressions = array("BIB_MFHD.BIB_ID", "null as ITEM_BARCODE", "null as ITEM_ID", | |
"MFHD_DATA.RECORD_SEGMENT", "null as ITEM_ENUM", | |
"'N' as ON_RESERVE", "1 as ITEM_SEQUENCE_NUMBER", | |
"'No information available' as status", | |
"NVL(LOCATION.LOCATION_DISPLAY_NAME, " . | |
"LOCATION.LOCATION_NAME) as location", | |
" null as TEMP_LOCATION", | |
" null as PERM_LOCATION", | |
"MFHD_MASTER.DISPLAY_CALL_NO as callnumber", | |
"MFHD_MASTER.MFHD_ID", | |
" null as duedate", | |
$this->getItemSortSequenceSQL('LOCATION.LOCATION_ID'), | |
" null as ITEM_TYPE_ID", | |
" null as TEMP_ITEM_TYPE_ID" | |
); | |
// From | |
$sqlFrom = array($this->dbName.".BIB_MFHD", $this->dbName.".LOCATION", | |
$this->dbName.".MFHD_MASTER", $this->dbName.".MFHD_DATA" | |
); | |
// Where | |
$sqlWhere = array("BIB_MFHD.BIB_ID = :id", | |
"LOCATION.LOCATION_ID = MFHD_MASTER.LOCATION_ID", | |
"MFHD_MASTER.MFHD_ID = BIB_MFHD.MFHD_ID", | |
"MFHD_DATA.MFHD_ID = BIB_MFHD.MFHD_ID", | |
"MFHD_MASTER.SUPPRESS_IN_OPAC='N'", | |
"NOT EXISTS (SELECT MFHD_ID FROM {$this->dbName}.MFHD_ITEM WHERE MFHD_ITEM.MFHD_ID=MFHD_MASTER.MFHD_ID)" | |
); | |
// Order | |
$sqlOrder = array("MFHD_DATA.MFHD_ID", "MFHD_DATA.SEQNUM"); | |
// Bind | |
$sqlBind = array(':id' => $id); | |
} | |
$sqlArray = array('expressions' => $sqlExpressions, | |
'from' => $sqlFrom, | |
'where' => $sqlWhere, | |
'order' => $sqlOrder, | |
'bind' => $sqlBind, | |
); | |
return $sqlArray; | |
} | |
protected function processHoldingData($data, $id, $patron = false) | |
{ | |
$holding = $this->preProcessHoldingData($data, $id, $patron); | |
$mode = CatalogConnection::getHoldsMode(); | |
foreach ($holding as $i => $row) { | |
$is_borrowable = $this->isBorrowable($row['_fullRow']['ITEM_TYPE_ID']); | |
$is_holdable = $this->itemHolds && $this->isHoldable($row['_fullRow']['STATUS_ARRAY']); | |
$isCallSlipAllowed = $this->isCallSlipAllowed($row); | |
// If the item cannot be borrowed or if the item is not holdable, | |
// set is_holdable to false | |
if (!$is_borrowable || !$is_holdable) { | |
$is_holdable = false; | |
} | |
// Only used for driver generated hold links | |
$addLink = false; | |
$addCallSlipLink = false; | |
$holdType = ''; | |
$callslip = ''; | |
// Hold Type - If we have patron data, we can use it to dermine if a | |
// hold link should be shown | |
if ($is_holdable) { | |
if ($patron && $mode == "driver") { | |
// This limit is set as the api is slow to return results | |
if ($i < $this->holdCheckLimit && $this->holdCheckLimit != "0") { | |
$holdType = $this->determineHoldType( | |
$patron['id'], $row['id'], $row['item_id'] | |
); | |
$addLink = $holdType ? $holdType : false; | |
} else { | |
$holdType = "auto"; | |
$addLink = "check"; | |
} | |
} else { | |
$holdType = "auto"; | |
} | |
} | |
if ($isCallSlipAllowed) { | |
if ($patron && $mode == "driver") { | |
if ($i < $this->callSlipCheckLimit && $this->callSlipCheckLimit != "0") { | |
$callslip = false; | |
if ($this->isCallSlipAllowed($row)) { | |
$callslip = $this->checkItemRequests($patron['id'], 'callslip', $row['id'], $row['item_id']); | |
} | |
} else { | |
$callslip = "auto"; | |
$addCallSlipLink = "check"; | |
} | |
} else { | |
$callslip = "auto"; | |
} | |
} | |
$UBRequest = ''; | |
$addUBRequestLink = false; | |
if ($patron && isset($this->config['UBRequests']['enabled']) && $this->config['UBRequests']['enabled']) { | |
$UBRequest = 'auto'; | |
$addUBRequestLink = 'check'; | |
} | |
$holding[$i] += array( | |
'is_holdable' => $is_holdable, | |
'holdtype' => $holdType, | |
'addLink' => $addLink, | |
'level' => "copy", | |
'callslip' => $callslip, | |
'addCallSlipLink' => $addCallSlipLink, | |
'ubrequest' => $UBRequest, | |
'addUBRequestLink' => $addUBRequestLink | |
); | |
unset($holding[$i]['_fullRow']); | |
} | |
return $holding; | |
} | |
/** | |
* Protected support method for getHolding. | |
* | |
* @param array $data Item Data | |
* @param string $id The record id | |
* @param array $patron Patron Data | |
* | |
* @return array Keyed data | |
* @access protected | |
*/ | |
protected function preProcessHoldingData($data, $id, $patron = false) | |
{ | |
$holding = array(); | |
// Build Holdings Array | |
$i = 0; | |
$purchaseHistory = parent::getPurchaseHistory($id); | |
foreach ($data as $item) { | |
foreach ($item as $number => $row) { | |
// Get availability/status info based on the array of status codes: | |
$availability = $this->determineAvailability($row['STATUS_ARRAY']); | |
// If we found other statuses, we should override the display value | |
// appropriately: | |
if (count($availability['otherStatuses']) > 0) { | |
$row['STATUS'] | |
= $this->pickStatus($availability['otherStatuses']); | |
} | |
// Convert Voyager Format to display format | |
$dueDate = false; | |
if (!empty($row['DUEDATE'])) { | |
$dueDate = $this->dateFormat->convertToDisplayDate( | |
"m-d-y", $row['DUEDATE'] | |
); | |
if (PEAR::isError($dueDate)) { | |
return $dueDate; | |
} | |
} | |
$returnDate = false; | |
if (!empty($row['RETURNDATE'])) { | |
$returnDate = $this->dateFormat->convertToDisplayDate( | |
"m-d-y H:i", $row['RETURNDATE'] | |
); | |
if (PEAR::isError($returnDate)) { | |
return $returnDate; | |
} | |
$returnTime = $this->dateFormat->convertToDisplayTime( | |
"m-d-y H:i", $row['RETURNDATE'] | |
); | |
if (PEAR::isError($returnTime)) { | |
return $returnTime; | |
} | |
$returnDate .= " " . $returnTime; | |
} | |
$returnDate = (in_array("Discharged", $row['STATUS_ARRAY'])) | |
? $returnDate : false; | |
$requests_placed = (isset($row['HOLDS_PLACED']) ? $row['HOLDS_PLACED'] : 0) | |
+ (isset($row['RECALLS_PLACED']) ? $row['RECALLS_PLACED'] : 0); | |
$holding[$i] = $this->processHoldingRow($row); | |
$purchases = array(); | |
foreach ($purchaseHistory as $historyItem) { | |
if ($holding[$i]['mfhd_id'] == $historyItem['mfhd_id']) { | |
$purchases[] = $historyItem; | |
} | |
} | |
$holding[$i] += array( | |
'availability' => $availability['available'], | |
'duedate' => $dueDate, | |
'number' => $number, | |
'requests_placed' => $requests_placed, | |
'returnDate' => $returnDate, | |
'use_unknown_message' => in_array('No information available', $row['STATUS_ARRAY']), | |
'purchase_history' => $purchases | |
); | |
// Parse Holding Record | |
if ($row['RECORD_SEGMENT']) { | |
$marcDetails | |
= $this->processRecordSegment($row['RECORD_SEGMENT']); | |
if (!empty($marcDetails)) { | |
$holding[$i] += $marcDetails; | |
} | |
} | |
$i++; | |
} | |
} | |
if (!isset($this->config['Holdings']['use_sort_groups']) | |
|| $this->config['Holdings']['use_sort_groups'] | |
) { | |
usort( | |
$holding, | |
function($a, $b) { | |
return $a['sort_seq'] == $b['sort_seq'] | |
&& isset($a['item_id']) && isset($b['item_id']) | |
? $a['item_id'] - $b['item_id'] | |
: $a['sort_seq'] - $b['sort_seq']; | |
} | |
); | |
} | |
return $holding; | |
} | |
/** | |
* Protected support method for getHolding. | |
* | |
* @param array $sqlRow SQL Row Data | |
* | |
* @return array Keyed data | |
* @access protected | |
*/ | |
protected function processHoldingRow($sqlRow) | |
{ | |
$row = array( | |
'id' => $sqlRow['BIB_ID'], | |
'mfhd_id' => $sqlRow['MFHD_ID'], | |
'item_id' => $sqlRow['ITEM_ID'], | |
'status' => $sqlRow['STATUS'], | |
'location' => $sqlRow['TEMP_LOCATION'] > 0 | |
? $this->getLocationName($sqlRow['TEMP_LOCATION']) | |
: utf8_encode($sqlRow['LOCATION']), | |
'reserve' => $sqlRow['ON_RESERVE'], | |
'callnumber' => $sqlRow['CALLNUMBER'], | |
'barcode' => $sqlRow['ITEM_BARCODE'], | |
'sort_seq' => isset($sqlRow['SORT_SEQ']) | |
? $sqlRow['SORT_SEQ'] | |
: PHP_INT_MAX | |
); | |
if (array_key_exists('ORDER_UPDATE_DATE',$sqlRow)) { | |
$row +=array( | |
'quantity' => $sqlRow['QUANTITY'], | |
'order_update_date' => | |
$this->dateFormat->convertToDisplayDate("m-d-y", | |
$sqlRow['ORDER_UPDATE_DATE']), | |
'order_status' => $sqlRow['LINE_ITEM_STATUS_DESC'], | |
'order_type' => $sqlRow['PO_TYPE']); | |
} | |
$row += array('item_id' => $sqlRow['ITEM_ID'], '_fullRow' => $sqlRow); | |
return $row; | |
} | |
public function getHolding($id, $patron = false) | |
{ | |
$possibleQueries = array(); | |
// There are two possible queries we can use to obtain status information. | |
// The first (and most common) obtains information from a combination of | |
// items and holdings records. The second (a rare case) obtains | |
// information from the holdings record when no items are available. | |
$sqlArrayItems = $this->getHoldingItemsSQL($id); | |
$possibleQueries[] = $this->buildSqlFromArray($sqlArrayItems); | |
$sqlArrayNoItems = $this->getHoldingNoItemsSQL($id); | |
$possibleQueries[] = $this->buildSqlFromArray($sqlArrayNoItems); | |
// Loop through the possible queries and try each in turn -- the first one | |
// that yields results will cause us to break out of the loop. | |
$data = array(); | |
foreach ($possibleQueries as $sql) { | |
// Execute SQL | |
try { | |
$sqlStmt = $this->db->prepare($sql['string']); | |
$this->debugLogSQL(__FUNCTION__, $sql['string'], $sql['bind']); | |
$sqlStmt->execute($sql['bind']); | |
} catch (PDOException $e) { | |
return new PEAR_Error($e->getMessage()); | |
} | |
$sqlRows = array(); | |
while ($row = $sqlStmt->fetch(PDO::FETCH_ASSOC)) { | |
$sqlRows[] = $row; | |
} | |
$data = array_merge($data, $this->getHoldingData($sqlRows)); | |
} | |
return $this->processHoldingData($data, $id, $patron); | |
} | |
/** | |
* Protected support method for getHolding. | |
* | |
* @param array $recordSegment A Marc Record Segment obtained from an SQL query | |
* | |
* @return array Keyed data | |
* @access protected | |
*/ | |
protected function processRecordSegment($recordSegment) | |
{ | |
$marcDetails = array(); | |
try { | |
$marc = new File_MARC( | |
str_replace(array("\n", "\r"), '', $recordSegment), | |
File_MARC::SOURCE_STRING | |
); | |
if ($record = $marc->next()) { | |
// Get Notes | |
$noteFields = array( | |
'506' => 'au', | |
'845' => 'a', | |
'852' => 'z' | |
); | |
foreach ($noteFields as $fieldCode => $subfieldCodes) { | |
if ($fields = $record->getFields($fieldCode)) { | |
foreach ($fields as $field) { | |
if ($subfields = $field->getSubfields()) { | |
$line = ''; | |
foreach ($subfields as $code => $subfield) { | |
if (!strstr($subfieldCodes, $code)) { | |
continue; | |
} | |
if ($line) { | |
$line .= ' '; | |
} | |
$line .= $subfield->getData(); | |
} | |
if ($line) { | |
$marcDetails['notes'][] = $line; | |
} | |
} | |
} | |
} | |
} | |
// Get Summary (may be multiple lines) | |
if ($fields = $record->getFields('863')) { | |
foreach ($fields as $field) { | |
if ($subfields = $field->getSubfields()) { | |
$line = ''; | |
foreach ($subfields as $code => $subfield) { | |
if (!strstr('abiz', $code)) { | |
continue; | |
} | |
if ($line) { | |
$line .= ' '; | |
} | |
if ($code == 'i' || $code == 'z') { | |
$line .= '(' . $subfield->getData() . ')'; | |
} else { | |
$line .= $subfield->getData(); | |
} | |
} | |
if ($line) { | |
$marcDetails['summary'][] = $line; | |
} | |
} | |
} | |
} | |
if ($fields = $record->getFields('866')) { | |
foreach ($fields as $field) { | |
if ($subfields = $field->getSubfields()) { | |
$line = ''; | |
foreach ($subfields as $code => $subfield) { | |
if (!strstr('az', $code)) { | |
continue; | |
} | |
if ($line) { | |
$line .= ' '; | |
} | |
$line .= $subfield->getData(); | |
} | |
if ($line) { | |
$marcDetails['summary'][] = $line; | |
} | |
} | |
} | |
} | |
// Get Supplementary material (may be multiple lines) | |
if ($fields = $record->getFields('867')) { | |
foreach ($fields as $field) { | |
if ($subfields = $field->getSubfields()) { | |
$line = ''; | |
foreach ($subfields as $code => $subfield) { | |
if (!strstr('az', $code)) { | |
continue; | |
} | |
if ($line) { | |
$line .= ' '; | |
} | |
if ($code == 'z') { | |
$line .= '(' . $subfield->getData() . ')'; | |
} else { | |
$line .= $subfield->getData(); | |
} | |
} | |
if ($line) { | |
$marcDetails['supplements'][] = $line; | |
} | |
} | |
} | |
} | |
// Get indexes (may be multiple lines) | |
if ($fields = $record->getFields('868')) { | |
foreach ($fields as $field) { | |
if ($subfields = $field->getSubfields()) { | |
$line = ''; | |
foreach ($subfields as $code => $subfield) { | |
if (!strstr('az', $code)) { | |
continue; | |
} | |
if ($line) { | |
$line .= ' '; | |
} | |
if ($code == 'z') { | |
$line .= '(' . $subfield->getData() . ')'; | |
} else { | |
$line .= $subfield->getData(); | |
} | |
} | |
if ($line) { | |
$marcDetails['indexes'][] = $line; | |
} | |
} | |
} | |
} | |
} | |
} catch (Exception $e) { | |
trigger_error( | |
'Poorly Formatted MFHD Record', E_USER_NOTICE | |
); | |
} | |
return $marcDetails; | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment