private static function loadLibraryLocationInformation() { if (MillenniumDriver::$libraryLocationInformationLoaded == false) { //Get a list of all locations for the active library global $library; global $timer; $userLibrary = Library::getPatronHomeLibrary(); MillenniumDriver::$libraryLocations = array(); MillenniumDriver::$libraryLocationLabels = array(); $libraryLocation = new Location(); if ($userLibrary) { $libraryLocation->libraryId = $userLibrary->libraryId; $libraryLocation->find(); while ($libraryLocation->fetch()) { MillenniumDriver::$libraryLocations[] = $libraryLocation->code; MillenniumDriver::$libraryLocationLabels[$libraryLocation->code] = $libraryLocation->facetLabel; } } else { $libraryLocation->libraryId = $library->libraryId; $libraryLocation->find(); while ($libraryLocation->fetch()) { MillenniumDriver::$libraryLocations[] = $libraryLocation->code; MillenniumDriver::$libraryLocationLabels[$libraryLocation->code] = $libraryLocation->facetLabel; } } MillenniumDriver::$homeLocationCode = null; MillenniumDriver::$homeLocationLabel = null; $searchLocation = Location::getSearchLocation(); if ($searchLocation) { MillenniumDriver::$homeLocationCode = $searchLocation->code; MillenniumDriver::$homeLocationLabel = $searchLocation->facetLabel; } else { $homeLocation = Location::getUserHomeLocation(); if ($homeLocation) { MillenniumDriver::$homeLocationCode = $homeLocation->code; MillenniumDriver::$homeLocationLabel = $homeLocation->facetLabel; } } $timer->logTime("Finished loading location data"); MillenniumDriver::$scopingLocationCode = ''; $searchLibrary = Library::getSearchLibrary(); $searchLocation = Location::getSearchLocation(); if (isset($searchLibrary)) { MillenniumDriver::$scopingLocationCode = $searchLibrary->ilsCode; } if (isset($searchLocation)) { MillenniumDriver::$scopingLocationCode = $searchLocation->code; } MillenniumDriver::$libraryLocationInformationLoaded = true; } }
static function getObjectStructure() { global $user; //Load Libraries for lookup values $location = new Location(); $location->orderBy('displayName'); if ($user->hasRole('libraryAdmin')) { $homeLibrary = Library::getPatronHomeLibrary(); $location->libraryId = $homeLibrary->libraryId; } $location->find(); $locationList = array(); while ($location->fetch()) { $locationList[$location->locationId] = $location->displayName; } require_once ROOT_DIR . '/sys/Browse/BrowseCategory.php'; $browseCategories = new BrowseCategory(); $browseCategories->orderBy('label'); $browseCategories->find(); $browseCategoryList = array(); while ($browseCategories->fetch()) { $browseCategoryList[$browseCategories->textId] = $browseCategories->label . " ({$browseCategories->textId})"; } $structure = array('id' => array('property' => 'id', 'type' => 'label', 'label' => 'Id', 'description' => 'The unique id of the hours within the database'), 'locationId' => array('property' => 'locationId', 'type' => 'enum', 'values' => $locationList, 'label' => 'Location', 'description' => 'A link to the location which the browse category belongs to'), 'browseCategoryTextId' => array('property' => 'browseCategoryTextId', 'type' => 'enum', 'values' => $browseCategoryList, 'label' => 'Browse Category', 'description' => 'The browse category to display '), 'weight' => array('property' => 'weight', 'type' => 'numeric', 'label' => 'Weight', 'weight' => 'Defines how lists are sorted within the widget. Lower weights are displayed to the left of the screen.', 'required' => true)); foreach ($structure as $fieldName => $field) { $field['propertyOld'] = $field['property'] . 'Old'; $structure[$fieldName] = $field; } return $structure; }
public function testSave() { $loc = new Location(); $loc->setBuildingID(1); $loc->setRoom(9999); $loc->save(); $this->assertTrue($loc->getID() != NULL); $fetched = new Location(); $fetched->fetch($loc->getID()); $this->assertEquals($fetched->getID(), $loc->getID()); $this->assertEquals($fetched->getBuildingID(), $loc->getBuildingID()); $this->assertEquals($fetched->getRoom(), $loc->getRoom()); //delete from DB for cleanup //TODO -- replace with proper delete method $sql = "DELETE FROM `locations` WHERE id=?"; $sql = $this->db->prepareQuery($sql, $loc->getID()); $this->db->query($sql); }
function getAllObjects() { //Look lookup information for display in the user interface global $user; $location = new Location(); $location->orderBy('displayName'); if (!$user->hasRole('opacAdmin')) { //Scope to just locations for the user based on home library $patronLibrary = Library::getLibraryForLocation($user->homeLocationId); $location->libraryId = $patronLibrary->libraryId; } $location->find(); $locationList = array(); while ($location->fetch()) { $locationList[$location->locationId] = clone $location; } return $locationList; }
function getObjectStructure() { //Look lookup information for display in the user interface $location = new Location(); $location->orderBy('displayName'); $location->find(); $locationList = array(); $locationLookupList = array(); $locationLookupList[-1] = '<No Nearby Location>'; while ($location->fetch()) { $locationLookupList[$location->locationId] = $location->displayName; $locationList[$location->locationId] = clone $location; } $structure = array('ip' => array('property' => 'ip', 'type' => 'text', 'label' => 'IP Address', 'description' => 'The IP Address to map to a location formatted as xxx.xxx.xxx.xxx/mask'), 'location' => array('property' => 'location', 'type' => 'text', 'label' => 'Display Name', 'description' => 'Descriptive information for the IP Address for internal use'), 'locationid' => array('property' => 'locationid', 'type' => 'enum', 'values' => $locationLookupList, 'label' => 'Location', 'description' => 'The Location which this IP address maps to')); foreach ($structure as $fieldName => $field) { $field['propertyOld'] = $field['property'] . 'Old'; $structure[$fieldName] = $field; } return $structure; }
static function getObjectStructure() { global $user; $location = new Location(); $location->orderBy('displayName'); if ($user->hasRole('libraryAdmin')) { $homeLibrary = Library::getPatronHomeLibrary(); $location->libraryId = $homeLibrary->libraryId; } $location->find(); while ($location->fetch()) { $locationList[$location->locationId] = $location->displayName; } $structure = parent::getObjectStructure(); $structure['locationId'] = array('property' => 'locationId', 'type' => 'enum', 'values' => $locationList, 'label' => 'Location', 'description' => 'The id of a location'); foreach ($structure as $fieldName => $field) { $field['propertyOld'] = $field['property'] . 'Old'; $structure[$fieldName] = $field; } return $structure; }
static function getObjectStructure() { $location = new Location(); $location->orderBy('displayName'); $location->find(); $locationList = array(); while ($location->fetch()) { $locationList[$location->locationId] = $location->displayName; } $days = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'); $time = array('01:00', '01:30', '02:00', '02:30', '03:00', '03:30', '04:00', '04:30', '05:00', '05:30', '06:00', '06:30', '07:00', '07:30', '08:00', '08:30', '09:00', '09:30', '10:00', '10:30', '11:00', '11:30', '12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00', '15:30', '16:00', '16:30', '17:00', '17:30', '18:00', '18:30', '19:00', '19:30', '20:00', '20:30', '21:00', '21:30', '22:00', '22:30', '23:00', '23:30'); $timeList = array(); foreach ($time as $t) { $timeList[$t] = $t; } $structure = array('id' => array('property' => 'id', 'type' => 'label', 'label' => 'Id', 'description' => 'The unique id of the hours within the database'), 'locationId' => array('property' => 'locationId', 'type' => 'enum', 'values' => $locationList, 'label' => 'Location', 'description' => 'The library location.'), 'day' => array('property' => 'day', 'type' => 'enum', 'values' => $days, 'label' => 'Day of Week', 'description' => 'The day of the week 0 to 6 (0 = Sunday to 6 = Saturday)'), 'closed' => array('property' => 'closed', 'type' => 'checkbox', 'label' => 'Closed', 'description' => 'Check to indicate that the library is closed on this day.'), 'open' => array('property' => 'open', 'type' => 'enum', 'values' => $timeList, 'label' => 'Opening Hour', 'description' => 'The opening hour. Use 24 hour format HH:MM, eg: 08:30'), 'close' => array('property' => 'close', 'type' => 'enum', 'values' => $timeList, 'label' => 'Closing Hour', 'description' => 'The closing hour. Use 24 hour format HH:MM, eg: 16:30')); foreach ($structure as $fieldName => $field) { $field['propertyOld'] = $field['property'] . 'Old'; $structure[$fieldName] = $field; } return $structure; }
function getLocationsFacetsForLibrary($libraryId) { $location = new Location(); $location->libraryId = $libraryId; $location->find(); $facets = array(); if ($location->N > 0) { while ($location->fetch()) { $facets[] = $location->facetLabel; } } return $facets; }
/** * Place Item Hold * * This is responsible for both placing item level holds. * * @param string $recordId The id of the bib record * @param string $itemId The id of the item to hold * @param string $patronId The id of the patron * @param string $comment Any comment regarding the hold or recall * @param string $type Whether to place a hold or recall * @param string $type The date when the hold should be cancelled if any * @return mixed True if successful, false if unsuccessful * If an error occurs, return a PEAR_Error * @access public */ public function placeItemHold($recordId, $itemId, $patronId, $comment, $type) { global $user; global $configArray; $hold_result = array(); $hold_result['result'] = false; require_once ROOT_DIR . '/RecordDrivers/MarcRecord.php'; $recordDriver = new MarcRecord($recordId); if (!$recordDriver->isValid()) { $hold_result['message'] = 'Unable to find a valid record for this title. Please try your search again.'; return $hold_result; } $hold_result['title'] = $recordDriver->getTitle(); //Set pickup location if (isset($_REQUEST['campus'])) { $campus = trim($_REQUEST['campus']); } else { $campus = $user->homeLocationId; //Get the code for the location $locationLookup = new Location(); $locationLookup->locationId = $campus; $locationLookup->find(); if ($locationLookup->N > 0) { $locationLookup->fetch(); $campus = $locationLookup->code; } } $campus = strtoupper($campus); //Login before placing the hold $this->loginToKoha($user); //Post the hold to koha $placeHoldPage = $configArray['Catalog']['url'] . '/cgi-bin/koha/opac-reserve.pl'; $holdParams = array('biblionumbers' => $recordId . '/', 'branch' => $campus, "checkitem_{$recordId}" => $itemId, 'place_reserve' => 1, "reqtype_{$recordId}" => 'Specific', 'reserve_mode' => 'multi', 'selecteditems' => "{$recordId}/{$itemId}/{$campus}/", 'single_bib' => $recordId); $kohaHoldResult = $this->postToKohaPage($placeHoldPage, $holdParams); $hold_result['id'] = $recordId; if (preg_match('/<a href="#opac-user-holds">Holds<\\/a>/si', $kohaHoldResult)) { //We redirected to the holds page, everything seems to be good $holds = $this->getMyHolds($user, 1, -1, 'title', $kohaHoldResult); $hold_result['result'] = true; $hold_result['message'] = "Your hold was placed successfully."; //Find the correct hold (will be unavailable) foreach ($holds['holds']['unavailable'] as $holdInfo) { if ($holdInfo['id'] == $recordId) { if (isset($holdInfo['position'])) { $hold_result['message'] .= " You are number <b>" . $holdInfo['position'] . "</b> in the queue."; } break; } } } else { $hold_result['result'] = false; //Look for an alert message if (preg_match('/<div class="dialog alert">(.*?)<\\/div>/', $kohaHoldResult, $matches)) { $hold_result['message'] = 'Your hold could not be placed. ' . $matches[1]; } else { $hold_result['message'] = 'Your hold could not be placed. '; } } return $hold_result; }
function launch() { global $interface; global $user; $period = isset($_REQUEST['period']) ? $_REQUEST['period'] : 'week'; if ($period == 'week') { $periodLength = new DateInterval("P1W"); } elseif ($period == 'day') { $periodLength = new DateInterval("P1D"); } elseif ($period == 'month') { $periodLength = new DateInterval("P1M"); } else { //year $periodLength = new DateInterval("P1Y"); } $interface->assign('period', $period); $endDate = isset($_REQUEST['endDate']) && strlen($_REQUEST['endDate']) > 0 ? DateTime::createFromFormat('m/d/Y', $_REQUEST['endDate']) : new DateTime(); $interface->assign('endDate', $endDate->format('m/d/Y')); if (isset($_REQUEST['startDate']) && strlen($_REQUEST['startDate']) > 0) { $startDate = DateTime::createFromFormat('m/d/Y', $_REQUEST['startDate']); } else { if ($period == 'day') { $startDate = new DateTime($endDate->format('m/d/Y') . " - 7 days"); } elseif ($period == 'week') { //Get the sunday after this $endDate->setISODate($endDate->format('Y'), $endDate->format("W"), 0); $endDate->modify("+7 days"); $startDate = new DateTime($endDate->format('m/d/Y') . " - 28 days"); } elseif ($period == 'month') { $endDate->modify("+1 month"); $numDays = $endDate->format("d"); $endDate->modify(" -{$numDays} days"); $startDate = new DateTime($endDate->format('m/d/Y') . " - 6 months"); } else { //year $endDate->modify("+1 year"); $numDays = $endDate->format("m"); $endDate->modify(" -{$numDays} months"); $numDays = $endDate->format("d"); $endDate->modify(" -{$numDays} days"); $startDate = new DateTime($endDate->format('m/d/Y') . " - 2 years"); } } $interface->assign('startDate', $startDate->format('m/d/Y')); //Set the end date to the end of the day $endDate->setTime(24, 0, 0); $startDate->setTime(0, 0, 0); //Create the periods that are being represented $periods = array(); $periodEnd = clone $endDate; while ($periodEnd >= $startDate) { array_unshift($periods, clone $periodEnd); $periodEnd->sub($periodLength); } //print_r($periods); //Load data for each period //this will be a two dimensional array // Period 1, Period 2, Period 3 //Status 1 //Status 2 //Status 3 $periodData = array(); for ($i = 0; $i < count($periods) - 1; $i++) { /** @var DateTime $periodStart */ $periodStart = clone $periods[$i]; /** @var DateTime $periodEnd */ $periodEnd = clone $periods[$i + 1]; $periodData[$periodStart->getTimestamp()] = array(); //Determine how many requests were created $materialsRequest = new MaterialsRequest(); $materialsRequest->joinAdd(new User(), 'INNER', 'user'); $materialsRequest->selectAdd(); $materialsRequest->selectAdd('COUNT(id) as numRequests'); $materialsRequest->whereAdd('dateCreated >= ' . $periodStart->getTimestamp() . ' AND dateCreated < ' . $periodEnd->getTimestamp()); if ($user->hasRole('library_material_requests')) { //Need to limit to only requests submitted for the user's home location $userHomeLibrary = Library::getPatronHomeLibrary(); $locations = new Location(); $locations->libraryId = $userHomeLibrary->libraryId; $locations->find(); $locationsForLibrary = array(); while ($locations->fetch()) { $locationsForLibrary[] = $locations->locationId; } $materialsRequest->whereAdd('user.homeLocationId IN (' . implode(', ', $locationsForLibrary) . ')'); } $materialsRequest->find(); while ($materialsRequest->fetch()) { $periodData[$periodStart->getTimestamp()]['Created'] = $materialsRequest->numRequests; } //Get a list of all requests by the status of the request $materialsRequest = new MaterialsRequest(); $materialsRequest->joinAdd(new MaterialsRequestStatus()); $materialsRequest->joinAdd(new User(), 'INNER', 'user'); $materialsRequest->selectAdd(); $materialsRequest->selectAdd('COUNT(materials_request.id) as numRequests,description'); $materialsRequest->whereAdd('dateUpdated >= ' . $periodStart->getTimestamp() . ' AND dateUpdated < ' . $periodEnd->getTimestamp()); if ($user->hasRole('library_material_requests')) { //Need to limit to only requests submitted for the user's home location $userHomeLibrary = Library::getPatronHomeLibrary(); $locations = new Location(); $locations->libraryId = $userHomeLibrary->libraryId; $locations->find(); $locationsForLibrary = array(); while ($locations->fetch()) { $locationsForLibrary[] = $locations->locationId; } $materialsRequest->whereAdd('user.homeLocationId IN (' . implode(', ', $locationsForLibrary) . ')'); } $materialsRequest->groupBy('status'); $materialsRequest->orderBy('status'); $materialsRequest->find(); while ($materialsRequest->fetch()) { $periodData[$periodStart->getTimestamp()][$materialsRequest->description] = $materialsRequest->numRequests; } } $interface->assign('periodData', $periodData, $periods); //Get a list of all of the statuses that will be shown $statuses = array(); foreach ($periodData as $periodInfo) { foreach ($periodInfo as $status => $numRequests) { $statuses[$status] = translate($status); } } $interface->assign('statuses', $statuses); //Check to see if we are exporting to Excel if (isset($_REQUEST['exportToExcel'])) { $this->exportToExcel($periodData, $statuses); } else { //Generate the graph $this->generateGraph($periodData, $statuses); } $interface->setTemplate('summaryReport.tpl'); $interface->assign('sidebar', 'MyAccount/account-sidebar.tpl'); $interface->setPageTitle('Materials Request Summary Report'); $interface->display('layout.tpl'); }
function launch() { global $configArray; global $interface; global $user; /** @var Library $librarySingleton */ global $librarySingleton; $activeLibrary = $librarySingleton->getActiveLibrary(); if ($activeLibrary == null) { $canUpdateContactInfo = true; $canUpdateAddress = true; $showWorkPhoneInProfile = false; $showNoticeTypeInProfile = true; $showPickupLocationInProfile = false; $treatPrintNoticesAsPhoneNotices = false; $allowPinReset = false; $showAlternateLibraryOptionsInProfile = true; } else { $canUpdateContactInfo = $activeLibrary->allowProfileUpdates == 1; $canUpdateAddress = $activeLibrary->allowPatronAddressUpdates == 1; $showWorkPhoneInProfile = $activeLibrary->showWorkPhoneInProfile == 1; $showNoticeTypeInProfile = $activeLibrary->showNoticeTypeInProfile == 1; $treatPrintNoticesAsPhoneNotices = $activeLibrary->treatPrintNoticesAsPhoneNotices == 1; $showPickupLocationInProfile = $activeLibrary->showPickupLocationInProfile == 1; $allowPinReset = $activeLibrary->allowPinReset == 1; $showAlternateLibraryOptionsInProfile = $activeLibrary->showAlternateLibraryOptionsInProfile == 1; } if ($showPickupLocationInProfile) { // only grab pickup locations if needed. global $locationSingleton; //Get the list of pickup branch locations for display in the user interface. $locations = $locationSingleton->getPickupBranches($user, $user->homeLocationId); $interface->assign('pickupLocations', $locations); } $interface->assign('canUpdateContactInfo', $canUpdateContactInfo); $interface->assign('canUpdateAddress', $canUpdateAddress); $interface->assign('showWorkPhoneInProfile', $showWorkPhoneInProfile); $interface->assign('showPickupLocationInProfile', $showPickupLocationInProfile); $interface->assign('showNoticeTypeInProfile', $showNoticeTypeInProfile); $interface->assign('treatPrintNoticesAsPhoneNotices', $treatPrintNoticesAsPhoneNotices); $interface->assign('allowPinReset', $allowPinReset); $interface->assign('showAlternateLibraryOptions', $showAlternateLibraryOptionsInProfile); $ils = $configArray['Catalog']['ils']; $interface->assign('showSMSNoticesInProfile', $ils == 'Sierra'); if ($configArray['Catalog']['offline']) { $interface->assign('offline', true); } else { $interface->assign('offline', false); } if (isset($_POST['updateScope']) && !$configArray['Catalog']['offline']) { $updateScope = $_REQUEST['updateScope']; if ($updateScope == 'contact') { $errors = $this->catalog->updatePatronInfo($canUpdateContactInfo); session_start(); // any writes to the session storage also closes session. Happens in updatePatronInfo (for Horizon). plb 4-21-2015 $_SESSION['profileUpdateErrors'] = $errors; } elseif ($updateScope == 'catalog') { $user->updateCatalogOptions(); } elseif ($updateScope == 'overdrive') { // overdrive setting keep changing /* require_once ROOT_DIR . '/Drivers/OverDriveDriverFactory.php'; $overDriveDriver = OverDriveDriverFactory::getDriver(); $result = $overDriveDriver->updateLendingOptions(); */ $user->updateOverDriveOptions(); } elseif ($updateScope == 'pin') { $errors = $this->catalog->updatePin(); session_start(); // any writes to the session storage also closes session. possibly happens in updatePin. plb 4-21-2015 $_SESSION['profileUpdateErrors'] = $errors; } session_write_close(); header("Location: " . $configArray['Site']['path'] . '/MyAccount/Profile'); exit; } elseif (!$configArray['Catalog']['offline']) { $interface->assign('edit', true); } else { $interface->assign('edit', false); } /*require_once ROOT_DIR . '/Drivers/OverDriveDriverFactory.php'; $overDriveDriver = OverDriveDriverFactory::getDriver(); if ($overDriveDriver->version >= 2){ $lendingPeriods = $overDriveDriver->getLendingPeriods($user); $interface->assign('overDriveLendingOptions', $lendingPeriods); }*/ $interface->assign('overDriveUrl', $configArray['OverDrive']['url']); if (isset($_SESSION['profileUpdateErrors'])) { $interface->assign('profileUpdateErrors', $_SESSION['profileUpdateErrors']); unset($_SESSION['profileUpdateErrors']); } //Get the list of locations for display in the user interface. $location = new Location(); $location->validHoldPickupBranch = 1; $location->find(); $locationList = array(); while ($location->fetch()) { $locationList[$location->locationId] = $location->displayName; } $interface->assign('locationList', $locationList); if ($this->catalog->checkFunction('isUserStaff')) { $userIsStaff = $this->catalog->isUserStaff(); $interface->assign('userIsStaff', $userIsStaff); } else { $interface->assign('userIsStaff', false); } // switch for hack for Millenium driver profile updating when updating is allowed but address updating is not allowed. $millenniumNoAddress = $canUpdateContactInfo && !$canUpdateAddress && in_array($ils, array('Millennium', 'Sierra')); $interface->assign('millenniumNoAddress', $millenniumNoAddress); $this->display(); // $interface->assign('sidebar', 'MyAccount/account-sidebar.tpl'); // $interface->setTemplate('profile.tpl'); // $interface->setPageTitle(translate('Account Settings')); // $interface->display('layout.tpl'); }
/** * Load status (holdings) for a record and filter them based on the logged in user information. * * @param string $id the id of the record * @return array A list of holdings for the record */ public function getStatus($id) { global $library; global $user; global $timer; global $logger; //Get information about holdings, order information, and issue information $millenniumInfo = $this->driver->getMillenniumRecordInfo($id); //Get the number of holds if ($millenniumInfo->framesetInfo) { if (preg_match('/(\\d+) hold(s?) on .*? of \\d+ (copies|copy)/', $millenniumInfo->framesetInfo, $matches)) { $holdQueueLength = $matches[1]; } else { $holdQueueLength = 0; } } // Load Record Page $r = substr($millenniumInfo->holdingsInfo, stripos($millenniumInfo->holdingsInfo, 'bibItems')); $r = substr($r, strpos($r, ">") + 1); $r = substr($r, 0, stripos($r, "</table")); $rows = preg_split("/<tr([^>]*)>/", $r); // Load the full marc record so we can get the iType for each record. $marcRecord = MarcLoader::loadMarcRecordByILSId($id); $itemFields = $marcRecord->getFields("989"); $marcItemData = array(); $pType = $this->driver->getPType(); $scope = $this->driver->getMillenniumScope(); //Load item information from marc record foreach ($itemFields as $itemField) { /** @var $itemField File_MARC_Data_Field */ $fullCallNumber = $itemField->getSubfield('s') != null ? $itemField->getSubfield('s')->getData() . ' ' : ''; $fullCallNumber .= $itemField->getSubfield('a') != null ? $itemField->getSubfield('a')->getData() : ''; $fullCallNumber .= $itemField->getSubfield('r') != null ? ' ' . $itemField->getSubfield('r')->getData() : ''; $itemData['callnumber'] = $fullCallNumber; $itemData['location'] = $itemField->getSubfield('d') != null ? $itemField->getSubfield('d')->getData() : ($itemField->getSubfield('p') != null ? $itemField->getSubfield('p')->getData() : '?????'); $itemData['iType'] = $itemField->getSubfield('j') != null ? $itemField->getSubfield('j')->getData() : '0'; $itemData['matched'] = false; $marcItemData[] = $itemData; } //Process each row in the callnumber table. $ret = $this->parseHoldingRows($id, $rows); $timer->logTime('processed all holdings rows'); global $locationSingleton; /** @var $locationSingleton Location */ $physicalLocation = $locationSingleton->getPhysicalLocation(); if ($physicalLocation != null) { $physicalBranch = $physicalLocation->holdingBranchLabel; } else { $physicalBranch = ''; } $homeBranch = ''; $homeBranchId = 0; $nearbyBranch1 = ''; $nearbyBranch1Id = 0; $nearbyBranch2 = ''; $nearbyBranch2Id = 0; //Set location information based on the user login. This will override information based if (isset($user) && $user != false) { $homeBranchId = $user->homeLocationId; $nearbyBranch1Id = $user->myLocation1Id; $nearbyBranch2Id = $user->myLocation2Id; } else { //Check to see if the cookie for home location is set. if (isset($_COOKIE['home_location']) && is_numeric($_COOKIE['home_location'])) { $cookieLocation = new Location(); $locationId = $_COOKIE['home_location']; $cookieLocation->whereAdd("locationId = '{$locationId}'"); $cookieLocation->find(); if ($cookieLocation->N == 1) { $cookieLocation->fetch(); $homeBranchId = $cookieLocation->locationId; $nearbyBranch1Id = $cookieLocation->nearbyLocation1; $nearbyBranch2Id = $cookieLocation->nearbyLocation2; } } } //Load the holding label for the user's home location. $userLocation = new Location(); $userLocation->whereAdd("locationId = '{$homeBranchId}'"); $userLocation->find(); if ($userLocation->N == 1) { $userLocation->fetch(); $homeBranch = $userLocation->holdingBranchLabel; } //Load nearby branch 1 $nearbyLocation1 = new Location(); $nearbyLocation1->whereAdd("locationId = '{$nearbyBranch1Id}'"); $nearbyLocation1->find(); if ($nearbyLocation1->N == 1) { $nearbyLocation1->fetch(); $nearbyBranch1 = $nearbyLocation1->holdingBranchLabel; } //Load nearby branch 2 $nearbyLocation2 = new Location(); $nearbyLocation2->whereAdd(); $nearbyLocation2->whereAdd("locationId = '{$nearbyBranch2Id}'"); $nearbyLocation2->find(); if ($nearbyLocation2->N == 1) { $nearbyLocation2->fetch(); $nearbyBranch2 = $nearbyLocation2->holdingBranchLabel; } $sorted_array = array(); //Get a list of the display names for all locations based on holding label. $locationLabels = array(); $location = new Location(); $location->find(); $libraryLocationLabels = array(); $locationCodes = array(); $suppressedLocationCodes = array(); while ($location->fetch()) { if (strlen($location->holdingBranchLabel) > 0 && $location->holdingBranchLabel != '???') { if ($library && $library->libraryId == $location->libraryId) { $cleanLabel = str_replace('/', '\\/', $location->holdingBranchLabel); $libraryLocationLabels[] = str_replace('.', '\\.', $cleanLabel); } $locationLabels[$location->holdingBranchLabel] = $location->displayName; $locationCodes[$location->code] = $location->holdingBranchLabel; if ($location->suppressHoldings == 1) { $suppressedLocationCodes[$location->code] = $location->code; } } } if (count($libraryLocationLabels) > 0) { $libraryLocationLabels = '/^(' . join('|', $libraryLocationLabels) . ').*/i'; } else { $libraryLocationLabels = ''; } //Get the current Ptype for later usage. $timer->logTime('setup for additional holdings processing.'); //Now that we have the holdings, we need to filter and sort them according to scoping rules. $i = 0; foreach ($ret as $holdingKey => $holding) { $holding['type'] = 'holding'; //Process holdings without call numbers - Need to show items without call numbers //because they may have links, etc. Also show if there is a status. Since some //In process items may not have a call number yet. if ((!isset($holding['callnumber']) || strlen($holding['callnumber']) == 0) && (!isset($holding['link']) || count($holding['link']) == 0) && !isset($holding['status'])) { continue; } //Determine if the holding is available or not. //First check the status if (preg_match('/^(' . $this->driver->availableStatiRegex . ')$/', $holding['status'])) { $holding['availability'] = 1; } else { $holding['availability'] = 0; } if (preg_match('/^(' . $this->driver->holdableStatiRegex . ')$/', $holding['status'])) { $holding['holdable'] = 1; } else { $holding['holdable'] = 0; $holding['nonHoldableReason'] = "This item is not currently available for Patron Holds"; } if (!isset($holding['libraryDisplayName'])) { $holding['libraryDisplayName'] = $holding['location']; } //Get the location id for this holding $holding['locationCode'] = '?????'; foreach ($locationCodes as $locationCode => $holdingLabel) { if (strlen($locationCode) > 0 && preg_match("~{$holdingLabel}~i", $holding['location'])) { $holding['locationCode'] = $locationCode; } } if ($holding['locationCode'] == '?????') { $logger->log("Did not find location code for " . $holding['location'], PEAR_LOG_DEBUG); } if (array_key_exists($holding['locationCode'], $suppressedLocationCodes)) { $logger->log("Location " . $holding['locationCode'] . " is suppressed", PEAR_LOG_DEBUG); continue; } //Now that we have the location code, try to match with the marc record $holding['iType'] = 0; foreach ($marcItemData as $itemData) { if (!$itemData['matched']) { $locationMatched = strpos($itemData['location'], $holding['locationCode']) === 0; if (strlen($itemData['callnumber']) == 0 || strlen($holding['callnumber']) == 0) { $callNumberMatched = strlen($holding['callnumber']) == strlen($holding['callnumber']); } else { $callNumberMatched = strpos($itemData['callnumber'], $holding['callnumber']) >= 0; } if ($locationMatched && $callNumberMatched) { $holding['iType'] = $itemData['iType']; $itemData['matched'] = true; } } } //Check to see if this item can be held by the current patron. Only important when //we know what pType is in use and we are showing all items. if ($scope == 93 && $pType > 0) { //Never remove the title if it is owned by the current library (could be in library use only) if (isset($library) && strlen($library->ilsCode) > 0 && strpos($holding['locationCode'], $library->ilsCode) === 0) { $logger->log("Cannot remove holding because it belongs to the active library", PEAR_LOG_DEBUG); } else { if (!$this->driver->isItemHoldableToPatron($holding['locationCode'], $holding['iType'], $pType)) { $logger->log("Removing item {$holdingKey} because it is not usable by the current patronType {$pType}, iType is {$holding['iType']}, location is {$holding['locationCode']}", PEAR_LOG_DEBUG); //echo("Removing item $holdingKey because it is not usable by the current patronType $pType, iType is {$holding['iType']}, location is {$holding['locationCode']}"); unset($ret[$holdingKey]); continue; } } } //Set the hold queue length $holding['holdQueueLength'] = isset($holdQueueLength) ? $holdQueueLength : null; //Add the holding to the sorted array to determine $sortString = $holding['location'] . '-' . $i; //$sortString = $holding['location'] . $holding['callnumber']. $i; if (strlen($physicalBranch) > 0 && stripos($holding['location'], $physicalBranch) !== false) { //If the user is in a branch, those holdings come first. $holding['section'] = 'In this library'; $holding['sectionId'] = 1; $sorted_array['1' . $sortString] = $holding; } else { if (strlen($homeBranch) > 0 && stripos($holding['location'], $homeBranch) !== false) { //Next come the user's home branch if the user is logged in or has the home_branch cookie set. $holding['section'] = 'Your library'; $holding['sectionId'] = 2; $sorted_array['2' . $sortString] = $holding; } else { if (strlen($nearbyBranch1) > 0 && stripos($holding['location'], $nearbyBranch1) !== false) { //Next come nearby locations for the user $holding['section'] = 'Nearby Libraries'; $holding['sectionId'] = 3; $sorted_array['3' . $sortString] = $holding; } else { if (strlen($nearbyBranch2) > 0 && stripos($holding['location'], $nearbyBranch2) !== false) { //Next come nearby locations for the user $holding['section'] = 'Nearby Libraries'; $holding['sectionId'] = 4; $sorted_array['4' . $sortString] = $holding; } else { if (strlen($libraryLocationLabels) > 0 && preg_match($libraryLocationLabels, $holding['location'])) { //Next come any locations within the same system we are in. $holding['section'] = $library->displayName; $holding['sectionId'] = 5; $sorted_array['5' . $sortString] = $holding; } else { //Finally, all other holdings are shown sorted alphabetically. $holding['section'] = 'Other Locations'; $holding['sectionId'] = 6; $sorted_array['6' . $sortString] = $holding; } } } } } $i++; } $timer->logTime('finished processing holdings'); //Check to see if the title is holdable $holdable = $this->driver->isRecordHoldable($marcRecord); foreach ($sorted_array as $key => $holding) { $holding['holdable'] = $holdable ? 1 : 0; $sorted_array[$key] = $holding; } //Load order records, these only show in the full page view, not the item display $orderMatches = array(); if (preg_match_all('/<tr\\s+class="bibOrderEntry">.*?<td\\s*>(.*?)<\\/td>/s', $millenniumInfo->framesetInfo, $orderMatches)) { for ($i = 0; $i < count($orderMatches[1]); $i++) { $location = trim($orderMatches[1][$i]); $location = preg_replace('/\\sC\\d{3}[\\s\\.]/', '', $location); //Remove courier code if any $sorted_array['7' . $location . $i] = array('location' => $location, 'section' => 'On Order', 'sectionId' => 7, 'holdable' => 1); } } $timer->logTime('loaded order records'); ksort($sorted_array); //Check to see if we can remove the sections. //We can if all section keys are the same. $removeSection = true; $lastKeyIndex = ''; foreach ($sorted_array as $key => $holding) { $currentKey = substr($key, 0, 1); if ($lastKeyIndex == '') { $lastKeyIndex = $currentKey; } else { if ($lastKeyIndex != $currentKey) { $removeSection = false; break; } } } foreach ($sorted_array as $key => $holding) { if ($removeSection == true) { $holding['section'] = ''; $sorted_array[$key] = $holding; } } $issueSummaries = $this->driver->getIssueSummaries($millenniumInfo); $timer->logTime('loaded issue summaries'); if (!is_null($issueSummaries)) { krsort($sorted_array); //Group holdings under the issue issue summary that is related. foreach ($sorted_array as $key => $holding) { //Have issue summary = false $haveIssueSummary = false; $issueSummaryKey = null; foreach ($issueSummaries as $issueKey => $issueSummary) { if ($issueSummary['location'] == $holding['location']) { $haveIssueSummary = true; $issueSummaryKey = $issueKey; break; } } if ($haveIssueSummary) { $issueSummaries[$issueSummaryKey]['holdings'][strtolower($key)] = $holding; } else { //Need to automatically add a summary so we don't lose data $issueSummaries[$holding['location']] = array('location' => $holding['location'], 'type' => 'issue', 'holdings' => array(strtolower($key) => $holding)); } } foreach ($issueSummaries as $key => $issueSummary) { if (isset($issueSummary['holdings']) && is_array($issueSummary['holdings'])) { krsort($issueSummary['holdings']); $issueSummaries[$key] = $issueSummary; } } ksort($issueSummaries); return $issueSummaries; } else { return $sorted_array; } }
function getHoursAndLocations() { //Get a list of locations for the current library global $library; $tmpLocation = new Location(); $tmpLocation->libraryId = $library->libraryId; $tmpLocation->showInLocationsAndHoursList = 1; $tmpLocation->orderBy('displayName'); $libraryLocations = array(); $tmpLocation->find(); if ($tmpLocation->N == 0) { //Get all locations $tmpLocation = new Location(); $tmpLocation->showInLocationsAndHoursList = 1; $tmpLocation->orderBy('displayName'); $tmpLocation->find(); } while ($tmpLocation->fetch()) { $mapAddress = urlencode(preg_replace('/\\r\\n|\\r|\\n/', '+', $tmpLocation->address)); $clonedLocation = clone $tmpLocation; $hours = $clonedLocation->getHours(); foreach ($hours as $key => $hourObj) { if (!$hourObj->closed) { $hourString = $hourObj->open; list($hour, $minutes) = explode(':', $hourString); if ($hour < 12) { $hourObj->open .= ' AM'; } elseif ($hour == 12) { $hourObj->open = 'Noon'; } elseif ($hour == 24) { $hourObj->open = 'Midnight'; } else { $hour -= 12; $hourObj->open = "{$hour}:{$minutes} PM"; } $hourString = $hourObj->close; list($hour, $minutes) = explode(':', $hourString); if ($hour < 12) { $hourObj->close .= ' AM'; } elseif ($hour == 12) { $hourObj->close = 'Noon'; } elseif ($hour == 24) { $hourObj->close = 'Midnight'; } else { $hour -= 12; $hourObj->close = "{$hour}:{$minutes} PM"; } } $hours[$key] = $hourObj; } $libraryLocations[] = array('id' => $tmpLocation->locationId, 'name' => $tmpLocation->displayName, 'address' => preg_replace('/\\r\\n|\\r|\\n/', '<br/>', $tmpLocation->address), 'phone' => $tmpLocation->phone, 'map_image' => "http://maps.googleapis.com/maps/api/staticmap?center={$mapAddress}&zoom=15&size=200x200&sensor=false&markers=color:red%7C{$mapAddress}", 'map_link' => "http://maps.google.com/maps?f=q&hl=en&geocode=&q={$mapAddress}&ie=UTF8&z=15&iwloc=addr&om=1&t=m", 'hours' => $hours); } global $interface; $interface->assign('libraryLocations', $libraryLocations); return $interface->fetch('AJAX/libraryHoursAndLocations.tpl'); }
public function parseHoldsPage($pageContents) { //global $logger; $availableHolds = array(); $unavailableHolds = array(); $holds = array('available' => $availableHolds, 'unavailable' => $unavailableHolds); //Get the headers from the table preg_match_all('/<th\\s+class="patFuncHeaders">\\s*([\\w\\s]*?)\\s*<\\/th>/si', $pageContents, $result, PREG_SET_ORDER); $sKeys = array(); for ($matchi = 0; $matchi < count($result); $matchi++) { $sKeys[] = $result[$matchi][1]; } //Get the rows for the table preg_match_all('/<tr\\s+class="patFuncEntry(?: on_ice)?">(.*?)<\\/tr>/si', $pageContents, $result, PREG_SET_ORDER); $sRows = array(); for ($matchi = 0; $matchi < count($result); $matchi++) { $sRows[] = $result[$matchi][1]; } $sCount = 0; foreach ($sRows as $sRow) { preg_match_all('/<td[^>]*>(.*?)<\\/td>/si', $sRow, $result, PREG_SET_ORDER); $sCols = array(); for ($matchi = 0; $matchi < count($result); $matchi++) { $sCols[] = $result[$matchi][1]; } //$sCols = preg_split("/<t(h|d)([^>]*)>/",$sRow); $curHold = array(); $curHold['create'] = null; $curHold['reqnum'] = null; $curHold['holdSource'] = 'ILS'; //Holds page occasionally has a header with number of items checked out. for ($i = 0; $i < sizeof($sCols); $i++) { $sCols[$i] = str_replace(" ", " ", $sCols[$i]); $sCols[$i] = preg_replace("/<br+?>/", " ", $sCols[$i]); $sCols[$i] = html_entity_decode(trim($sCols[$i])); //print_r($scols[$i]); /*if ($sCount <= 1) { $sKeys[$i] = $sCols[$i]; } else if ($sCount > 1) {*/ if ($sKeys[$i] == "CANCEL") { //Only check Cancel key, not Cancel if not filled by //Extract the id from the checkbox $matches = array(); $numMatches = preg_match_all('/.*?cancel(.*?)x(\\d\\d).*/s', $sCols[$i], $matches); if ($numMatches > 0) { $curHold['renew'] = "BOX"; $curHold['cancelable'] = true; $curHold['itemId'] = $matches[1][0]; $curHold['xnum'] = $matches[2][0]; $curHold['cancelId'] = $matches[1][0] . '~' . $matches[2][0]; } else { $curHold['cancelable'] = false; } } if (stripos($sKeys[$i], "TITLE") > -1) { if (preg_match('/.*?<a href=\\"\\/record=(.*?)(?:~S\\d{1,2})\\">(.*?)<\\/a>.*/', $sCols[$i], $matches)) { $shortId = $matches[1]; $bibid = '.' . $matches[1] . $this->driver->getCheckDigit($shortId); $title = strip_tags($matches[2]); } elseif (preg_match('/.*<a href=".*?\\/record\\/C__R(.*?)\\?.*?">(.*?)<\\/a>.*/si', $sCols[$i], $matches)) { $shortId = $matches[1]; $bibid = '.' . $matches[1] . $this->driver->getCheckDigit($shortId); $title = strip_tags($matches[2]); } else { //This happens for prospector titles $bibid = ''; $shortId = ''; $title = trim($sCols[$i]); /*global $configArray; if ($configArray['System']['debug']){ echo("Unexpected format in title column. Got " . htmlentities($sCols[$i]) . "<br/>"); }*/ } $curHold['id'] = $bibid; $curHold['recordId'] = $bibid; $curHold['shortId'] = $shortId; $curHold['title'] = $title; } if (stripos($sKeys[$i], "Ratings") > -1) { $curHold['request'] = "STARS"; } if (stripos($sKeys[$i], "PICKUP LOCATION") > -1) { //Extract the current location for the hold if possible $matches = array(); if (preg_match('/<select\\s+name=loc(.*?)x(\\d\\d).*?<option\\s+value="([a-z]{1,5})[+ ]*"\\s+selected="selected">.*/s', $sCols[$i], $matches)) { $curHold['locationId'] = $matches[1]; $curHold['locationXnum'] = $matches[2]; $curPickupBranch = new Location(); $curPickupBranch->whereAdd("code = '{$matches[3]}'"); $curPickupBranch->find(1); if ($curPickupBranch->N > 0) { $curPickupBranch->fetch(); $curHold['currentPickupId'] = $curPickupBranch->locationId; $curHold['currentPickupName'] = $curPickupBranch->displayName; $curHold['location'] = $curPickupBranch->displayName; } $curHold['locationUpdateable'] = true; //Return the full select box for reference. $curHold['locationSelect'] = $sCols[$i]; } else { $curHold['location'] = $sCols[$i]; //Trim the carrier code if any if (preg_match('/.*\\s[\\w\\d]{4}/', $curHold['location'])) { $curHold['location'] = substr($curHold['location'], 0, strlen($curHold['location']) - 5); } $curHold['currentPickupName'] = $curHold['location']; $curHold['locationUpdateable'] = false; } } if (stripos($sKeys[$i], "STATUS") > -1) { $status = trim(strip_tags($sCols[$i])); $status = strtolower($status); $status = ucwords($status); if ($status != " ") { $curHold['status'] = $status; if (preg_match('/READY.*(\\d{2}-\\d{2}-\\d{2})/i', $status, $matches)) { $curHold['status'] = 'Ready'; //Get expiration date $exipirationDate = $matches[1]; $expireDate = DateTime::createFromFormat('m-d-y', $exipirationDate); $curHold['expire'] = $expireDate->getTimestamp(); } elseif (preg_match('/READY\\sFOR\\sPICKUP/i', $status, $matches)) { $curHold['status'] = 'Ready'; } else { $curHold['status'] = $status; } } else { $curHold['status'] = "Pending {$status}"; } $matches = array(); $curHold['renewError'] = false; if (preg_match('/.*DUE\\s(\\d{2}-\\d{2}-\\d{2}).*(?:<font color="red">\\s*(.*)<\\/font>).*/s', $sCols[$i], $matches)) { //Renew error $curHold['renewError'] = $matches[2]; $curHold['statusMessage'] = $matches[2]; } else { if (preg_match('/.*DUE\\s(\\d{2}-\\d{2}-\\d{2})\\s(.*)?/s', $sCols[$i], $matches)) { $curHold['statusMessage'] = $matches[2]; } } //$logger->log('Status for item ' . $curHold['id'] . '=' . $sCols[$i], PEAR_LOG_INFO); } if (stripos($sKeys[$i], "CANCEL IF NOT FILLED BY") > -1) { //$curHold['expire'] = strip_tags($scols[$i]); } if (stripos($sKeys[$i], "FREEZE") > -1) { $matches = array(); $curHold['frozen'] = false; if (preg_match('/<input.*name="freeze(.*?)"\\s*(\\w*)\\s*\\/>/', $sCols[$i], $matches)) { $curHold['freezeable'] = true; if (strlen($matches[2]) > 0) { $curHold['frozen'] = true; $curHold['status'] = 'Frozen'; } } elseif (preg_match('/This hold can\\s?not be frozen/i', $sCols[$i], $matches)) { //If we detect an error Freezing the hold, save it so we can report the error to the user later. $shortId = str_replace('.b', 'b', $curHold['id']); $_SESSION['freezeResult'][$shortId]['message'] = $sCols[$i]; $_SESSION['freezeResult'][$shortId]['result'] = false; } else { $curHold['freezeable'] = false; } } //} } //End of columns //if ($sCount > 1) { if (!isset($curHold['status']) || strcasecmp($curHold['status'], "ready") != 0) { $holds['unavailable'][] = $curHold; } else { $holds['available'][] = $curHold; } //} $sCount++; } //End of the row return $holds; }
public function parseHoldsPage($sResult) { global $logger; $availableHolds = array(); $unavailableHolds = array(); $holds = array('available' => $availableHolds, 'unavailable' => $unavailableHolds); $sResult = preg_replace("/<[^<]+?>\\W<[^<]+?>\\W\\d* HOLD.?\\W<[^<]+?>\\W<[^<]+?>/", "", $sResult); //$logger->log('Hold information = ' . $sresult, PEAR_LOG_INFO); $s = substr($sResult, stripos($sResult, 'patFunc')); $s = substr($s, strpos($s, ">") + 1); $s = substr($s, 0, stripos($s, "</table")); $s = preg_replace("/<br \\/>/", "", $s); $sRows = preg_split("/<tr([^>]*)>/", $s); $sCount = 0; $sKeys = array_pad(array(), 10, ""); foreach ($sRows as $sRow) { $sCols = preg_split("/<t(h|d)([^>]*)>/", $sRow); $curHold = array(); $curHold['create'] = null; $curHold['reqnum'] = null; //Holds page occassionally has a header with number of items checked out. for ($i = 0; $i < sizeof($sCols); $i++) { $sCols[$i] = str_replace(" ", " ", $sCols[$i]); $sCols[$i] = preg_replace("/<br+?>/", " ", $sCols[$i]); $sCols[$i] = html_entity_decode(trim(substr($sCols[$i], 0, stripos($sCols[$i], "</t")))); //print_r($scols[$i]); if ($sCount <= 1) { $sKeys[$i] = $sCols[$i]; } else { if ($sCount > 1) { if ($sKeys[$i] == "CANCEL") { //Only check Cancel key, not Cancel if not filled by //Extract the id from the checkbox $matches = array(); $numMatches = preg_match_all('/.*?cancel(.*?)x(\\d\\d).*/s', $sCols[$i], $matches); if ($numMatches > 0) { $curHold['renew'] = "BOX"; $curHold['cancelable'] = true; $curHold['itemId'] = $matches[1][0]; $curHold['xnum'] = $matches[2][0]; $curHold['cancelId'] = $matches[1][0] . '~' . $matches[2][0]; } else { $curHold['cancelable'] = false; } } if (stripos($sKeys[$i], "TITLE") > -1) { if (preg_match('/.*?<a href=\\"\\/record=(.*?)(?:~S\\d{1,2})\\">(.*?)<\\/a>.*/', $sCols[$i], $matches)) { $shortId = $matches[1]; $bibid = '.' . $matches[1]; //Technically, this isn't corrcect since the check digit is missing $title = $matches[2]; } else { $bibid = ''; $shortId = ''; $title = trim($sCols[$i]); } $curHold['id'] = $bibid; $curHold['shortId'] = $shortId; $curHold['title'] = $title; } if (stripos($sKeys[$i], "Ratings") > -1) { $curHold['request'] = "STARS"; } if (stripos($sKeys[$i], "PICKUP LOCATION") > -1) { //Extract the current location for the hold if possible $matches = array(); if (preg_match('/<select\\s+name=loc(.*?)x(\\d\\d).*?<option\\s+value="([a-z]{1,5})[+ ]*"\\s+selected="selected">.*/s', $sCols[$i], $matches)) { $curHold['locationId'] = $matches[1]; $curHold['locationXnum'] = $matches[2]; $curPickupBranch = new Location(); $curPickupBranch->whereAdd("code = '{$matches[3]}'"); $curPickupBranch->find(1); if ($curPickupBranch->N > 0) { $curPickupBranch->fetch(); $curHold['currentPickupId'] = $curPickupBranch->locationId; $curHold['currentPickupName'] = $curPickupBranch->displayName; $curHold['location'] = $curPickupBranch->displayName; } $curHold['locationUpdateable'] = true; //Return the full select box for reference. $curHold['locationSelect'] = $sCols[$i]; } else { $curHold['location'] = $sCols[$i]; //Trim the carrier code if any if (preg_match('/.*\\s[\\w\\d]{4}/', $curHold['location'])) { $curHold['location'] = substr($curHold['location'], 0, strlen($curHold['location']) - 5); } $curHold['currentPickupName'] = $curHold['location']; $curHold['locationUpdateable'] = false; } } if (stripos($sKeys[$i], "STATUS") > -1) { $status = trim(strip_tags($sCols[$i])); $status = strtolower($status); $status = ucwords($status); if ($status != " ") { $curHold['status'] = $status; if (preg_match('/READY.*(\\d{2}-\\d{2}-\\d{2})/i', $status, $matches)) { $curHold['status'] = 'Ready'; //Get expiration date $exipirationDate = $matches[1]; $expireDate = DateTime::createFromFormat('m-d-y', $exipirationDate); $curHold['expire'] = $expireDate->getTimestamp(); } elseif (preg_match('/READY\\sFOR\\sPICKUP/i', $status, $matches)) { $curHold['status'] = 'Ready'; } else { $curHold['status'] = $status; } } else { $curHold['status'] = "Pending {$status}"; } $matches = array(); $curHold['renewError'] = false; if (preg_match('/.*DUE\\s(\\d{2}-\\d{2}-\\d{2}).*(?:<font color="red">\\s*(.*)<\\/font>).*/s', $sCols[$i], $matches)) { //Renew error $curHold['renewError'] = $matches[2]; $curHold['statusMessage'] = $matches[2]; } else { if (preg_match('/.*DUE\\s(\\d{2}-\\d{2}-\\d{2})\\s(.*)?/s', $sCols[$i], $matches)) { $curHold['statusMessage'] = $matches[2]; } } $logger->log('Status for item ' . $curHold['id'] . '=' . $sCols[$i], PEAR_LOG_INFO); } if (stripos($sKeys[$i], "CANCEL IF NOT FILLED BY") > -1) { //$curHold['expire'] = strip_tags($scols[$i]); } if (stripos($sKeys[$i], "FREEZE") > -1) { $matches = array(); $curHold['frozen'] = false; if (preg_match('/<input.*name="freeze(.*?)"\\s*(\\w*)\\s*\\/>/', $sCols[$i], $matches)) { $curHold['freezeable'] = true; if (strlen($matches[2]) > 0) { $curHold['frozen'] = true; $curHold['status'] = 'Frozen'; } } elseif (preg_match('/This hold can\\s?not be frozen/i', $sCols[$i], $matches)) { //If we detect an error Freezing the hold, save it so we can report the error to the user later. $shortId = str_replace('.b', 'b', $curHold['id']); $_SESSION['freezeResult'][$shortId]['message'] = $sCols[$i]; $_SESSION['freezeResult'][$shortId]['result'] = false; } else { $curHold['freezeable'] = false; } } } } } //End of columns if ($sCount > 1) { if (!isset($curHold['status']) || strcasecmp($curHold['status'], "ready") != 0) { $holds['unavailable'][] = $curHold; } else { $holds['available'][] = $curHold; } } $sCount++; } //End of the row return $holds; }
<?php require_once dirname(dirname(__FILE__)) . '/models/config.php'; $reports = json_decode(CallAPI("GET", "https://people.cs.clemson.edu/~jacksod/api/v1/reports?filter=new"), true)['data']; //expand report location and person to show details, not just ID if (is_array($reports)) { for ($i = 0; $i < count($reports); $i++) { $person = new Person(); $person->fetch($reports[$i]['personID']); $reports[$i]['personKind'] = $person->getPersonKindName(); $reports[$i]['personName'] = $person->getName(); $reports[$i]['personUsername'] = $person->getUsername(); $reports[$i]['personPhone'] = $person->getPhone(); $location = new Location(); $location->fetch($reports[$i]['locationID']); $reports[$i]['locationBuilding'] = $location->getBuildingName(); $reports[$i]['locationRoom'] = $location->getRoom(); } } //var_dump($reports); ?> <?php include 'header.php'; ?> <!-- in .container div --> <div class='row'> <div class='col-sm-12'> <div class="page-header">
function building() { //Get the user home library $user = new User(); $user->id = $this->user_id; $user->find(true); //get the home location $homeLocation = new Location(); $homeLocation->locationId = $user->homeLocationId; $homeLocation->find(true); //If the user is scoped to just see holdings for their location, only make the list available for that location //unless the user a library admin $scopeToLocation = false; if ($homeLocation->useScope == 1 && $homeLocation->restrictSearchByLocation) { if ($user->hasRole('opacAdmin') || $user->hasRole('libraryAdmin')) { $scopeToLocation = false; } else { $scopeToLocation = true; } } $buildings = array(); if ($scopeToLocation) { //publish to all locations $buildings[] = $homeLocation->facetLabel; } else { //publish to all locations for the library $location = new Location(); $location->libraryId = $homeLocation->libraryId; $location->find(); while ($location->fetch()) { $buildings[] = $location->facetLabel; } } return $buildings; }
/** * Process facets from the results object * * @access public * @param array $filter Array of field => on-screen description * listing all of the desired facet fields; * set to null to get all configured values. * @param bool $expandingLinks If true, we will include expanding URLs * (i.e. get all matches for a facet, not * just a limit to the current search) in * the return array. * @return array Facets data arrays */ public function getFacetList($filter = null, $expandingLinks = false) { // If there is no filter, we'll use all facets as the filter: if (is_null($filter)) { $filter = $this->facetConfig; } // Start building the facet list: $list = array(); // If we have no facets to process, give up now if (!isset($this->indexResult['facet_counts'])) { return $list; } elseif (!is_array($this->indexResult['facet_counts']['facet_fields']) && !is_array($this->indexResult['facet_counts']['facet_dates'])) { return $list; } // Loop through every field returned by the result set $validFields = array_keys($filter); global $locationSingleton; /** @var Library $currentLibrary */ $currentLibrary = Library::getActiveLibrary(); $activeLocationFacet = null; $activeLocation = $locationSingleton->getActiveLocation(); if (!is_null($activeLocation)) { $activeLocationFacet = $activeLocation->facetLabel; } $relatedLocationFacets = null; $relatedHomeLocationFacets = null; $additionalAvailableAtLocations = null; if (!is_null($currentLibrary)) { $relatedLocationFacets = $locationSingleton->getLocationsFacetsForLibrary($currentLibrary->libraryId); if (strlen($currentLibrary->additionalLocationsToShowAvailabilityFor) > 0) { $locationsToLookfor = explode('|', $currentLibrary->additionalLocationsToShowAvailabilityFor); $location = new Location(); $location->whereAddIn('code', $locationsToLookfor, 'string'); $location->find(); $additionalAvailableAtLocations = array(); while ($location->fetch()) { $additionalAvailableAtLocations[] = $location->facetLabel; } } } $homeLibrary = Library::getPatronHomeLibrary(); if (!is_null($homeLibrary)) { $relatedHomeLocationFacets = $locationSingleton->getLocationsFacetsForLibrary($homeLibrary->libraryId); } $allFacets = array_merge($this->indexResult['facet_counts']['facet_fields'], $this->indexResult['facet_counts']['facet_dates']); foreach ($allFacets as $field => $data) { // Skip filtered fields and empty arrays: if (!in_array($field, $validFields) || count($data) < 1) { continue; } // Initialize the settings for the current field $list[$field] = array(); // Add the on-screen label $list[$field]['label'] = $filter[$field]; // Build our array of values for this field $list[$field]['list'] = array(); $foundInstitution = false; $doInstitutionProcessing = false; $foundBranch = false; $doBranchProcessing = false; //Marmot specific processing to do custom resorting of facets. if ($field == 'owning_library' && isset($currentLibrary) && !is_null($currentLibrary)) { $doInstitutionProcessing = true; } if ($field == 'owning_location' && (!is_null($relatedLocationFacets) || !is_null($activeLocationFacet))) { $doBranchProcessing = true; } elseif ($field == 'available_at') { $doBranchProcessing = true; } // Should we translate values for the current facet? $translate = in_array($field, $this->translatedFacets); $numValidRelatedLocations = 0; $numValidLibraries = 0; // Loop through values: foreach ($data as $facet) { // Initialize the array of data about the current facet: $currentSettings = array(); $currentSettings['value'] = $facet[0]; $currentSettings['display'] = $translate ? translate($facet[0]) : $facet[0]; $currentSettings['count'] = $facet[1]; $currentSettings['isApplied'] = false; $currentSettings['url'] = $this->renderLinkWithFilter("{$field}:" . $facet[0]); // If we want to have expanding links (all values matching the facet) // in addition to limiting links (filter current search with facet), // do some extra work: if ($expandingLinks) { $currentSettings['expandUrl'] = $this->getExpandingFacetLink($field, $facet[0]); } // Is this field a current filter? if (in_array($field, array_keys($this->filterList))) { // and is this value a selected filter? if (in_array($facet[0], $this->filterList[$field])) { $currentSettings['isApplied'] = true; $currentSettings['removalUrl'] = $this->renderLinkWithoutFilter("{$field}:{$facet[0]}"); } } //Setup the key to allow sorting alphabetically if needed. $valueKey = $facet[0]; $okToAdd = true; if ($doInstitutionProcessing) { //Special processing for Marmot digital library if ($facet[0] == $currentLibrary->facetLabel) { $valueKey = '1' . $valueKey; $numValidLibraries++; $foundInstitution = true; } elseif ($facet[0] == $currentLibrary->facetLabel . ' Online') { $valueKey = '1' . $valueKey; $foundInstitution = true; $numValidLibraries++; } elseif ($facet[0] == $currentLibrary->facetLabel . ' On Order' || $facet[0] == $currentLibrary->facetLabel . ' Under Consideration') { $valueKey = '1' . $valueKey; $foundInstitution = true; $numValidLibraries++; } elseif ($facet[0] == 'Digital Collection' || $facet[0] == 'Marmot Digital Library') { $valueKey = '2' . $valueKey; $foundInstitution = true; $numValidLibraries++; } else { if (!is_null($currentLibrary) && $currentLibrary->restrictOwningBranchesAndSystems == 1) { $okToAdd = false; } } } else { if ($doBranchProcessing) { if (strlen($facet[0]) > 0) { if ($activeLocationFacet != null && $facet[0] == $activeLocationFacet) { $valueKey = '1' . $valueKey; $foundBranch = true; $numValidRelatedLocations++; } elseif (isset($currentLibrary) && $facet[0] == $currentLibrary->facetLabel . ' Online') { $valueKey = '1' . $valueKey; $numValidRelatedLocations++; } elseif (isset($currentLibrary) && ($facet[0] == $currentLibrary->facetLabel . ' On Order' || $facet[0] == $currentLibrary->facetLabel . ' Under Consideration')) { $valueKey = '1' . $valueKey; $numValidRelatedLocations++; } else { if (!is_null($relatedLocationFacets) && in_array($facet[0], $relatedLocationFacets)) { $valueKey = '2' . $valueKey; $numValidRelatedLocations++; } else { if (!is_null($relatedLocationFacets) && in_array($facet[0], $relatedLocationFacets)) { $valueKey = '2' . $valueKey; $numValidRelatedLocations++; } else { if (!is_null($relatedHomeLocationFacets) && in_array($facet[0], $relatedHomeLocationFacets)) { $valueKey = '2' . $valueKey; $numValidRelatedLocations++; } elseif (!is_null($currentLibrary) && $facet[0] == $currentLibrary->facetLabel . ' Online') { $valueKey = '3' . $valueKey; $numValidRelatedLocations++; } else { if ($field == 'available_at' && !is_null($additionalAvailableAtLocations) && in_array($facet[0], $additionalAvailableAtLocations)) { $valueKey = '4' . $valueKey; $numValidRelatedLocations++; } elseif ($facet[0] == 'Marmot Digital Library' || $facet[0] == 'Digital Collection' || $facet[0] == 'OverDrive' || $facet[0] == 'Online') { $valueKey = '5' . $valueKey; $numValidRelatedLocations++; } else { if (!is_null($currentLibrary) && $currentLibrary->restrictOwningBranchesAndSystems == 1) { $okToAdd = false; } } } } } } } } } // Store the collected values: if ($okToAdd) { $list[$field]['list'][$valueKey] = $currentSettings; } } if (!$foundInstitution && $doInstitutionProcessing) { $list[$field]['list']['1' . $currentLibrary->facetLabel] = array('value' => $currentLibrary->facetLabel, 'display' => $currentLibrary->facetLabel, 'count' => 0, 'isApplied' => false, 'url' => null, 'expandUrl' => null); } if (!$foundBranch && $doBranchProcessing && !is_null($activeLocationFacet)) { $list[$field]['list']['1' . $activeLocationFacet] = array('value' => $activeLocationFacet, 'display' => $activeLocationFacet, 'count' => 0, 'isApplied' => false, 'url' => null, 'expandUrl' => null); $numValidRelatedLocations++; } //How many facets should be shown by default //Only show one system unless we are in the global scope if ($field == 'owning_library' && isset($currentLibrary)) { $list[$field]['valuesToShow'] = $numValidLibraries; } else { if ($field == 'owning_location' && isset($relatedLocationFacets) && $numValidRelatedLocations > 0) { $list[$field]['valuesToShow'] = $numValidRelatedLocations; } else { if ($field == 'available_at') { $list[$field]['valuesToShow'] = count($list[$field]['list']); } else { $list[$field]['valuesToShow'] = 5; } } } //Sort the facet alphabetically? //Sort the system and location alphabetically unless we are in the global scope if (in_array($field, array('owning_library', 'owning_location', 'available_at')) && isset($currentLibrary)) { $list[$field]['showAlphabetically'] = true; } else { $list[$field]['showAlphabetically'] = false; } if ($list[$field]['showAlphabetically']) { ksort($list[$field]['list']); } } return $list; }
function launch() { global $configArray; global $interface; global $user; //Load status information $materialsRequestStatus = new MaterialsRequestStatus(); $materialsRequestStatus->orderBy('isDefault DESC, isOpen DESC, description ASC'); if ($user->hasRole('library_material_requests')) { $homeLibrary = Library::getPatronHomeLibrary(); $materialsRequestStatus->libraryId = $homeLibrary->libraryId; } else { $libraryList[-1] = 'Default'; } $materialsRequestStatus->find(); $allStatuses = array(); $availableStatuses = array(); $defaultStatusesToShow = array(); while ($materialsRequestStatus->fetch()) { $availableStatuses[$materialsRequestStatus->id] = $materialsRequestStatus->description; $allStatuses[$materialsRequestStatus->id] = clone $materialsRequestStatus; if ($materialsRequestStatus->isOpen == 1 || $materialsRequestStatus->isDefault == 1) { $defaultStatusesToShow[] = $materialsRequestStatus->id; } } $interface->assign('availableStatuses', $availableStatuses); if (isset($_REQUEST['statusFilter'])) { $statusesToShow = $_REQUEST['statusFilter']; $_SESSION['materialsRequestStatusFilter'] = $statusesToShow; } elseif (isset($_SESSION['materialsRequestStatusFilter'])) { $statusesToShow = $_SESSION['materialsRequestStatusFilter']; } else { $statusesToShow = $defaultStatusesToShow; } $interface->assign('statusFilter', $statusesToShow); //Process status change if needed if (isset($_REQUEST['updateStatus']) && isset($_REQUEST['select'])) { //Look for which titles should be modified $selectedRequests = $_REQUEST['select']; $statusToSet = $_REQUEST['newStatus']; require_once ROOT_DIR . '/sys/Mailer.php'; $mail = new VuFindMailer(); foreach ($selectedRequests as $requestId => $selected) { $materialRequest = new MaterialsRequest(); $materialRequest->id = $requestId; if ($materialRequest->find(true)) { $materialRequest->status = $statusToSet; $materialRequest->dateUpdated = time(); $materialRequest->update(); if ($allStatuses[$statusToSet]->sendEmailToPatron == 1 && $materialRequest->email) { $body = '*****This is an auto-generated email response. Please do not reply.*****'; $body .= "\r\n" . $allStatuses[$statusToSet]->emailTemplate; //Replace tags with appropriate values $materialsRequestUser = new User(); $materialsRequestUser->id = $materialRequest->createdBy; $materialsRequestUser->find(true); foreach ($materialsRequestUser as $fieldName => $fieldValue) { if (!is_array($fieldValue)) { $body = str_replace('{' . $fieldName . '}', $fieldValue, $body); } } foreach ($materialRequest as $fieldName => $fieldValue) { if (!is_array($fieldValue)) { $body = str_replace('{' . $fieldName . '}', $fieldValue, $body); } } $materialsRequestUser->find(true); $mail->send($materialRequest->email, $configArray['Site']['email'], "Your Materials Request Update", $body, $configArray['Site']['email']); } } } } $availableFormats = MaterialsRequest::getFormats(); $interface->assign('availableFormats', $availableFormats); $defaultFormatsToShow = array_keys($availableFormats); if (isset($_REQUEST['formatFilter'])) { $formatsToShow = $_REQUEST['formatFilter']; $_SESSION['materialsRequestFormatFilter'] = $formatsToShow; } elseif (isset($_SESSION['materialsRequestFormatFilter'])) { $formatsToShow = $_SESSION['materialsRequestFormatFilter']; } else { $formatsToShow = $defaultFormatsToShow; } $interface->assign('formatFilter', $formatsToShow); //Get a list of all materials requests for the user $allRequests = array(); if ($user) { $materialsRequests = new MaterialsRequest(); $materialsRequests->joinAdd(new Location(), "LEFT"); $materialsRequests->joinAdd(new MaterialsRequestStatus()); $materialsRequests->joinAdd(new User(), 'INNER', 'user'); $materialsRequests->selectAdd(); $materialsRequests->selectAdd('materials_request.*, description as statusLabel, location.displayName as location, firstname, lastname, ' . $configArray['Catalog']['barcodeProperty'] . ' as barcode'); if ($user->hasRole('library_material_requests')) { //Need to limit to only requests submitted for the user's home location $userHomeLibrary = Library::getPatronHomeLibrary(); $locations = new Location(); $locations->libraryId = $userHomeLibrary->libraryId; $locations->find(); $locationsForLibrary = array(); while ($locations->fetch()) { $locationsForLibrary[] = $locations->locationId; } $materialsRequests->whereAdd('user.homeLocationId IN (' . implode(', ', $locationsForLibrary) . ')'); } if (count($availableStatuses) > count($statusesToShow)) { $statusSql = ""; foreach ($statusesToShow as $status) { if (strlen($statusSql) > 0) { $statusSql .= ","; } $statusSql .= "'" . $materialsRequests->escape($status) . "'"; } $materialsRequests->whereAdd("status in ({$statusSql})"); } if (count($availableFormats) > count($formatsToShow)) { //At least one format is disabled $formatSql = ""; foreach ($formatsToShow as $format) { if (strlen($formatSql) > 0) { $formatSql .= ","; } $formatSql .= "'" . $materialsRequests->escape($format) . "'"; } $materialsRequests->whereAdd("format in ({$formatSql})"); } //Add filtering by date as needed if (isset($_REQUEST['startDate']) && strlen($_REQUEST['startDate']) > 0) { $startDate = strtotime($_REQUEST['startDate']); $materialsRequests->whereAdd("dateCreated >= {$startDate}"); $interface->assign('startDate', $_REQUEST['startDate']); } if (isset($_REQUEST['endDate']) && strlen($_REQUEST['endDate']) > 0) { $endDate = strtotime($_REQUEST['endDate']); $materialsRequests->whereAdd("dateCreated <= {$endDate}"); $interface->assign('endDate', $_REQUEST['endDate']); } $materialsRequests->find(); while ($materialsRequests->fetch()) { $allRequests[] = clone $materialsRequests; } } else { $interface->assign('error', "You must be logged in to manage requests."); } $interface->assign('allRequests', $allRequests); if (isset($_REQUEST['exportSelected'])) { $this->exportToExcel($_REQUEST['select'], $allRequests); } else { $interface->setTemplate('manageRequests.tpl'); $interface->setPageTitle('Manage Materials Requests'); $interface->display('layout.tpl'); } }
/** * Load status (holdings) for a record and filter them based on the logged in user information. * * Format of return array is: * key = {section#}{location}-### where ### is the holding iteration * * value = array ( * id = The id of the bib * number = The position of the holding within the original list of holdings * section = A description of the section * sectionId = a numeric id of the section for sorting * type = holding * status * statusfull * availability * holdable * nonHoldableReason * reserve * holdQueueLength * duedate * location * libraryDisplayName * locationCode * locationLink * callnumber * link = array * linkText * isDownload * ) * * Includes both physical titles as well as titles on order * * @param string $id the id of the record * @return array A list of holdings for the record */ public function getHolding($id) { if (array_key_exists($id, HorizonAPI::$loadedStatus)) { return HorizonAPI::$loadedStatus[$id]; } global $configArray; global $library; //Get location information so we can put things into sections global $locationSingleton; /** @var $locationSingleton Location */ $physicalLocation = $locationSingleton->getPhysicalLocation(); if ($physicalLocation != null) { $physicalBranch = $physicalLocation->holdingBranchLabel; } else { $physicalBranch = ''; } $homeBranch = ''; $homeBranchId = 0; $nearbyBranch1 = ''; $nearbyBranch1Id = 0; $nearbyBranch2 = ''; $nearbyBranch2Id = 0; //Set location information based on the user login. This will override information based if (isset($user) && $user != false) { $homeBranchId = $user->homeLocationId; $nearbyBranch1Id = $user->myLocation1Id; $nearbyBranch2Id = $user->myLocation2Id; } else { //Check to see if the cookie for home location is set. if (isset($_COOKIE['home_location']) && is_numeric($_COOKIE['home_location'])) { $cookieLocation = new Location(); $locationId = $_COOKIE['home_location']; $cookieLocation->whereAdd("locationId = '{$locationId}'"); $cookieLocation->find(); if ($cookieLocation->N == 1) { $cookieLocation->fetch(); $homeBranchId = $cookieLocation->locationId; $nearbyBranch1Id = $cookieLocation->nearbyLocation1; $nearbyBranch2Id = $cookieLocation->nearbyLocation2; } } } //Load the holding label for the user's home location. $userLocation = new Location(); $userLocation->whereAdd("locationId = '{$homeBranchId}'"); $userLocation->find(); if ($userLocation->N == 1) { $userLocation->fetch(); $homeBranch = $userLocation->holdingBranchLabel; } //Load nearby branch 1 $nearbyLocation1 = new Location(); $nearbyLocation1->whereAdd("locationId = '{$nearbyBranch1Id}'"); $nearbyLocation1->find(); if ($nearbyLocation1->N == 1) { $nearbyLocation1->fetch(); $nearbyBranch1 = $nearbyLocation1->holdingBranchLabel; } //Load nearby branch 2 $nearbyLocation2 = new Location(); $nearbyLocation2->whereAdd(); $nearbyLocation2->whereAdd("locationId = '{$nearbyBranch2Id}'"); $nearbyLocation2->find(); if ($nearbyLocation2->N == 1) { $nearbyLocation2->fetch(); $nearbyBranch2 = $nearbyLocation2->holdingBranchLabel; } //Get a list of items from Horizon $lookupTitleInfoUrl = $configArray['Catalog']['webServiceUrl'] . '/standard/lookupTitleInfo?clientID=' . $configArray['Catalog']['clientId'] . '&titleKey=' . $id . '&includeItemInfo=true&includeHoldCount=true'; $lookupTitleInfoResponse = $this->getWebServiceResponse($lookupTitleInfoUrl); $holdings = array(); if ($lookupTitleInfoResponse->titleInfo) { $i = 0; foreach ($lookupTitleInfoResponse->titleInfo->itemInfo as $itemInfo) { if (!isset($itemInfo->locationID)) { //Suppress anything without a location code continue; } $i++; $holding = array('id' => $id, 'number' => $i++, 'type' => 'holding', 'status' => isset($itemInfo->statusID) ? (string) $itemInfo->statusID : 'Unknown', 'statusfull' => isset($itemInfo->statusDescription) ? (string) $itemInfo->statusDescription : 'Unknown', 'availability' => isset($itemInfo->available) ? (string) $itemInfo->available == "true" : false, 'holdable' => true, 'reserve' => 'N', 'holdQueueLength' => (int) $lookupTitleInfoResponse->titleInfo->holdCount, 'dueDate' => isset($itemInfo->dueDate) ? (string) $itemInfo->dueDate : 'Unknown', 'locationCode' => (string) $itemInfo->locationID, 'location' => (string) $itemInfo->locationDescription, 'callnumber' => (string) $itemInfo->callNumber, 'isDownload' => false, 'barcode' => (string) $itemInfo->barcode, 'isLocalItem' => false, 'isLibraryItem' => true, 'locationLabel' => (string) $itemInfo->locationDescription, 'shelfLocation' => (string) $itemInfo->locationDescription); $holding['groupedStatus'] = mapValue('item_grouped_status', $holding['status']); $paddedNumber = str_pad($i, 3, '0', STR_PAD_LEFT); $sortString = $holding['location'] . '-' . $paddedNumber; //$sortString = $holding['location'] . $holding['callnumber']. $i; if (strlen($physicalBranch) > 0 && stripos($holding['location'], $physicalBranch) !== false) { //If the user is in a branch, those holdings come first. $holding['section'] = 'In this library'; $holding['sectionId'] = 1; $holding['isLocalItem'] = true; $sorted_array['1' . $sortString] = $holding; } else { if (strlen($homeBranch) > 0 && stripos($holding['location'], $homeBranch) !== false) { //Next come the user's home branch if the user is logged in or has the home_branch cookie set. $holding['section'] = 'Your library'; $holding['sectionId'] = 2; $holding['isLocalItem'] = true; $sorted_array['2' . $sortString] = $holding; } else { if (strlen($nearbyBranch1) > 0 && stripos($holding['location'], $nearbyBranch1) !== false) { //Next come nearby locations for the user $holding['section'] = 'Nearby Libraries'; $holding['sectionId'] = 3; $sorted_array['3' . $sortString] = $holding; } else { if (strlen($nearbyBranch2) > 0 && stripos($holding['location'], $nearbyBranch2) !== false) { //Next come nearby locations for the user $holding['section'] = 'Nearby Libraries'; $holding['sectionId'] = 4; $sorted_array['4' . $sortString] = $holding; //MDN 11/17 - taken out because all Horizon libraries are single institution (so far) /*} else if (strlen($libraryLocationLabels) > 0 && preg_match($libraryLocationLabels, $holding['location'])){ //Next come any locations within the same system we are in. $holding['section'] = $library->displayName; $holding['sectionId'] = 5; $sorted_array['5' . $sortString] = $holding; */ } else { //Finally, all other holdings are shown sorted alphabetically. $holding['section'] = $library->displayName; $holding['sectionId'] = 5; $sorted_array['5' . $sortString] = $holding; } } } } $holdings[] = $holding; } } return $holdings; }
private static function getSearchSourcesDefault() { $searchOptions = array(); //Check to see if marmot catalog is a valid option global $library; global $interface; $repeatSearchSetting = ''; $repeatInWorldCat = false; $repeatInProspector = true; $repeatInAmazon = true; $repeatInOverdrive = false; $systemsToRepeatIn = array(); $searchGenealogy = true; $repeatCourseReserves = false; /** @var $locationSingleton Location */ global $locationSingleton; $location = $locationSingleton->getActiveLocation(); if ($location != null && $location->useScope && $location->restrictSearchByLocation) { $repeatSearchSetting = $location->repeatSearchOption; $repeatInWorldCat = $location->repeatInWorldCat == 1; $repeatInProspector = $location->repeatInProspector == 1; $repeatInOverdrive = $location->repeatInOverdrive == 1; if (strlen($location->systemsToRepeatIn) > 0) { $systemsToRepeatIn = explode('|', $location->systemsToRepeatIn); } else { $systemsToRepeatIn = explode('|', $library->systemsToRepeatIn); } } elseif (isset($library)) { $repeatSearchSetting = $library->repeatSearchOption; $repeatInWorldCat = $library->repeatInWorldCat == 1; $repeatInProspector = $library->repeatInProspector == 1; $repeatInOverdrive = $library->repeatInOverdrive == 1; $systemsToRepeatIn = explode('|', $library->systemsToRepeatIn); } if (isset($library)) { $repeatInAmazon = $library->repeatInAmazon; $searchGenealogy = $library->enableGenealogy; $repeatCourseReserves = $library->enableCourseReserves == 1; } $marmotAdded = false; //Local search if (isset($location) && $location != null && $location->useScope && $location->restrictSearchByLocation) { $searchOptions['local'] = array('name' => $location->displayName, 'description' => "The {$location->displayName} catalog."); } elseif (isset($library)) { $searchOptions['local'] = array('name' => $library->displayName, 'description' => "The {$library->displayName} catalog."); } else { $marmotAdded = true; $searchOptions['local'] = array('name' => 'Marmot Catalog', 'description' => "The entire Marmot catalog."); } if ($location != null && ($repeatSearchSetting == 'marmot' || $repeatSearchSetting == 'librarySystem') && ($location->useScope && $location->restrictSearchByLocation)) { $searchOptions[$library->subdomain] = array('name' => $library->displayName, 'description' => "The entire {$library->displayName} catalog not limited to a particular branch."); } //Process additional systems to repeat in if (count($systemsToRepeatIn) > 0) { foreach ($systemsToRepeatIn as $system) { if (strlen($system) > 0) { $repeatInLibrary = new Library(); $repeatInLibrary->subdomain = $system; $repeatInLibrary->find(); if ($repeatInLibrary->N == 1) { $repeatInLibrary->fetch(); $searchOptions[$repeatInLibrary->subdomain] = array('name' => $repeatInLibrary->displayName, 'description' => ''); } else { //See if this is a repeat within a location $repeatInLocation = new Location(); $repeatInLocation->code = $system; $repeatInLocation->find(); if ($repeatInLocation->N == 1) { $repeatInLocation->fetch(); $searchOptions[$repeatInLocation->code] = array('name' => $repeatInLocation->displayName, 'description' => ''); } } } } } //eContent Search $searchOptions['econtent'] = array('name' => 'Online Collection', 'description' => 'Digital Media available for use online and with portable devices'); //Marmot Global search if (isset($library) && $repeatSearchSetting == 'marmot' && $library->restrictSearchByLibrary && $marmotAdded == false) { $searchOptions['marmot'] = array('name' => 'Marmot Catalog', 'description' => 'A shared catalog of public, academic, and school libraries on the Western Slope.'); } //Genealogy Search if ($searchGenealogy && !$interface->isMobile()) { $searchOptions['genealogy'] = array('name' => 'Genealogy Records', 'description' => 'Genealogy Records from Colorado'); } //Overdrive if ($repeatInOverdrive && !$interface->isMobile()) { $searchOptions['overdrive'] = array('name' => 'OverDrive Digital Catalog', 'description' => 'Downloadable Books, Videos, Music, and eBooks with free use for library card holders.', 'external' => true); } if ($repeatInProspector && !$interface->isMobile()) { $searchOptions['prospector'] = array('name' => 'Prospector Catalog', 'description' => 'A shared catalog of academic, public, and special libraries all over Colorado.', 'external' => true); } //Course reserves for colleges if ($repeatCourseReserves) { //Mesa State $searchOptions['course-reserves-course-name'] = array('name' => 'Course Reserves by Name or Number', 'description' => 'Search course reserves by course name or number', 'external' => true); $searchOptions['course-reserves-instructor'] = array('name' => 'Course Reserves by Instructor', 'description' => 'Search course reserves by professor, lecturer, or instructor name', 'external' => true); } if ($repeatInWorldCat && !$interface->isMobile()) { $searchOptions['worldcat'] = array('name' => 'WorldCat', 'description' => 'A shared catalog of libraries all over the world.', 'external' => true); } //Check to see if Gold Rush is a valid option if (isset($library) && strlen($library->goldRushCode) > 0 && !$interface->isMobile()) { $searchOptions['goldrush'] = array('name' => 'Gold Rush Magazine Finder', 'description' => 'A catalog of online journals and full text articles.', 'external' => true); } if ($repeatInAmazon && !$interface->isMobile()) { $searchOptions['amazon'] = array('name' => 'Amazon', 'description' => 'Online retailer selling a wide variety of books, movies, music, and more.', 'external' => true); } return $searchOptions; }
/** * Load status (holdings) for a record and filter them based on the logged in user information. * * Format of return array is: * key = {section#}{location}-### where ### is the holding iteration * * value = array ( * id = The id of the bib * number = The position of the holding within the original list of holdings * section = A description of the section * sectionId = a numeric id of the section for sorting * type = holding * status * statusfull * availability * holdable * nonHoldableReason * reserve * holdQueueLength * duedate * location * libraryDisplayName * locationLink * callnumber * link = array * linkText * isDownload * ) * * Includes both physical titles as well as titles on order * * @param string $id the id of the record * @return array A list of holdings for the record */ public function getStatus($id) { if (array_key_exists($id, MillenniumStatusLoader::$loadedStatus)) { return MillenniumStatusLoader::$loadedStatus[$id]; } global $library; global $user; global $timer; global $logger; global $configArray; $pType = $this->driver->getPType(); $scope = $this->driver->getMillenniumScope(); if (!$configArray['Catalog']['offline']) { //Get information about holdings, order information, and issue information $millenniumInfo = $this->driver->getMillenniumRecordInfo($id); //Get the number of holds if ($millenniumInfo->framesetInfo) { if (preg_match('/(\\d+) hold(s?) on .*? of \\d+ (copies|copy)/', $millenniumInfo->framesetInfo, $matches)) { $holdQueueLength = $matches[1]; } else { $holdQueueLength = 0; } } // Load Record Page $r = substr($millenniumInfo->holdingsInfo, stripos($millenniumInfo->holdingsInfo, 'bibItems')); $r = substr($r, strpos($r, ">") + 1); $r = substr($r, 0, stripos($r, "</table")); $rows = preg_split("/<tr([^>]*)>/", $r); } else { $rows = array(); $millenniumInfo = null; } //Load item information from marc record $matchItemsWithMarcItems = $configArray['Catalog']['matchItemsWithMarcItems']; if ($matchItemsWithMarcItems) { // Load the full marc record so we can get the iType for each record. $marcRecord = MarcLoader::loadMarcRecordByILSId($id); $marcItemField = isset($configArray['Reindex']['itemTag']) ? $configArray['Reindex']['itemTag'] : '989'; $itemFields = $marcRecord->getFields($marcItemField); $marcItemData = array(); //TODO: Don't hardcode item subfields $statusSubfield = $configArray['Reindex']['statusSubfield']; $dueDateSubfield = $configArray['Reindex']['dueDateSubfield']; $locationSubfield = $configArray['Reindex']['locationSubfield']; $iTypeSubfield = $configArray['Reindex']['iTypeSubfield']; $callNumberPrestampSubfield = $configArray['Reindex']['callNumberPrestampSubfield']; $callNumberSubfield = $configArray['Reindex']['callNumberSubfield']; $callNumberCutterSubfield = $configArray['Reindex']['callNumberCutterSubfield']; $callNumberPoststampSubfield = $configArray['Reindex']['callNumberPoststampSubfield']; $volumeSubfield = $configArray['Reindex']['volumeSubfield']; $lastCheckinDateSubfield = $configArray['Reindex']['lastCheckinDateSubfield']; // added plb 3-24-2015 foreach ($itemFields as $itemField) { /** @var $itemField File_MARC_Data_Field */ $fullCallNumber = $itemField->getSubfield($callNumberPrestampSubfield) != null ? $itemField->getSubfield($callNumberPrestampSubfield)->getData() . ' ' : ''; $fullCallNumber .= $itemField->getSubfield($callNumberSubfield) != null ? $itemField->getSubfield($callNumberSubfield)->getData() : ''; $fullCallNumber .= $itemField->getSubfield($callNumberCutterSubfield) != null ? ' ' . $itemField->getSubfield($callNumberCutterSubfield)->getData() : ''; $fullCallNumber .= $itemField->getSubfield($callNumberPoststampSubfield) != null ? ' ' . $itemField->getSubfield($callNumberPoststampSubfield)->getData() : ''; $fullCallNumber .= $itemField->getSubfield($volumeSubfield) != null ? ' ' . $itemField->getSubfield($volumeSubfield)->getData() : ''; $fullCallNumber = str_replace(' ', ' ', $fullCallNumber); $itemData['callnumber'] = $fullCallNumber; $itemData['location'] = $itemField->getSubfield($locationSubfield) != null ? trim($itemField->getSubfield($locationSubfield)->getData()) : '?????'; $itemData['iType'] = $itemField->getSubfield($iTypeSubfield) != null ? $itemField->getSubfield($iTypeSubfield)->getData() : '-1'; $itemData['matched'] = false; $itemData['status'] = $itemField->getSubfield($statusSubfield) != null ? $itemField->getSubfield($statusSubfield)->getData() : '-'; $itemData['dueDate'] = $itemField->getSubfield($dueDateSubfield) != null ? trim($itemField->getSubfield($dueDateSubfield)->getData()) : null; $lastCheckinDate = $itemField->getSubfield($lastCheckinDateSubfield); // added plb 3-24-2015 if ($lastCheckinDate) { // convert to timestamp for ease of display in template $lastCheckinDate = trim($lastCheckinDate->getData()); $lastCheckinDate = DateTime::createFromFormat('m-d-Y G:i', $lastCheckinDate); if ($lastCheckinDate) { $lastCheckinDate = $lastCheckinDate->getTimestamp(); } } $itemData['lastCheckinDate'] = $lastCheckinDate ? $lastCheckinDate : null; $marcItemData[] = $itemData; } } else { $marcItemData = array(); $marcRecord = null; } if (!$configArray['Catalog']['offline']) { //Process each row in the callnumber table. $ret = $this->parseHoldingRows($id, $rows); if (count($ret) == 0) { //Also check the frameset for links if (preg_match('/<div class="bibDisplayUrls">.*?<table.*?>(.*?)<\\/table>.*?<\\/div>/si', $millenniumInfo->framesetInfo, $displayUrlInfo)) { $linksTable = $displayUrlInfo[1]; preg_match_all('/<td.*?>.*?<a href="(.*?)".*?>(.*?)<\\/a>.*?<\\/td>/si', $linksTable, $linkData, PREG_SET_ORDER); for ($i = 0; $i < count($linkData); $i++) { $linkText = $linkData[$i][2]; if ($linkText != 'Latest Received') { $newHolding = array('type' => 'holding', 'link' => array(), 'status' => 'Online', 'location' => 'Online'); $newHolding['link'][] = array('link' => $linkData[$i][1], 'linkText' => $linkText, 'isDownload' => true); $ret[] = $newHolding; } } } } $timer->logTime('processed all holdings rows'); } else { $ret = null; } global $locationSingleton; /** @var $locationSingleton Location */ $physicalLocation = $locationSingleton->getPhysicalLocation(); if ($physicalLocation != null) { $physicalBranch = $physicalLocation->holdingBranchLabel; } else { $physicalBranch = ''; } $homeBranch = ''; $homeBranchId = 0; $nearbyBranch1 = ''; $nearbyBranch1Id = 0; $nearbyBranch2 = ''; $nearbyBranch2Id = 0; //Set location information based on the user login. This will override information based if (isset($user) && $user != false) { $homeBranchId = $user->homeLocationId; $nearbyBranch1Id = $user->myLocation1Id; $nearbyBranch2Id = $user->myLocation2Id; } else { //Check to see if the cookie for home location is set. if (isset($_COOKIE['home_location']) && is_numeric($_COOKIE['home_location'])) { $cookieLocation = new Location(); $locationId = $_COOKIE['home_location']; $cookieLocation->whereAdd("locationId = '{$locationId}'"); $cookieLocation->find(); if ($cookieLocation->N == 1) { $cookieLocation->fetch(); $homeBranchId = $cookieLocation->locationId; $nearbyBranch1Id = $cookieLocation->nearbyLocation1; $nearbyBranch2Id = $cookieLocation->nearbyLocation2; } } } //Load the holding label for the user's home location. $userLocation = new Location(); $userLocation->whereAdd("locationId = '{$homeBranchId}'"); $userLocation->find(); if ($userLocation->N == 1) { $userLocation->fetch(); $homeBranch = $userLocation->holdingBranchLabel; } //Load nearby branch 1 $nearbyLocation1 = new Location(); $nearbyLocation1->whereAdd("locationId = '{$nearbyBranch1Id}'"); $nearbyLocation1->find(); if ($nearbyLocation1->N == 1) { $nearbyLocation1->fetch(); $nearbyBranch1 = $nearbyLocation1->holdingBranchLabel; } //Load nearby branch 2 $nearbyLocation2 = new Location(); $nearbyLocation2->whereAdd(); $nearbyLocation2->whereAdd("locationId = '{$nearbyBranch2Id}'"); $nearbyLocation2->find(); if ($nearbyLocation2->N == 1) { $nearbyLocation2->fetch(); $nearbyBranch2 = $nearbyLocation2->holdingBranchLabel; } $sorted_array = array(); //Get a list of the display names for all locations based on holding label. $locationLabels = array(); $location = new Location(); $location->find(); $libraryLocationLabels = array(); $locationCodes = array(); $suppressedLocationCodes = array(); while ($location->fetch()) { if (strlen($location->holdingBranchLabel) > 0 && $location->holdingBranchLabel != '???') { if ($library && $library->libraryId == $location->libraryId) { $cleanLabel = str_replace('/', '\\/', $location->holdingBranchLabel); $libraryLocationLabels[] = str_replace('.', '\\.', $cleanLabel); } $locationLabels[$location->holdingBranchLabel] = $location->displayName; $locationCodes[$location->code] = $location->holdingBranchLabel; if ($location->suppressHoldings == 1) { $suppressedLocationCodes[$location->code] = $location->code; } } } if (count($libraryLocationLabels) > 0) { $libraryLocationLabels = '/^(' . join('|', $libraryLocationLabels) . ').*/i'; } else { $libraryLocationLabels = ''; } //Get the current Ptype for later usage. $timer->logTime('setup for additional holdings processing.'); //Now that we have the holdings, we need to filter and sort them according to scoping rules. if (!$configArray['Catalog']['offline']) { $i = 0; foreach ($ret as $holdingKey => $holding) { $holding['type'] = 'holding'; //Process holdings without call numbers - Need to show items without call numbers //because they may have links, etc. Also show if there is a status. Since some //In process items may not have a call number yet. if ((!isset($holding['callnumber']) || strlen($holding['callnumber']) == 0) && (!isset($holding['link']) || count($holding['link']) == 0) && !isset($holding['status'])) { continue; } //Determine if the holding is available or not. //First check the status if (preg_match('/^(' . $this->driver->availableStatiRegex . ')$/', $holding['status'])) { $holding['availability'] = 1; } else { $holding['availability'] = 0; } if (preg_match('/^(' . $this->driver->holdableStatiRegex . ')$/', $holding['status'])) { $holding['holdable'] = 1; } else { $holding['holdable'] = 0; $holding['nonHoldableReason'] = "This item is not currently available for Patron Holds"; } if (!isset($holding['libraryDisplayName'])) { $holding['libraryDisplayName'] = $holding['location']; } //Get the location id for this holding $holding['locationCode'] = '?????'; foreach ($locationCodes as $locationCode => $holdingLabel) { if (strlen($locationCode) > 0 && preg_match("~{$holdingLabel}~i", $holding['location'])) { $holding['locationCode'] = $locationCode; break; } } if ($holding['locationCode'] == '?????') { $logger->log("Did not find location code for " . $holding['location'] . " record {$id}", PEAR_LOG_DEBUG); } if (array_key_exists($holding['locationCode'], $suppressedLocationCodes)) { $logger->log("Location " . $holding['locationCode'] . " is suppressed", PEAR_LOG_DEBUG); continue; } //Now that we have the location code, try to match with the marc record $holding['iType'] = 0; if ($matchItemsWithMarcItems) { foreach ($marcItemData as $itemKey => $itemData) { if ($itemData['matched'] === false) { // ensure not checked already $locationMatched = strpos($itemData['location'], $holding['locationCode']) === 0; $itemCallNumber = isset($itemData['callnumber']) ? $itemData['callnumber'] : ''; $holdingCallNumber = isset($holding['callnumber']) ? $holding['callnumber'] : ''; if (strlen($itemCallNumber) == 0 || strlen($holding['callnumber']) == 0) { $callNumberMatched = strlen($itemCallNumber) == strlen($holdingCallNumber); } else { $callNumberMatched = strpos($itemCallNumber, $holdingCallNumber) >= 0; } if ($locationMatched && $callNumberMatched) { $holding['iType'] = $itemData['iType']; $holding['lastCheckinDate'] = $itemData['lastCheckinDate']; // if the marc record matches up, include the last checkin date in the holding info. //Get the more specific location code if (strlen($holding['locationCode']) < strlen($itemData['location'])) { $holding['locationCode'] = $itemData['location']; } $itemData['matched'] = true; $marcItemData[$itemKey] = $itemData; // add matched sub-array element back to original array being looped over. break; } } } //Check to see if this item can be held by the current patron. Only important when //we know what pType is in use and we are showing all items. if ($scope == $this->driver->getDefaultScope() && $pType >= 0) { //Never remove the title if it is owned by the current library (could be in library use only) if (isset($library) && strlen($library->ilsCode) > 0 && strpos($holding['locationCode'], $library->ilsCode) === 0) { //$logger->log("Cannot remove holding because it belongs to the active library", PEAR_LOG_DEBUG); } else { if (!$this->driver->isItemHoldableToPatron($holding['locationCode'], $holding['iType'], $pType)) { //$logger->log("Removing item $holdingKey because it is not usable by the current patronType $pType, iType is {$holding['iType']}, location is {$holding['locationCode']}", PEAR_LOG_DEBUG); //echo("Removing item $holdingKey because it is not usable by the current patronType $pType, iType is {$holding['iType']}, location is {$holding['locationCode']}"); unset($ret[$holdingKey]); continue; } } } else { if ($pType >= 0 && $holding['holdable'] == 1) { //We won't want to remove titles based on holdability, but we do want to check if it is holdable if (!$this->driver->isItemHoldableToPatron($holding['locationCode'], $holding['iType'], $pType)) { $holding['holdable'] = 0; } } } } //Set the hold queue length $holding['holdQueueLength'] = isset($holdQueueLength) ? $holdQueueLength : null; //Add the holding to the sorted array to determine $paddedNumber = str_pad($i, 3, '0', STR_PAD_LEFT); $sortString = $holding['location'] . '-' . $paddedNumber; //$sortString = $holding['location'] . $holding['callnumber']. $i; if (strlen($physicalBranch) > 0 && stripos($holding['location'], $physicalBranch) !== false) { //If the user is in a branch, those holdings come first. $holding['section'] = 'In this library'; $holding['sectionId'] = 1; $sorted_array['1' . $sortString] = $holding; } else { if (strlen($homeBranch) > 0 && stripos($holding['location'], $homeBranch) !== false) { //Next come the user's home branch if the user is logged in or has the home_branch cookie set. $holding['section'] = 'Your library'; $holding['sectionId'] = 2; $sorted_array['2' . $sortString] = $holding; } else { if (strlen($nearbyBranch1) > 0 && stripos($holding['location'], $nearbyBranch1) !== false) { //Next come nearby locations for the user $holding['section'] = 'Nearby Libraries'; $holding['sectionId'] = 3; $sorted_array['3' . $sortString] = $holding; } else { if (strlen($nearbyBranch2) > 0 && stripos($holding['location'], $nearbyBranch2) !== false) { //Next come nearby locations for the user $holding['section'] = 'Nearby Libraries'; $holding['sectionId'] = 4; $sorted_array['4' . $sortString] = $holding; } else { if (strlen($libraryLocationLabels) > 0 && preg_match($libraryLocationLabels, $holding['location'])) { //Next come any locations within the same system we are in. $holding['section'] = $library->displayName; $holding['sectionId'] = 5; $sorted_array['5' . $sortString] = $holding; } else { //Finally, all other holdings are shown sorted alphabetically. $holding['section'] = 'Other Locations'; $holding['sectionId'] = 6; $sorted_array['6' . $sortString] = $holding; } } } } } $i++; } } else { $i = 0; //Offline circ, process each item in the marc record foreach ($marcItemData as $marcData) { $i++; $holding = array(); $holding['type'] = 'holding'; $holding['locationCode'] = $marcData['location']; $holding['callnumber'] = $marcData['callnumber']; $holding['statusfull'] = $this->translateStatusCode($marcData['status'], $marcData['dueDate']); $holding['lastCheckinDate'] = $marcData['lastCheckinDate']; //Try to translate the location code at least to location $location = new Location(); $location->whereAdd("LOCATE(code, '{$marcData['location']}') = 1"); if ($location->find(true)) { $holding['location'] = $location->displayName; } else { $holding['location'] = $marcData['location']; } if (array_key_exists($holding['locationCode'], $suppressedLocationCodes)) { $logger->log("Location " . $holding['locationCode'] . " is suppressed", PEAR_LOG_DEBUG); continue; } $holding['iType'] = $marcData['iType']; if ($marcData['status'] == '-' && $marcData['dueDate'] == null) { $holding['availability'] = 1; } else { $holding['availability'] = 0; } //Check to see if this item can be held by the current patron. Only important when //we know what pType is in use and we are showing all items. if ($scope == $this->driver->getDefaultScope() && $pType > 0) { //Never remove the title if it is owned by the current library (could be in library use only) if (isset($library) && strlen($library->ilsCode) > 0 && strpos($holding['locationCode'], $library->ilsCode) === 0) { //$logger->log("Cannot remove holding because it belongs to the active library", PEAR_LOG_DEBUG); } else { if (!$this->driver->isItemHoldableToPatron($holding['locationCode'], $holding['iType'], $pType)) { //$logger->log("Removing item because it is not usable by the current patronType $pType, iType is {$holding['iType']}, location is {$holding['locationCode']}", PEAR_LOG_DEBUG); //echo("Removing item $holdingKey because it is not usable by the current patronType $pType, iType is {$holding['iType']}, location is {$holding['locationCode']}"); continue; } } } $paddedNumber = str_pad($i, 3, '0', STR_PAD_LEFT); $sortString = $holding['location'] . '-' . $paddedNumber; if (strlen($physicalBranch) > 0 && stripos($holding['location'], $physicalBranch) !== false) { //If the user is in a branch, those holdings come first. $holding['section'] = 'In this library'; $holding['sectionId'] = 1; $sorted_array['1' . $sortString] = $holding; } else { if (strlen($homeBranch) > 0 && stripos($holding['location'], $homeBranch) !== false) { //Next come the user's home branch if the user is logged in or has the home_branch cookie set. $holding['section'] = 'Your library'; $holding['sectionId'] = 2; $sorted_array['2' . $sortString] = $holding; } else { if (strlen($nearbyBranch1) > 0 && stripos($holding['location'], $nearbyBranch1) !== false) { //Next come nearby locations for the user $holding['section'] = 'Nearby Libraries'; $holding['sectionId'] = 3; $sorted_array['3' . $sortString] = $holding; } else { if (strlen($nearbyBranch2) > 0 && stripos($holding['location'], $nearbyBranch2) !== false) { //Next come nearby locations for the user $holding['section'] = 'Nearby Libraries'; $holding['sectionId'] = 4; $sorted_array['4' . $sortString] = $holding; } else { if (strlen($libraryLocationLabels) > 0 && preg_match($libraryLocationLabels, $holding['location'])) { //Next come any locations within the same system we are in. $holding['section'] = $library->displayName; $holding['sectionId'] = 5; $sorted_array['5' . $sortString] = $holding; } else { //Finally, all other holdings are shown sorted alphabetically. $holding['section'] = 'Other Locations'; $holding['sectionId'] = 6; $sorted_array['6' . $sortString] = $holding; } } } } } } } $timer->logTime('finished processing holdings'); //Check to see if the title is holdable $holdable = $this->driver->isRecordHoldable($marcRecord); foreach ($sorted_array as $key => $holding) { //Do not override holdability based on status if (isset($holding['holdable']) && $holding['holdable'] == 1) { $holding['holdable'] = $holdable ? 1 : 0; $sorted_array[$key] = $holding; } } if (!$configArray['Catalog']['offline']) { //Load order records, these only show in the full page view, not the item display $orderMatches = array(); if (preg_match_all('/<tr\\s+class="bibOrderEntry">.*?<td\\s*>(.*?)<\\/td>/s', $millenniumInfo->framesetInfo, $orderMatches)) { for ($i = 0; $i < count($orderMatches[1]); $i++) { $location = trim($orderMatches[1][$i]); $location = preg_replace('/\\sC\\d{3}\\w{0,2}[\\s\\.]/', '', $location); //Remove courier code if any $sorted_array['7' . $location . $i] = array('location' => $location, 'section' => 'On Order', 'sectionId' => 7, 'holdable' => 1); } } $timer->logTime('loaded order records'); } ksort($sorted_array); //Check to see if we can remove the sections. //We can if all section keys are the same. $removeSection = true; $lastKeyIndex = ''; foreach ($sorted_array as $key => $holding) { $currentKey = substr($key, 0, 1); if ($lastKeyIndex == '') { $lastKeyIndex = $currentKey; } else { if ($lastKeyIndex != $currentKey) { $removeSection = false; break; } } } foreach ($sorted_array as $key => $holding) { if ($removeSection == true) { $holding['section'] = ''; $sorted_array[$key] = $holding; } } if (!$configArray['Catalog']['offline']) { $issueSummaries = $this->driver->getIssueSummaries($millenniumInfo); } else { $issueSummaries = null; } $timer->logTime('loaded issue summaries'); if (!is_null($issueSummaries)) { krsort($sorted_array); //Group holdings under the issue issue summary that is related. foreach ($sorted_array as $key => $holding) { //Have issue summary = false $haveIssueSummary = false; $issueSummaryKey = null; foreach ($issueSummaries as $issueKey => $issueSummary) { if ($issueSummary['location'] == $holding['location']) { $haveIssueSummary = true; $issueSummaryKey = $issueKey; break; } } if ($haveIssueSummary) { $issueSummaries[$issueSummaryKey]['holdings'][strtolower($key)] = $holding; } else { //Need to automatically add a summary so we don't lose data $issueSummaries[$holding['location']] = array('location' => $holding['location'], 'type' => 'issue', 'holdings' => array(strtolower($key) => $holding)); } } foreach ($issueSummaries as $key => $issueSummary) { if (isset($issueSummary['holdings']) && is_array($issueSummary['holdings'])) { krsort($issueSummary['holdings']); $issueSummaries[$key] = $issueSummary; } } ksort($issueSummaries); $status = $issueSummaries; } else { $status = $sorted_array; } MillenniumStatusLoader::$loadedStatus[$id] = $status; return $status; }
/** * Process SIP2 User Account * * @param array $info An array of user information * @param string $username The user's ILS username * @param string $password The user's ILS password * @param array $patronInfoResponse The user's ILS password * @return User * @access public * @author Bob Wicksall <*****@*****.**> */ private function processSIP2User($info, $username, $password, $patronInfoResponse) { global $timer; require_once ROOT_DIR . "/services/MyResearch/lib/User.php"; $user = new User(); $user->username = $info['variable']['AA'][0]; if ($user->find(true)) { $insert = false; } else { $insert = true; } // This could potentially be different depending on the ILS. Name could be Bob Wicksall or Wicksall, Bob. // This is currently assuming Wicksall, Bob if (strpos($info['variable']['AE'][0], ',') !== false) { $user->firstname = trim(substr($info['variable']['AE'][0], 1 + strripos($info['variable']['AE'][0], ','))); $user->lastname = trim(substr($info['variable']['AE'][0], 0, strripos($info['variable']['AE'][0], ','))); } else { $user->lastname = trim(substr($info['variable']['AE'][0], 1 + strripos($info['variable']['AE'][0], ' '))); $user->firstname = trim(substr($info['variable']['AE'][0], 0, strripos($info['variable']['AE'][0], ' '))); } // I'm inserting the sip username and password since the ILS is the source. // Should revisit this. $user->cat_username = $username; $user->cat_password = $password; $user->email = isset($patronInfoResponse['variable']['BE'][0]) ? $patronInfoResponse['variable']['BE'][0] : ''; $user->phone = isset($patronInfoResponse['variable']['BF'][0]) ? $patronInfoResponse['variable']['BF'][0] : ''; $user->major = 'null'; $user->college = 'null'; $user->patronType = $patronInfoResponse['variable']['PC'][0]; //Get home location //Check AO? if ((!isset($user->homeLocationId) || $user->homeLocationId == 0) && (isset($patronInfoResponse['variable']['AQ']) || isset($patronInfoResponse['variable']['AO']))) { $location = new Location(); if (isset($patronInfoResponse['variable']['AQ'])) { $location->code = $patronInfoResponse['variable']['AQ'][0]; } else { $location->code = $patronInfoResponse['variable']['AO'][0]; } $location->find(); if ($location->N > 0) { $location->fetch(); $user->homeLocationId = $location->locationId; } } if ($insert) { $user->created = date('Y-m-d'); $user->insert(); } else { $user->update(); } $timer->logTime("Processed SIP2 User"); return $user; }
function getObjectStructure() { $structure = array('id' => array('property' => 'id', 'type' => 'hidden', 'label' => 'Id', 'primaryKey' => true, 'description' => 'The unique id of the e-pub file.', 'storeDb' => true, 'storeSolr' => false), 'recordtype' => array('property' => 'recordtype', 'type' => 'method', 'methodName' => 'recordtype', 'storeDb' => false, 'storeSolr' => true), 'solrId' => array('property' => 'id', 'type' => 'method', 'methodName' => 'solrId', 'storeDb' => false, 'storeSolr' => true), 'title' => array('property' => 'title', 'type' => 'text', 'size' => 100, 'maxLength' => 255, 'label' => 'Title', 'description' => 'The title of the item.', 'required' => true, 'storeDb' => true, 'storeSolr' => true), 'title_proper' => array('property' => 'title_proper', 'type' => 'method', 'storeDb' => false, 'storeSolr' => true), 'title_sort' => array('property' => 'title_sort', 'type' => 'method', 'storeDb' => false, 'storeSolr' => true), 'format_category' => array('property' => 'format_category', 'type' => 'method', 'storeDb' => false, 'storeSolr' => true), 'format' => array('property' => 'format', 'type' => 'method', 'storeDb' => false, 'storeSolr' => true), 'description' => array('property' => 'description', 'type' => 'textarea', 'label' => 'Description', 'rows' => 3, 'cols' => 80, 'description' => 'A brief description of the file for indexing and display if there is not an existing record within the catalog.', 'required' => false, 'storeDb' => true, 'storeSolr' => true), 'num_titles' => array('property' => 'num_titles', 'type' => 'method', 'storeDb' => false, 'storeSolr' => true), 'num_holdings' => array('property' => 'num_holdings', 'type' => 'method', 'storeDb' => false, 'storeSolr' => true), 'format_boost' => array('property' => 'format_boost', 'type' => 'method', 'storeDb' => false, 'storeSolr' => true), 'language_boost' => array('property' => 'language_boost', 'type' => 'method', 'storeDb' => false, 'storeSolr' => true), 'contents' => array('property' => 'contents', 'type' => 'method', 'required' => false, 'storeDb' => false, 'storeSolr' => true), 'bib_suppression' => array('property' => 'bib_suppression', 'type' => 'method', 'storeDb' => false, 'storeSolr' => true), 'owning_library' => array('property' => 'owning_library', 'type' => 'method', 'methodName' => 'institution', 'storeDb' => false, 'storeSolr' => true), 'owning_location' => array('property' => 'owning_location', 'type' => 'method', 'methodName' => 'building', 'storeDb' => false, 'storeSolr' => true), 'usable_by' => array('property' => 'usable_by', 'type' => 'method', 'methodName' => 'usable_by', 'storeDb' => false, 'storeSolr' => true)); //Add local formats $library = new Library(); $library->find(); while ($library->fetch() == true) { $structure['format_' . $library->subdomain] = array('property' => 'format_' . $library->subdomain, 'type' => 'method', 'methodName' => 'format', 'storeDb' => false, 'storeSolr' => true); } $location = new Location(); $location->find(); while ($location->fetch() == true) { $structure['format_' . $location->code] = array('property' => 'format_' . $location->code, 'type' => 'method', 'methodName' => 'format', 'storeDb' => false, 'storeSolr' => true); } return $structure; }
public function placeHoldViaSIP($recordId, $patronId, $comment, $type) { global $configArray; global $user; //Place the hold via SIP 2 $mysip = new sip2(); $mysip->hostname = $configArray['SIP2']['host']; $mysip->port = $configArray['SIP2']['port']; $hold_result = array(); $hold_result['result'] = false; if ($mysip->connect()) { //send selfcheck status message $in = $mysip->msgSCStatus(); $msg_result = $mysip->get_message($in); // Make sure the response is 98 as expected if (preg_match("/^98/", $msg_result)) { $result = $mysip->parseACSStatusResponse($msg_result); // Use result to populate SIP2 setings $mysip->AO = $result['variable']['AO'][0]; /* set AO to value returned */ $mysip->AN = $result['variable']['AN'][0]; /* set AN to value returned */ $mysip->patron = $user->cat_username; $mysip->patronpwd = $user->cat_password; if (isset($_REQUEST['campus'])) { $campus = trim($_REQUEST['campus']); } else { $campus = $user->homeLocationId; //Get the code for the location $locationLookup = new Location(); $locationLookup->locationId = $campus; $locationLookup->find(); if ($locationLookup->N > 0) { $locationLookup->fetch(); $campus = $locationLookup->code; } } //place the hold if ($type == 'cancel' || $type == 'recall') { $mode = '-'; } elseif ($type == 'update') { $mode = '*'; } else { $mode = '+'; } //expire the hold in 2 years by default $expirationTime = time() + 2 * 365 * 24 * 60 * 60; $in = $mysip->msgHold($mode, $expirationTime, '2', '', $recordId, '', $campus); $msg_result = $mysip->get_message($in); $hold_result['title'] = $this->getRecordTitle($recordId); $hold_result['id'] = $recordId; if (preg_match("/^16/", $msg_result)) { $result = $mysip->parseHoldResponse($msg_result); $hold_result['result'] = $result['fixed']['Ok'] == 1; $hold_result['message'] = $result['variable']['AF'][0]; //Get the hold position. if ($result['fixed']['Ok'] == 1) { $holds = $this->getMyHolds($user); //Find the correct hold (will be unavailable) foreach ($holds['holds']['unavailable'] as $key => $holdInfo) { if ($holdInfo['id'] == $recordId) { $hold_result['message'] .= " You are number <b>" . $holdInfo['position'] . "</b> in the queue."; break; } } } } } } return $hold_result; }
/** * Update the configuration array as needed based on scoping rules defined * by the subdomain. * * @param array $configArray the existing main configuration options. * * @return array the configuration options adjusted based on the scoping rules. */ function updateConfigForScoping($configArray) { global $timer; //Get the subdomain for the request global $serverName; //split the servername based on global $subdomain; $subdomain = null; if (strpos($_SERVER['SERVER_NAME'], '.')) { $serverComponents = explode('.', $_SERVER['SERVER_NAME']); if (count($serverComponents) >= 3) { //URL is probably of the form subdomain.marmot.org or subdomain.opac.marmot.org $subdomain = $serverComponents[0]; } else { if (count($serverComponents) == 2) { //URL could be either subdomain.localhost or marmot.org. Only use the subdomain //If the second component is localhost. if (strcasecmp($serverComponents[1], 'localhost') == 0) { $subdomain = $serverComponents[0]; } } } //Trim off test indicator when doing lookups for library/location if (substr($subdomain, -1) == '2' || substr($subdomain, -1) == '3') { $subdomain = substr($subdomain, 0, -1); } } $timer->logTime('got subdomain'); //Load the library system information global $library; global $locationSingleton; if (isset($_SESSION['library']) && isset($_SESSION['location'])) { $library = $_SESSION['library']; $locationSingleton = $_SESSION['library']; } else { $Library = new Library(); $Library->whereAdd("subdomain = '{$subdomain}'"); $Library->find(); if ($Library->N == 1) { $Library->fetch(); //Make the library information global so we can work with it later. $library = $Library; } else { //The subdomain can also indicate a location. $Location = new Location(); $Location->whereAdd("code = '{$subdomain}'"); $Location->find(); if ($Location->N == 1) { $Location->fetch(); //We found a location for the subdomain, get the library. /** @var Library $librarySingleton */ global $librarySingleton; $library = $librarySingleton->getLibraryForLocation($Location->locationId); $locationSingleton->setActiveLocation(clone $Location); } else { //Check to see if there is only one library in the system $Library = new Library(); $Library->find(); if ($Library->N == 1) { $Library->fetch(); $library = $Library; } } } } if (isset($library) && $library != null) { //Update the title $configArray['Site']['theme'] = $library->themeName . ',' . $configArray['Site']['theme'] . ',default'; $configArray['Site']['title'] = $library->displayName; $location = $locationSingleton->getActiveLocation(); //Add an extra css file for the location if it exists. $themes = explode(',', $library->themeName); foreach ($themes as $themeName) { if ($location != null && file_exists('./interface/themes/' . $themeName . '/images/' . $location->code . '_logo_responsive.png')) { $configArray['Site']['responsiveLogo'] = '/interface/themes/' . $themeName . '/images/' . $location->code . '_logo_responsive.png'; } if ($subdomain != null && file_exists('./interface/themes/' . $themeName . '/images/' . $subdomain . '_logo_responsive.png')) { $configArray['Site']['responsiveLogo'] = '/interface/themes/' . $themeName . '/images/' . $subdomain . '_logo_responsive.png'; } if ($location != null && file_exists('./interface/themes/' . $themeName . '/images/' . $location->code . '_logo_small.png')) { $configArray['Site']['smallLogo'] = '/interface/themes/' . $themeName . '/images/' . $location->code . '_logo_small.png'; } if ($location != null && file_exists('./interface/themes/' . $themeName . '/images/' . $location->code . '_logo_large.png')) { $configArray['Site']['largeLogo'] = '/interface/themes/' . $themeName . '/images/' . $location->code . '_logo_large.png'; } } } $timer->logTime('finished update config for scoping'); return $configArray; }
function launch() { global $configArray; global $interface; global $user; //Load status information $materialsRequestStatus = new MaterialsRequestStatus(); $materialsRequestStatus->orderBy('isDefault DESC, isOpen DESC, description ASC'); if ($user->hasRole('library_material_requests')) { $homeLibrary = Library::getPatronHomeLibrary(); $materialsRequestStatus->libraryId = $homeLibrary->libraryId; } $materialsRequestStatus->find(); $availableStatuses = array(); $defaultStatusesToShow = array(); while ($materialsRequestStatus->fetch()) { $availableStatuses[$materialsRequestStatus->id] = $materialsRequestStatus->description; if ($materialsRequestStatus->isOpen == 1 || $materialsRequestStatus->isDefault == 1) { $defaultStatusesToShow[] = $materialsRequestStatus->id; } } $interface->assign('availableStatuses', $availableStatuses); if (isset($_REQUEST['statusFilter'])) { $statusesToShow = $_REQUEST['statusFilter']; } else { $statusesToShow = $defaultStatusesToShow; } $interface->assign('statusFilter', $statusesToShow); //Get a list of users that have requests open $materialsRequest = new MaterialsRequest(); $materialsRequest->joinAdd(new User()); $materialsRequest->joinAdd(new MaterialsRequestStatus()); $materialsRequest->selectAdd(); $materialsRequest->selectAdd('COUNT(materials_request.id) as numRequests'); $materialsRequest->selectAdd('user.id as userId, status, description, user.firstName, user.lastName, user.cat_username, user.cat_password'); if ($user->hasRole('library_material_requests')) { //Need to limit to only requests submitted for the user's home location $userHomeLibrary = Library::getPatronHomeLibrary(); $locations = new Location(); $locations->libraryId = $userHomeLibrary->libraryId; $locations->find(); $locationsForLibrary = array(); while ($locations->fetch()) { $locationsForLibrary[] = $locations->locationId; } $materialsRequest->whereAdd('user.homeLocationId IN (' . implode(', ', $locationsForLibrary) . ')'); } $statusSql = ""; foreach ($statusesToShow as $status) { if (strlen($statusSql) > 0) { $statusSql .= ","; } $statusSql .= "'" . $materialsRequest->escape($status) . "'"; } $materialsRequest->whereAdd("status in ({$statusSql})"); $materialsRequest->groupBy('userId, status'); $materialsRequest->find(); $userData = array(); while ($materialsRequest->fetch()) { if (!array_key_exists($materialsRequest->userId, $userData)) { $userData[$materialsRequest->userId] = array(); $userData[$materialsRequest->userId]['firstName'] = $materialsRequest->firstName; $userData[$materialsRequest->userId]['lastName'] = $materialsRequest->lastName; $barcodeProperty = $configArray['Catalog']['barcodeProperty']; $userData[$materialsRequest->userId]['barcode'] = $materialsRequest->{$barcodeProperty}; $userData[$materialsRequest->userId]['totalRequests'] = 0; $userData[$materialsRequest->userId]['requestsByStatus'] = array(); } $userData[$materialsRequest->userId]['requestsByStatus'][$materialsRequest->description] = $materialsRequest->numRequests; $userData[$materialsRequest->userId]['totalRequests'] += $materialsRequest->numRequests; } $interface->assign('userData', $userData); //Get a list of all of the statuses that will be shown $statuses = array(); foreach ($userData as $userInfo) { foreach ($userInfo['requestsByStatus'] as $status => $numRequests) { $statuses[$status] = translate($status); } } $interface->assign('statuses', $statuses); //Check to see if we are exporting to Excel if (isset($_REQUEST['exportToExcel'])) { $this->exportToExcel($userData, $statuses); } $interface->setTemplate('userReport.tpl'); $interface->setPageTitle('Materials Request User Report'); $interface->assign('sidebar', 'MyAccount/account-sidebar.tpl'); $interface->display('layout.tpl'); }
/** * In Sierra, all status information is up to date within the MARC record * due to the export so we don't need to screen scrape! * * Format of return array is: * key = {section#}{location}-### where ### is the holding iteration * * value = array ( * id = The id of the bib * number = The position of the holding within the original list of holdings * section = A description of the section * sectionId = a numeric id of the section for sorting * type = holding * status * statusfull * reserve * holdQueueLength * duedate * location * locationLink * callnumber * link = array * linkText * isDownload * ) * * Includes both physical titles as well as titles on order * * @param string $id the id of the record * @return array A list of holdings for the record */ public function getStatus($id) { $recordDriver = RecordDriverFactory::initRecordDriverById('ils:' . $id); $format = $recordDriver->getFormat(); if ($format[0] == 'Journal') { return parent::getStatus($id); } if (array_key_exists($id, SierraStatusLoader::$loadedStatus)) { return SierraStatusLoader::$loadedStatus[$id]; } //Load local information global $library; global $locationSingleton; /** @var $locationSingleton Location */ global $user; $physicalLocation = $locationSingleton->getPhysicalLocation(); if ($physicalLocation != null) { $physicalBranch = $physicalLocation->holdingBranchLabel; } else { $physicalBranch = ''; } $homeBranch = ''; $homeBranchId = 0; $nearbyBranch1 = ''; $nearbyBranch1Id = 0; $nearbyBranch2 = ''; $nearbyBranch2Id = 0; //Set location information based on the user login. This will override information based if (isset($user) && $user != false) { $homeBranchId = $user->homeLocationId; $nearbyBranch1Id = $user->myLocation1Id; $nearbyBranch2Id = $user->myLocation2Id; } else { //Check to see if the cookie for home location is set. if (isset($_COOKIE['home_location']) && is_numeric($_COOKIE['home_location'])) { $cookieLocation = new Location(); $locationId = $_COOKIE['home_location']; $cookieLocation->whereAdd("locationId = '{$locationId}'"); $cookieLocation->find(); if ($cookieLocation->N == 1) { $cookieLocation->fetch(); $homeBranchId = $cookieLocation->locationId; $nearbyBranch1Id = $cookieLocation->nearbyLocation1; $nearbyBranch2Id = $cookieLocation->nearbyLocation2; } } } //Load the holding label for the user's home location. $userLocation = new Location(); $userLocation->whereAdd("locationId = '{$homeBranchId}'"); $userLocation->find(); if ($userLocation->N == 1) { $userLocation->fetch(); $homeBranch = $userLocation->holdingBranchLabel; } //Load nearby branch 1 $nearbyLocation1 = new Location(); $nearbyLocation1->whereAdd("locationId = '{$nearbyBranch1Id}'"); $nearbyLocation1->find(); if ($nearbyLocation1->N == 1) { $nearbyLocation1->fetch(); $nearbyBranch1 = $nearbyLocation1->holdingBranchLabel; } //Load nearby branch 2 $nearbyLocation2 = new Location(); $nearbyLocation2->whereAdd(); $nearbyLocation2->whereAdd("locationId = '{$nearbyBranch2Id}'"); $nearbyLocation2->find(); if ($nearbyLocation2->N == 1) { $nearbyLocation2->fetch(); $nearbyBranch2 = $nearbyLocation2->holdingBranchLabel; } //Get a list of the display names for all locations based on holding label. $locationLabels = array(); $location = new Location(); $location->find(); $libraryLocationLabels = array(); $locationCodes = array(); $suppressedLocationCodes = array(); while ($location->fetch()) { if (strlen($location->holdingBranchLabel) > 0 && $location->holdingBranchLabel != '???') { if ($library && $library->libraryId == $location->libraryId) { $cleanLabel = str_replace('/', '\\/', $location->holdingBranchLabel); $libraryLocationLabels[] = str_replace('.', '\\.', $cleanLabel); } $locationLabels[$location->holdingBranchLabel] = $location->displayName; $locationCodes[$location->code] = $location->holdingBranchLabel; if ($location->suppressHoldings == 1) { $suppressedLocationCodes[$location->code] = $location->code; } } } if (count($libraryLocationLabels) > 0) { $libraryLocationLabels = '/^(' . join('|', $libraryLocationLabels) . ').*/i'; } else { $libraryLocationLabels = ''; } //In Sierra, we can just load data from the MARC Record/Index $items = $recordDriver->getItemsFast(); $holdQueueLength = $recordDriver->getNumHolds(); $itemStatus = array(); $i = 0; foreach ($items as $item) { //Determine what section this holding is in $sectionId = 1; $location = $item['shelfLocation']; if (strlen($physicalBranch) > 0 && stripos($location, $physicalBranch) !== false) { //If the user is in a branch, those holdings come first. $section = 'In this library'; $sectionId = 1; } else { if (strlen($homeBranch) > 0 && stripos($location, $homeBranch) !== false) { //Next come the user's home branch if the user is logged in or has the home_branch cookie set. $section = 'Your library'; $sectionId = 2; } else { if (strlen($nearbyBranch1) > 0 && stripos($location, $nearbyBranch1) !== false) { //Next come nearby locations for the user $section = 'Nearby Libraries'; $sectionId = 3; } else { if (strlen($nearbyBranch2) > 0 && stripos($location, $nearbyBranch2) !== false) { //Next come nearby locations for the user $section = 'Nearby Libraries'; $sectionId = 4; } else { if (strlen($libraryLocationLabels) > 0 && preg_match($libraryLocationLabels, $location)) { //Next come any locations within the same system we are in. $section = $library->displayName; $sectionId = 5; } else { //Finally, all other holdings are shown sorted alphabetically. $section = 'Other Locations'; $sectionId = 6; } } } } } $holding = array('location' => $item['shelfLocation'], 'reserve' => stripos($item['shelfLocation'], 'reserve') !== false ? 'Y' : 'N', 'callnumber' => $item['callnumber'], 'status' => $item['status'], 'duedate' => $item['dueDate'], 'lastCheckinDate' => $item['lastCheckinDate'], 'statusfull' => $this->translateStatusCode($item['status'], $item['dueDate']), 'id' => $id, 'number' => $i++, 'holdQueueLength' => $holdQueueLength, 'type' => 'holding', 'availability' => $item['availability'], 'holdable' => $item['holdable'] ? 1 : 0, 'libraryDisplayName' => $item['shelfLocation'], 'locationCode' => $item['location'], 'iType' => $item['iType'], 'section' => $section, 'sectionId' => $sectionId); $paddedNumber = str_pad($i, 3, '0', STR_PAD_LEFT); $holdingKey = $sectionId . $holding['location'] . $paddedNumber; $itemStatus[$holdingKey] = $holding; } ksort($itemStatus); SierraStatusLoader::$loadedStatus[$id] = $itemStatus; return $itemStatus; }