Exemple #1
0
 public function placeItemHold($recordId, $itemId, $patronId, $comment, $type)
 {
     global $configArray;
     global $user;
     $userId = $user->id;
     //Get the session token for the user
     if (isset(HorizonAPI::$sessionIdsForUsers[$userId])) {
         $sessionToken = HorizonAPI::$sessionIdsForUsers[$userId];
     } else {
         //Log the user in
         list($userValid, $sessionToken) = $this->loginViaWebService($user->cat_username, $user->cat_password);
         if (!$userValid) {
             return array('result' => false, 'message' => 'Sorry, it does not look like you are logged in currently.  Please login and try again');
         }
     }
     // Retrieve Full Marc Record
     require_once ROOT_DIR . '/RecordDrivers/Factory.php';
     $record = RecordDriverFactory::initRecordDriverById('ils:' . $recordId);
     if (!$record) {
         $title = null;
     } else {
         $title = $record->getTitle();
     }
     if ($configArray['Catalog']['offline']) {
         global $user;
         require_once ROOT_DIR . '/sys/OfflineHold.php';
         $offlineHold = new OfflineHold();
         $offlineHold->bibId = $recordId;
         $offlineHold->patronBarcode = $patronId;
         $offlineHold->patronId = $user->id;
         $offlineHold->timeEntered = time();
         $offlineHold->status = 'Not Processed';
         if ($offlineHold->insert()) {
             return array('title' => $title, 'bib' => $recordId, 'result' => true, 'message' => 'The circulation system is currently offline.  This hold will be entered for you automatically when the circulation system is online.');
         } else {
             return array('title' => $title, 'bib' => $recordId, 'result' => false, 'message' => 'The circulation system is currently offline and we could not place this hold.  Please try again later.');
         }
     } else {
         if ($type == 'cancel' || $type == 'recall' || $type == 'update') {
             $result = $this->updateHold($recordId, $patronId, $type, $title);
             $result['title'] = $title;
             $result['bid'] = $recordId;
             return $result;
         } else {
             if (isset($_REQUEST['campus'])) {
                 $campus = trim($_REQUEST['campus']);
             } else {
                 global $user;
                 $campus = $user->homeLocationId;
             }
             //create the hold using the web service
             $createHoldUrl = $configArray['Catalog']['webServiceUrl'] . '/standard/createMyHold?clientID=' . $configArray['Catalog']['clientId'] . '&sessionToken=' . $sessionToken . '&pickupLocation=' . $campus . '&titleKey=' . $recordId;
             if ($itemId) {
                 $createHoldUrl .= '&itemKey=' . $itemId;
             }
             $createHoldResponse = $this->getWebServiceResponse($createHoldUrl);
             $hold_result = array();
             if ($createHoldResponse == true) {
                 $hold_result['result'] = true;
                 $hold_result['message'] = 'Your hold was placed successfully.';
             } else {
                 $hold_result['result'] = false;
                 $hold_result['message'] = 'Your hold could not be placed. ';
                 if (isset($createHoldResponse->message)) {
                     $hold_result['message'] .= (string) $createHoldResponse->message;
                 } else {
                     if (isset($createHoldResponse->string)) {
                         $hold_result['message'] .= (string) $createHoldResponse->string;
                     }
                 }
             }
             $hold_result['title'] = $title;
             $hold_result['bid'] = $recordId;
             global $analytics;
             if ($analytics) {
                 if ($hold_result['result'] == true) {
                     $analytics->addEvent('ILS Integration', 'Successful Hold', $title);
                 } else {
                     $analytics->addEvent('ILS Integration', 'Failed Hold', $hold_result['message'] . ' - ' . $title);
                 }
             }
             //Clear the patron profile
             $this->clearPatronProfile();
             return $hold_result;
         }
     }
 }
Exemple #2
0
 function placeHold()
 {
     global $interface;
     global $configArray;
     global $user;
     global $logger;
     //TODO: Clean this up so there is only ever one id.
     if (isset($_REQUEST['recordId'])) {
         $recordId = $_REQUEST['recordId'];
     } else {
         $recordId = $_REQUEST['id'];
     }
     $interface->assign('id', $recordId);
     //Get title information for the record.
     $holding = $this->catalog->getHolding($recordId);
     if (PEAR_Singleton::isError($holding)) {
         PEAR_Singleton::raiseError($holding);
     }
     $interface->assign('holding', $holding);
     if (isset($_REQUEST['autologout'])) {
         $_SESSION['autologout'] = true;
     }
     $showMessage = false;
     $type = isset($_REQUEST['holdType']) ? $_REQUEST['holdType'] : '';
     if (isset($_POST['submit']) || $type == 'recall' || $type == 'update' || $type == 'hold') {
         if (isset($_REQUEST['username']) && isset($_REQUEST['password'])) {
             //Log the user in
             $user = UserAccount::login();
         }
         if ($user) {
             //The user is already logged in
             $barcodeProperty = $configArray['Catalog']['barcodeProperty'];
             $return = $this->catalog->placeHold($recordId, $user->{$barcodeProperty}, '', $type);
             $interface->assign('result', $return['result']);
             $message = $return['message'];
             $interface->assign('message', $message);
             $showMessage = true;
         } else {
             $message = 'Incorrect Patron Information';
             $interface->assign('message', $message);
             $interface->assign('focusElementId', 'username');
             $showMessage = true;
         }
     } else {
         //Get the referrer so we can go back there.
         if (isset($_SERVER['HTTP_REFERER'])) {
             $referer = $_SERVER['HTTP_REFERER'];
             $_SESSION['hold_referrer'] = $referer;
         }
         //Showing place hold form.
         if ($user) {
             $profile = $this->catalog->getMyProfile($user);
             $interface->assign('profile', $profile);
             //Get information to show a warning if the user does not have sufficient holds
             require_once ROOT_DIR . '/Drivers/marmot_inc/PType.php';
             $maxHolds = -1;
             //Determine if we should show a warning
             $ptype = new PType();
             $ptype->pType = $user->patronType;
             if ($ptype->find(true)) {
                 $maxHolds = $ptype->maxHolds;
             }
             $currentHolds = $profile['numHolds'];
             if ($maxHolds != -1 && $currentHolds + 1 > $maxHolds) {
                 $interface->assign('showOverHoldLimit', true);
                 $interface->assign('maxHolds', $maxHolds);
                 $interface->assign('currentHolds', $currentHolds);
             }
             global $locationSingleton;
             //Get the list of pickup branch locations for display in the user interface.
             $locations = $locationSingleton->getPickupBranches($profile, $profile['homeLocationId']);
             $interface->assign('pickupLocations', $locations);
             //set focus to the submit button if the user is logged in since the campus will be correct most of the time.
             $interface->assign('focusElementId', 'submit');
         } else {
             //set focus to the username field by default.
             $interface->assign('focusElementId', 'username');
         }
         global $library;
         $patronHomeBranch = Library::getPatronHomeLibrary();
         if ($patronHomeBranch != null) {
             if ($patronHomeBranch->defaultNotNeededAfterDays > 0) {
                 $interface->assign('defaultNotNeededAfterDays', date('m/d/Y', time() + $patronHomeBranch->defaultNotNeededAfterDays * 60 * 60 * 24));
             } else {
                 $interface->assign('defaultNotNeededAfterDays', '');
             }
             $interface->assign('showHoldCancelDate', $patronHomeBranch->showHoldCancelDate);
         } else {
             if ($library) {
                 //Show the hold cancellation date for now.  It may be hidden later when the user logs in.
                 if ($library->defaultNotNeededAfterDays > 0) {
                     $interface->assign('defaultNotNeededAfterDays', date('m/d/Y', time() + $library->defaultNotNeededAfterDays * 60 * 60 * 24));
                 } else {
                     $interface->assign('defaultNotNeededAfterDays', '');
                 }
                 $interface->assign('showHoldCancelDate', $library->showHoldCancelDate);
             } else {
                 //Show the hold cancellation date for now.  It may be hidden later when the user logs in.
                 $interface->assign('showHoldCancelDate', 1);
                 $interface->assign('defaultNotNeededAfterDays', '');
             }
         }
         $activeLibrary = Library::getActiveLibrary();
         if ($activeLibrary != null) {
             $interface->assign('holdDisclaimer', $activeLibrary->holdDisclaimer);
         } else {
             //Show the hold cancellation date for now.  It may be hidden later when the user logs in.
             $interface->assign('holdDisclaimer', '');
         }
     }
     $record = RecordDriverFactory::initRecordDriverById('ils:' . $_GET['id']);
     if ($record) {
         $interface->assign('record', $record);
     } else {
         PEAR_Singleton::raiseError('Cannot find record ' . $_GET['id']);
     }
     $interface->assign('id', $_GET['id']);
     if ($showMessage && isset($return)) {
         $hold_message_data = array('successful' => $return['result'] == true ? 'all' : 'none', 'error' => isset($return['error']) ? $return['error'] : '', 'titles' => array($return), 'campus' => $_REQUEST['campus']);
         //Check to see if there are item level holds that need follow-up by the user
         if (isset($return['items']) && count($return['items']) > 0) {
             $hold_message_data['showItemForm'] = true;
             $hold_message_data['items'] = $return['items'];
         }
         $_SESSION['hold_message'] = $hold_message_data;
         if (isset($_SESSION['hold_referrer'])) {
             $logger->log('Hold Referrer is set, redirecting to there. location ' . $_SESSION['hold_referrer'], PEAR_LOG_INFO);
             if ($_REQUEST['type'] != 'recall' && $_REQUEST['type'] != 'cancel' && $_REQUEST['type'] != 'update') {
                 header("Location: " . $_SESSION['hold_referrer']);
             } else {
                 //Redirect for hold cancellation or update
                 $section = isset($_REQUEST['section']) ? $_REQUEST['section'] : 'unavailable';
                 header("Location: " . '/MyResearch/Holds?section=' . $section);
             }
             if (!isset($hold_message_data['showItemForm']) || $hold_message_data['showItemForm'] == false) {
                 unset($_SESSION['hold_referrer']);
                 if (isset($_SESSION['autologout'])) {
                     unset($_SESSION['autologout']);
                     UserAccount::softLogout();
                 }
             }
         } else {
             $logger->log('No referrer set, but there is a message to show, go to the main holds page', PEAR_LOG_INFO);
             header("Location: " . '/MyResearch/Holds');
             die;
         }
     } else {
         //$logger->log('placeHold finished, do not need to show a message', PEAR_LOG_INFO);
         $interface->setPageTitle('Request an Item');
         $interface->assign('subTemplate', 'hold.tpl');
         $interface->setTemplate('hold.tpl');
         $interface->display('layout.tpl', 'RecordHold' . $_GET['id']);
     }
 }
 /**
  * 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 $configArray;
     $bib1 = $recordId;
     if (substr($bib1, 0, 1) != '.') {
         $bib1 = '.' . $bib1;
     }
     $bib = substr(str_replace('.b', 'b', $bib1), 0, -1);
     if (strlen($bib) == 0) {
         return array('result' => false, 'message' => 'A valid record id was not provided. Please try again.');
     }
     //Get the title of the book.
     $class = $configArray['Index']['engine'];
     $url = $configArray['Index']['url'];
     $this->driver->db = new $class($url);
     // Retrieve Full Marc Record
     require_once ROOT_DIR . '/RecordDrivers/Factory.php';
     $record = RecordDriverFactory::initRecordDriverById('ils:' . $bib1);
     if (!$record) {
         $title = null;
     } else {
         $title = $record->getTitle();
     }
     if ($configArray['Catalog']['offline']) {
         global $user;
         require_once ROOT_DIR . '/sys/OfflineHold.php';
         $offlineHold = new OfflineHold();
         $offlineHold->bibId = $bib1;
         $offlineHold->patronBarcode = $patronId;
         $offlineHold->patronId = $user->id;
         $offlineHold->timeEntered = time();
         $offlineHold->status = 'Not Processed';
         if ($offlineHold->insert()) {
             return array('title' => $title, 'bib' => $bib1, 'result' => true, 'message' => 'The circulation system is currently offline.  This hold will be entered for you automatically when the circulation system is online.');
         } else {
             return array('title' => $title, 'bib' => $bib1, 'result' => false, 'message' => 'The circulation system is currently offline and we could not place this hold.  Please try again later.');
         }
     } else {
         //Cancel a hold
         if ($type == 'cancel' || $type == 'recall' || $type == 'update') {
             $result = $this->updateHold($recordId, $patronId, $type, $title);
             $result['title'] = $title;
             $result['bid'] = $bib1;
             return $result;
         } else {
             if (isset($_REQUEST['canceldate']) && !is_null($_REQUEST['canceldate']) && $_REQUEST['canceldate'] != '') {
                 $date = $_REQUEST['canceldate'];
             } else {
                 //Default to a date 6 months (half a year) in the future.
                 $sixMonthsFromNow = time() + 182.5 * 24 * 60 * 60;
                 $date = date('m/d/Y', $sixMonthsFromNow);
             }
             if (isset($_REQUEST['campus'])) {
                 $campus = trim($_REQUEST['campus']);
             } else {
                 global $user;
                 $campus = $user->homeLocationId;
             }
             if (is_numeric($campus)) {
                 $location = new Location();
                 $location->locationId = $campus;
                 if ($location->find(true)) {
                     $campus = $location->code;
                 }
             }
             list($Month, $Day, $Year) = explode("/", $date);
             //------------BEGIN CURL-----------------------------------------------------------------
             $header = array();
             $header[0] = "Accept: text/xml,application/xml,application/xhtml+xml,";
             $header[0] .= "text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
             $header[] = "Cache-Control: max-age=0";
             $header[] = "Connection: keep-alive";
             $header[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7";
             $header[] = "Accept-Language: en-us,en;q=0.5";
             $cookie = tempnam("/tmp", "CURLCOOKIE");
             $curl_connection = curl_init();
             curl_setopt($curl_connection, CURLOPT_CONNECTTIMEOUT, 30);
             curl_setopt($curl_connection, CURLOPT_HTTPHEADER, $header);
             curl_setopt($curl_connection, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
             curl_setopt($curl_connection, CURLOPT_RETURNTRANSFER, true);
             curl_setopt($curl_connection, CURLOPT_SSL_VERIFYPEER, false);
             curl_setopt($curl_connection, CURLOPT_FOLLOWLOCATION, true);
             curl_setopt($curl_connection, CURLOPT_UNRESTRICTED_AUTH, true);
             curl_setopt($curl_connection, CURLOPT_COOKIEJAR, $cookie);
             curl_setopt($curl_connection, CURLOPT_COOKIESESSION, true);
             curl_setopt($curl_connection, CURLOPT_FORBID_REUSE, false);
             curl_setopt($curl_connection, CURLOPT_HEADER, false);
             curl_setopt($curl_connection, CURLOPT_POST, true);
             $lt = null;
             if (isset($configArray['Catalog']['loginPriorToPlacingHolds']) && ($configArray['Catalog']['loginPriorToPlacingHolds'] = true)) {
                 //User must be logged in as a separate step to placing holds
                 $curl_url = $configArray['Catalog']['url'] . "/patroninfo";
                 $post_data = $this->driver->_getLoginFormValues();
                 $post_data['submit.x'] = "35";
                 $post_data['submit.y'] = "21";
                 $post_data['submit'] = "submit";
                 curl_setopt($curl_connection, CURLOPT_REFERER, $curl_url);
                 curl_setopt($curl_connection, CURLOPT_URL, $curl_url);
                 $post_items = array();
                 foreach ($post_data as $key => $value) {
                     $post_items[] = $key . '=' . $value;
                 }
                 $post_string = implode('&', $post_items);
                 curl_setopt($curl_connection, CURLOPT_POSTFIELDS, $post_string);
                 $loginResult = curl_exec($curl_connection);
                 $curlInfo = curl_getinfo($curl_connection);
                 //When a library uses Encore, the initial login does a redirect and requires additional parameters.
                 if (preg_match('/<input type="hidden" name="lt" value="(.*?)" \\/>/si', $loginResult, $loginMatches)) {
                     //Get the lt value
                     $lt = $loginMatches[1];
                     //Login again
                     $post_data['lt'] = $lt;
                     $post_data['_eventId'] = 'submit';
                     $post_items = array();
                     foreach ($post_data as $key => $value) {
                         $post_items[] = $key . '=' . $value;
                     }
                     $post_string = implode('&', $post_items);
                     curl_setopt($curl_connection, CURLOPT_POSTFIELDS, $post_string);
                     $loginResult = curl_exec($curl_connection);
                     $curlInfo = curl_getinfo($curl_connection);
                 }
                 $post_data = array();
             } else {
                 $post_data = $this->driver->_getLoginFormValues();
             }
             $scope = $this->driver->getLibraryScope();
             $curl_url = $configArray['Catalog']['url'] . "/search/.{$bib}/.{$bib}/1,1,1,B/request~{$bib}";
             //echo "$curl_url";
             curl_setopt($curl_connection, CURLOPT_URL, $curl_url);
             /** @var Library $librarySingleton */
             global $librarySingleton;
             $patronHomeBranch = $librarySingleton->getPatronHomeLibrary();
             if ($patronHomeBranch->defaultNotNeededAfterDays != -1) {
                 $post_data['needby_Month'] = $Month;
                 $post_data['needby_Day'] = $Day;
                 $post_data['needby_Year'] = $Year;
             }
             $post_data['submit.x'] = "35";
             $post_data['submit.y'] = "21";
             $post_data['submit'] = "submit";
             $post_data['locx00'] = str_pad($campus, 5 - strlen($campus), '+');
             if (!is_null($itemId) && $itemId != -1) {
                 $post_data['radio'] = $itemId;
             }
             $post_data['x'] = "48";
             $post_data['y'] = "15";
             if ($lt != null) {
                 $post_data['lt'] = $lt;
                 $post_data['_eventId'] = 'submit';
             }
             $post_items = array();
             foreach ($post_data as $key => $value) {
                 $post_items[] = $key . '=' . $value;
             }
             $post_string = implode('&', $post_items);
             curl_setopt($curl_connection, CURLOPT_POSTFIELDS, $post_string);
             $sResult = curl_exec($curl_connection);
             global $logger;
             $logger->log("Placing hold {$curl_url}?{$post_string}", PEAR_LOG_INFO);
             $sResult = preg_replace("/<!--([^(-->)]*)-->/", "", $sResult);
             curl_close($curl_connection);
             //Parse the response to get the status message
             $hold_result = $this->_getHoldResult($sResult);
             $hold_result['title'] = $title;
             $hold_result['bid'] = $bib1;
             global $analytics;
             if ($analytics) {
                 if ($hold_result['result'] == true) {
                     $analytics->addEvent('ILS Integration', 'Successful Hold', $title);
                 } else {
                     $analytics->addEvent('ILS Integration', 'Failed Hold', $hold_result['message'] . ' - ' . $title);
                 }
             }
             //Clear the patron profile
             $this->driver->clearPatronProfile();
             return $hold_result;
         }
     }
 }
 public function getRelatedRecords($realTimeStatusNeeded = true)
 {
     global $timer;
     if ($this->relatedRecords == null || isset($_REQUEST['reload'])) {
         $timer->logTime("Starting to load related records for {$this->getUniqueID()}");
         $relatedRecords = array();
         global $solrScope;
         $relatedRecordFieldName = 'related_record_ids';
         if ($solrScope) {
             if (isset($this->fields["related_record_ids_{$solrScope}"])) {
                 $relatedRecordFieldName = "related_record_ids_{$solrScope}";
             }
         }
         //Get a list of related items
         $relatedItemsFieldName = 'related_record_items';
         if ($solrScope) {
             if (isset($this->fields["related_items_{$solrScope}"])) {
                 $relatedItemsFieldName = "related_items_{$solrScope}";
             }
         }
         if (isset($this->fields[$relatedRecordFieldName])) {
             $relatedRecordIds = $this->fields[$relatedRecordFieldName];
             if (!is_array($relatedRecordIds)) {
                 $relatedRecordIds = array($relatedRecordIds);
             }
             if (isset($this->fields[$relatedItemsFieldName])) {
                 $itemsFromIndex = array();
                 $itemsFromIndexRaw = $this->fields[$relatedItemsFieldName];
                 if (!is_array($itemsFromIndexRaw)) {
                     $itemsFromIndexRaw = array($itemsFromIndexRaw);
                 }
                 foreach ($itemsFromIndexRaw as $tmpItem) {
                     if (strpos($tmpItem, '|') !== FALSE) {
                         if (strpos($tmpItem, '~~') !== FALSE) {
                             $itemData = explode('~~', $tmpItem);
                             //When broken by ~~, the item data has sections for record info, item info, and scope info
                             $itemDataBySection['record'] = explode('|', $itemData[0]);
                             $itemDataBySection['item'] = explode('|', $itemData[1]);
                             if (array_key_exists(2, $itemData)) {
                                 $itemDataBySection['scope'] = explode('|', $itemData[2]);
                             } else {
                                 $itemDataBySection['scope'] = array();
                             }
                             $itemsFromIndex[] = $itemDataBySection;
                         } else {
                             $itemsFromIndex[] = explode('|', $tmpItem);
                         }
                     } else {
                         $itemsFromIndex[] = array($tmpItem);
                     }
                 }
             } else {
                 $itemsFromIndex = null;
             }
             foreach ($relatedRecordIds as $relatedRecordInfo) {
                 $hasDetailedRecordInfo = false;
                 if (strpos($relatedRecordInfo, '|') !== FALSE) {
                     $relatedRecordInfo = explode('|', $relatedRecordInfo);
                     $relatedRecordId = $relatedRecordInfo[0];
                     $hasDetailedRecordInfo = true;
                 } else {
                     $relatedRecordId = $relatedRecordInfo;
                 }
                 require_once ROOT_DIR . '/RecordDrivers/Factory.php';
                 $recordDriver = RecordDriverFactory::initRecordDriverById($relatedRecordId);
                 if ($recordDriver != null && $recordDriver->isValid()) {
                     if ($itemsFromIndex != null) {
                         $filteredItemsFromIndex = array();
                         foreach ($itemsFromIndex as $item) {
                             if (array_key_exists('record', $item)) {
                                 if ($item['record'][0] == $relatedRecordId) {
                                     $filteredItemsFromIndex[] = $item;
                                 }
                             } else {
                                 if ($item[0] == $relatedRecordId) {
                                     $filteredItemsFromIndex[] = $item;
                                 }
                             }
                         }
                         $recordDriver->setItemsFromIndex($filteredItemsFromIndex, $realTimeStatusNeeded);
                     }
                     if ($hasDetailedRecordInfo) {
                         $recordDriver->setDetailedRecordInfoFromIndex($relatedRecordInfo, $realTimeStatusNeeded);
                     }
                     $timer->logTime("Initialized Record Driver for {$relatedRecordId}");
                     $recordDriver->setScopingEnabled($this->scopingEnabled);
                     $relatedRecordsForBib = $recordDriver->getRelatedRecords($realTimeStatusNeeded);
                     foreach ($relatedRecordsForBib as $relatedRecord) {
                         $relatedRecord['driver'] = $recordDriver;
                         $relatedRecords[] = $relatedRecord;
                     }
                 }
                 $timer->logTime("Finished loading related records for {$relatedRecordId}");
             }
             //Sort the records based on format and then edition
             usort($relatedRecords, array($this, "compareRelatedRecords"));
         }
         $this->relatedRecords = $relatedRecords;
     }
     $timer->logTime("Finished loading related records");
     return $this->relatedRecords;
 }
 private function loadGroupedWork()
 {
     if ($this->groupedWork == null) {
         // Include Search Engine Class
         require_once ROOT_DIR . '/sys/Solr.php';
         $this->initMemcache();
         require_once ROOT_DIR . '/RecordDrivers/GroupedWorkDriver.php';
         if ($this->type == 'grouped_work') {
             $this->groupedWork = new GroupedWorkDriver($this->id);
             if (!$this->groupedWork->isValid) {
                 $this->groupedWork = false;
             }
         } else {
             require_once ROOT_DIR . '/RecordDrivers/Factory.php';
             $recordDriver = RecordDriverFactory::initRecordDriverById($this->type . ':' . $this->id);
             if ($recordDriver->isValid()) {
                 $this->groupedWork = $recordDriver->getGroupedWorkDriver();
                 if (!$this->groupedWork->isValid) {
                     $this->groupedWork = false;
                 }
             }
         }
     }
     return $this->groupedWork;
 }
 /**
  * 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;
 }