/** * Protected method for vufind (i.e. User) defined holds * * @param string $id A Bib ID * @param string $type The holds mode to be applied from: * (disabled, always, availability, driver) * @param array $patron Patron * * @return mixed A url on success, boolean false on failure */ protected function generateHold($id, $type, $patron) { $any_available = false; $addlink = false; $data = ['id' => $id, 'level' => 'title']; // Are holds allows? $checkHolds = $this->catalog->checkFunction('Holds', compact('id', 'patron')); if ($checkHolds != false) { if ($type == 'always') { $addlink = true; } elseif ($type == 'availability') { $holdings = $this->getHoldings($id); foreach ($holdings as $holding) { if ($holding['availability'] && !in_array($holding['location'], $this->hideHoldings)) { $any_available = true; } } $addlink = !$any_available; } if ($addlink) { if ($checkHolds['function'] == 'getHoldLink') { // Return opac link return $this->catalog->getHoldLink($id, $data); } else { // Return non-opac link return $this->getHoldDetails($data, $checkHolds['HMACKeys']); } } } return false; }
/** * Process ILL request information in holdings and set the links accordingly. * * @param array $holdings Holdings * @param string $id Record ID * @param array $patron Patron * * @return array Modified holdings */ protected function processILLRequests($holdings, $id, $patron) { if (!is_array($holdings)) { return $holdings; } // Are storage retrieval requests allowed? $requestConfig = $this->catalog->checkFunction('ILLRequests', compact('id', 'patron')); if (!$requestConfig) { return $holdings; } // Generate Links // Loop through each holding foreach ($holdings as &$location) { foreach ($location as &$copy) { // Is this copy requestable if (isset($copy['addILLRequestLink']) && $copy['addILLRequestLink']) { // If the request is blocked, link to an error page // instead of the form: if ($copy['addILLRequestLink'] === 'block') { $copy['ILLRequestLink'] = $this->getBlockedILLRequestDetails($copy); } else { $copy['ILLRequestLink'] = $this->getRequestDetails($copy, $requestConfig['HMACKeys'], 'ILLRequest'); } // If we are unsure whether request options are // available, set a flag so we can check later via AJAX: $copy['checkILLRequest'] = $copy['addILLRequestLink'] === 'check'; } } } return $holdings; }
/** * Process cancel request. * * @param \VuFind\ILS\Connection $catalog ILS connection object * @param array $patron Current logged in patron * * @return array The result of the cancellation, an * associative array keyed by item ID (empty if no cancellations performed) */ public function cancelILLRequests($catalog, $patron) { // Retrieve the flashMessenger helper: $flashMsg = $this->getController()->flashMessenger(); $params = $this->getController()->params(); // Pick IDs to cancel based on which button was pressed: $all = $params->fromPost('cancelAll'); $selected = $params->fromPost('cancelSelected'); if (!empty($all)) { $details = $params->fromPost('cancelAllIDS'); } else { if (!empty($selected)) { $details = $params->fromPost('cancelSelectedIDS'); } else { // No button pushed -- no action needed return []; } } if (!empty($details)) { // Confirm? if ($params->fromPost('confirm') === "0") { $url = $this->getController()->url()->fromRoute('myresearch-illrequests'); if ($params->fromPost('cancelAll') !== null) { return $this->getController()->confirm('ill_request_cancel_all', $url, $url, 'confirm_ill_request_cancel_all_text', ['cancelAll' => 1, 'cancelAllIDS' => $params->fromPost('cancelAllIDS')]); } else { return $this->getController()->confirm('ill_request_cancel_selected', $url, $url, 'confirm_ill_request_cancel_selected_text', ['cancelSelected' => 1, 'cancelSelectedIDS' => $params->fromPost('cancelSelectedIDS')]); } } foreach ($details as $info) { // If the user input contains a value not found in the session // whitelist, something has been tampered with -- abort the process. if (!in_array($info, $this->getSession()->validIds)) { $flashMsg->addMessage('error_inconsistent_parameters', 'error'); return []; } } // Add Patron Data to Submitted Data $cancelResults = $catalog->cancelILLRequests(['details' => $details, 'patron' => $patron]); if ($cancelResults == false) { $flashMsg->addMessage('ill_request_cancel_fail', 'error'); } else { if ($cancelResults['count'] > 0) { // TODO : add a mechanism for inserting tokens into translated // messages so we can avoid a double translation here. $msg = $this->getController()->translate('ill_request_cancel_success_items'); $flashMsg->addMessage($cancelResults['count'] . ' ' . $msg, 'success'); } return $cancelResults; } } else { $flashMsg->addMessage('ill_request_empty_selection', 'error'); } return []; }
/** * Get a link for placing a title level hold. * * @return mixed A url if a hold is possible, boolean false if not */ public function getRealTimeTitleHold() { if ($this->hasILS()) { $biblioLevel = strtolower($this->getBibliographicLevel()); if ("monograph" == $biblioLevel || strstr($biblioLevel, "part")) { if ($this->ils->getTitleHoldsMode() != "disabled") { return $this->titleHoldLogic->getHold($this->getUniqueID()); } } } return false; }
/** * Figure out which bib IDs to load from the ILS. * * @param \VuFind\ILS\Connection $catalog ILS connection * @param \VuFind\Search\Solr\Params $params Solr parameters * @param string $range Range setting * @param string $dept Department setting * @param \Zend\Mvc\Controller\Plugin\FlashMessenger $flash Flash messenger * * @return array */ public function getBibIDsFromCatalog($catalog, $params, $range, $dept, $flash) { // The code always pulls in enough catalog results to get a fixed number // of pages worth of Solr results. Note that if the Solr index is out of // sync with the ILS, we may see fewer results than expected. $resultPages = $this->getResultPages(); $perPage = $params->getLimit(); $newItems = $catalog->getNewItems(1, $perPage * $resultPages, $range, $dept); // Build a list of unique IDs $bibIDs = []; for ($i = 0; $i < count($newItems['results']); $i++) { $bibIDs[] = $newItems['results'][$i]['id']; } // Truncate the list if it is too long: $limit = $params->getQueryIDLimit(); if (count($bibIDs) > $limit) { $bibIDs = array_slice($bibIDs, 0, $limit); $flash->setNamespace('info')->addMessage('too_many_new_items'); } return $bibIDs; }
/** * Get circulation statuses for all elements of the item * * @param String $sysNumber SysNumber * * @return Array[] */ protected function getItemCirculationStatuses($sysNumber) { $data = []; try { $circulationStatuses = $this->ils->getDriver()->getCirculationStatus($sysNumber); foreach ($circulationStatuses as $circulationStatus) { $data[$circulationStatus['barcode']] = $circulationStatus; } } catch (\Exception $e) { //todo: GH get logging service } return $data; }
/** * Attempt to log in the user to the ILS, and save credentials if it works. * * @param string $username Catalog username * @param string $password Catalog password * * Returns associative array of patron data on success, false on failure. * * @return array|bool * @throws ILSException */ public function newCatalogLogin($username, $password) { $result = $this->catalog->patronLogin($username, $password); if ($result) { $user = $this->auth->isLoggedIn(); if ($user) { $user->saveCredentials($username, $password); $this->auth->updateSession($user); // cache for future use $this->ilsAccount[$username] = $result; } return $result; } return false; }
/** * Public method for getting title level holds * * @param string $id A Bib ID * * @return string|bool URL to place hold, or false if hold option unavailable */ public function getHold($id) { // Get Holdings Data if ($this->catalog) { $mode = ILSConnection::getTitleHoldsMode(); if ($mode == "disabled") { return false; } else { if ($mode == "driver") { $patron = $this->account->storedCatalogLogin(); if (!$patron) { return false; } return $this->driverHold($id, $patron); } else { return $this->generateHold($id, $mode); } } } return false; }
/** * Process renewal requests. * * @param \Zend\Stdlib\Parameters $request Request object * @param \VuFind\ILS\Connection $catalog ILS connection object * @param array $patron Current logged in patron * * @return array The result of the renewal, an * associative array keyed by item ID (empty if no renewals performed) */ public function processRenewals($request, $catalog, $patron) { // Pick IDs to renew based on which button was pressed: $all = $request->get('renewAll'); $selected = $request->get('renewSelected'); if (!empty($all)) { $ids = $request->get('renewAllIDS'); } else { if (!empty($selected)) { $ids = $request->get('renewSelectedIDS'); } else { $ids = []; } } // Retrieve the flashMessenger helper: $flashMsg = $this->getController()->flashMessenger(); // If there is actually something to renew, attempt the renewal action: if (is_array($ids) && !empty($ids)) { $renewResult = $catalog->renewMyItems(['details' => $ids, 'patron' => $patron]); if ($renewResult !== false) { // Assign Blocks to the Template if (isset($renewResult['blocks']) && is_array($renewResult['blocks'])) { foreach ($renewResult['blocks'] as $block) { $flashMsg->setNamespace('info')->addMessage($block); } } // Send back result details: return $renewResult['details']; } else { // System failure: $flashMsg->setNamespace('error')->addMessage('renew_error'); } } else { if (!empty($all) || !empty($selected)) { // Button was clicked but no items were selected: $flashMsg->setNamespace('error')->addMessage('renew_empty_selection'); } } return []; }
/** * Getting a default required date based on hold settings. * * @param array $checkHolds Hold settings returned by the ILS driver's * checkFunction method. * @param Connection $catalog ILS connection (optional) * @param array $patron Patron details (optional) * @param array $holdInfo Hold details (optional) * * @return int A timestamp representing the default required date */ public function getDefaultRequiredDate($checkHolds, $catalog = null, $patron = null, $holdInfo = null) { // Load config: $dateArray = isset($checkHolds['defaultRequiredDate']) ? explode(":", $checkHolds['defaultRequiredDate']) : [0, 1, 0]; // Process special "driver" prefix and adjust default date // settings accordingly: if ($dateArray[0] == 'driver') { $useDriver = true; array_shift($dateArray); if (count($dateArray) < 3) { $dateArray = [0, 1, 0]; } } else { $useDriver = false; } // If the driver setting is active, try it out: if ($useDriver && $catalog) { $check = $catalog->checkCapability('getHoldDefaultRequiredDate', [$patron, $holdInfo]); if ($check) { $result = $catalog->getHoldDefaultRequiredDate($patron, $holdInfo); if (!empty($result)) { return $result; } } } // If the driver setting is off or the driver didn't work, use the // standard relative date mechanism: return $this->getDateFromArray($dateArray); }
/** * Set the ILS connection for this object. * * @param \VuFind\ILS\Connection $connection ILS connection to set * * @return void */ public function setCatalog(\VuFind\ILS\Connection $connection) { // Right now, MultiILS authentication only works with the MultiBackend // driver; if other ILS drivers eventually support this option, we // should define an interface containing getLoginDrivers() and // getDefaultLoginDriver(). if (!$connection->getDriver() instanceof MultiBackend) { throw new \Exception('MultiILS authentication requires MultiBackend ILS driver.'); } return parent::setCatalog($connection); }
/** * Public method for getting item holdings from the catalog and selecting which * holding method to call * * @param string $id A Bib ID * * @return array A sorted results set */ public function getHoldings($id) { $holdings = array(); // Get Holdings Data if ($this->catalog) { // Retrieve stored patron credentials; it is the responsibility of the // controller and view to inform the user that these credentials are // needed for hold data. $patron = $this->account->storedCatalogLogin(); $result = $this->catalog->getHolding($id, $patron); $mode = ILSConnection::getHoldsMode(); if ($mode == "disabled") { $holdings = $this->standardHoldings($result); } else { if ($mode == "driver") { $holdings = $this->driverHoldings($result); } else { $holdings = $this->generateHoldings($result, $mode); } } } return $this->formatHoldings($holdings); }
/** * Process renewal requests. * * @param \VuFind\ILS\Connection $catalog ILS connection object * @param array $patron Current logged in patron * * @return array The result of the renewal, an * associative array keyed by item ID (empty if no renewals performed) */ public function cancelHolds($catalog, $patron) { // Retrieve the flashMessenger helper: $flashMsg = $this->getController()->flashMessenger(); $params = $this->getController()->params(); // Pick IDs to renew based on which button was pressed: $all = $params->fromPost('cancelAll'); $selected = $params->fromPost('cancelSelected'); if (!empty($all)) { $details = $params->fromPost('cancelAllIDS'); } else { if (!empty($selected)) { $details = $params->fromPost('cancelSelectedIDS'); } else { // No button pushed -- no action needed return array(); } } if (!empty($details)) { foreach ($details as $info) { // If the user input contains a value not found in the session // whitelist, something has been tampered with -- abort the process. if (!in_array($info, $this->getSession()->validIds)) { $flashMsg->setNamespace('error')->addMessage('error_inconsistent_parameters'); return array(); } } // Add Patron Data to Submitted Data $cancelResults = $catalog->cancelHolds(array('details' => $details, 'patron' => $patron)); if ($cancelResults == false) { $flashMsg->setNamespace('error')->addMessage('hold_cancel_fail'); } else { if ($cancelResults['count'] > 0) { // TODO : add a mechanism for inserting tokens into translated // messages so we can avoid a double translation here. $msg = $this->getController()->translate('hold_cancel_success_items'); $flashMsg->setNamespace('info')->addMessage($cancelResults['count'] . ' ' . $msg); } return $cancelResults; } } else { $flashMsg->setNamespace('error')->addMessage('hold_empty_selection'); } return array(); }
/** * Get a link for placing a title level hold. * * @param \VuFind\Auth\Manager $account Auth manager object * * @return mixed A url if a hold is possible, boolean false if not */ public function getRealTimeTitleHold(\VuFind\Auth\Manager $account) { $biblioLevel = $this->getBibliographicLevel(); if ("monograph" == strtolower($biblioLevel) || stristr("part", $biblioLevel)) { if (ILSConnection::getTitleHoldsMode() != "disabled") { $holdLogic = new TitleHoldLogic($account, $this->getILS()); return $holdLogic->getHold($this->getUniqueID()); } } return false; }
/** * checkRequestIsValid * * This is responsible for determining if an item is requestable * * @param string $id The Bib ID * @param array $data An Array of item data * @param patron $patron An array of patron data * * @return string True if request is valid, false if not */ public function checkRequestIsValid($id, $data, $patron) { $holdType = isset($data['holdtype']) ? $data['holdtype'] : "auto"; $level = isset($data['level']) ? $data['level'] : "copy"; $mode = "title" == $level ? ILSConnection::getTitleHoldsMode() : ILSConnection::getHoldsMode(); if ("driver" == $mode && "auto" == $holdType) { $itemID = isset($data['item_id']) ? $data['item_id'] : false; $result = $this->determineHoldType($patron['id'], $id, $itemID); if (!$result || $result == 'block') { return false; } } return true; }