/** * Extract a year from a human-readable date. Return false if no year can * be found. * * @param string $date Date to reformat * * @return string|bool */ public function extractYear($date) { try { return $this->converter->convertFromDisplayDate('Y', $date); } catch (\VuFind\Exception\Date $e) { // bad date? just ignore it! return false; } }
/** * Place Hold * * Attempts to place a hold or recall on a particular item and returns * an array with result details or throws an exception on failure of support * classes * * @param array $holdDetails An array of item and patron data * * @throws ILSException * @return mixed An array of data on the request including * whether or not it was successful and a system message (if available) */ public function placeHold($holdDetails) { $patron = $holdDetails['patron']; // convert expire date from display format // to the format Symphony/Unicorn expects $expire = $holdDetails['requiredBy']; $expire = $this->dateConverter->convertFromDisplayDate($this->config['Catalog']['server_date_format'], $expire); // query sirsi $params = ['query' => 'hold', 'itemId' => $holdDetails['item_id'], 'patronId' => $patron['cat_username'], 'pin' => $patron['cat_password'], 'pickup' => $holdDetails['pickUpLocation'], 'expire' => $expire, 'comments' => $holdDetails['comment'], 'holdType' => $holdDetails['level'], 'callnumber' => $holdDetails['callnumber'], 'override' => $holdDetails['override']]; $response = $this->querySirsi($params); // process the API response if ($response == 'invalid_login') { return ['success' => false, 'sysMessage' => "authentication_error_admin"]; } $matches = []; preg_match('/\\^MN([0-9][0-9][0-9])/', $response, $matches); if (isset($matches[1])) { $status = $matches[1]; if ($status == '209') { return ['success' => true]; } else { return ['success' => false, 'sysMessage' => $this->config['ApiMessages'][$status]]; } } return ['success' => false]; }
/** * Test citation generation * * @return void */ public function testDates() { // Build an object to test with (using empty configuration to ensure default // settings): $date = new Converter(new Config(array())); // Try some conversions: $this->assertEquals('11-29-1973', $date->convertToDisplayDate('U', 123456879)); $this->assertEquals('11-29-1973', $date->convertToDisplayDate('m-d-y', '11-29-73')); $this->assertEquals('11-29-1973', $date->convertToDisplayDate('m-d-y', '11-29-1973')); $this->assertEquals('11-29-1973', $date->convertToDisplayDate('m-d-y H:i', '11-29-73 23:01')); $this->assertEquals('23:01', $date->convertToDisplayTime('m-d-y H:i', '11-29-73 23:01')); $this->assertEquals('01-02-2001', $date->convertToDisplayDate('m-d-y', '01-02-01')); $this->assertEquals('01-02-2001', $date->convertToDisplayDate('m-d-y', '01-02-2001')); $this->assertEquals('01-02-2001', $date->convertToDisplayDate('m-d-y H:i', '01-02-01 05:11')); $this->assertEquals('05:11', $date->convertToDisplayTime('m-d-y H:i', '01-02-01 05:11')); $this->assertEquals('01-02-2001', $date->convertToDisplayDate('Y-m-d', '2001-01-02')); $this->assertEquals('01-02-2001', $date->convertToDisplayDate('Y-m-d H:i', '2001-01-02 05:11')); $this->assertEquals('05:11', $date->convertToDisplayTime('Y-m-d H:i', '2001-01-02 05:11')); $this->assertEquals('01-2001', $date->convertFromDisplayDate('m-Y', '01-02-2001')); // Check for proper handling of known problems: try { $bad = $date->convertToDisplayDate('U', 'invalid'); $this->fail('Expected exception did not occur'); } catch (DateException $e) { $this->assertTrue((bool) stristr($e->getMessage(), 'failed to parse time string')); } try { $bad = $date->convertToDisplayDate('d-m-Y', '31-02-2001'); $this->fail('Expected exception did not occur'); } catch (DateException $e) { $this->assertTrue((bool) stristr($e->getMessage(), 'parsed date was invalid')); } }
/** * Change pickup location * * This is responsible for changing the pickup location of a hold * * @param string $patron Patron array * @param string $holdDetails The request details * * @return array Associative array of the results */ public function changePickupLocation($patron, $holdDetails) { global $configArray; $username = $patron['cat_username']; $password = $patron['cat_password']; $pickupLocationId = $holdDetails['pickupLocationId']; try { $validFromDate = date('Y-m-d'); $validToDate = isset($holdDetails['requiredBy']) ? $this->dateFormat->convertFromDisplayDate('Y-m-d', $holdDetails['requiredBy']) : date('Y-m-d', $this->getDefaultRequiredByDate()); } catch (DateException $e) { // Hold Date is invalid throw new ILSException('hold_date_invalid'); } $requestId = $holdDetails['requestId']; list($organisation, $branch) = explode('.', $pickupLocationId, 2); $function = 'changeReservation'; $functionResult = 'changeReservationResult'; $conf = ['arenaMember' => $this->arenaMember, 'user' => $username, 'password' => $password, 'language' => 'en', 'id' => $requestId, 'pickUpBranchId' => $branch, 'validFromDate' => $validFromDate, 'validToDate' => $validToDate]; $result = $this->doSOAPRequest($this->reservations_wsdl, $function, $functionResult, $username, ['changeReservationsParam' => $conf]); $statusAWS = $result->{$functionResult}->status; if ($statusAWS->type != 'ok') { $message = $this->handleError($function, $statusAWS->message, $username); if ($message == 'ils_connection_failed') { throw new ILSException('ils_offline_status'); } return ['success' => false, 'sysMessage' => $message]; } return ['success' => true]; }
/** * Get the year of publication for inclusion in a citation. * Shared by APA and MLA functionality. * * @return string */ protected function getYear() { if (isset($this->details['pubDate'])) { if (strlen($this->details['pubDate']) > 4) { try { return $this->dateConverter->convertFromDisplayDate('Y', $this->details['pubDate']); } catch (\Exception $e) { // Ignore date errors -- no point in dying here: return false; } } return preg_replace('/[^0-9]/', '', $this->details['pubDate']); } return false; }
/** * Protected support method for getMyTransactions. * * @param array $row An array of keyed data * * @throws \VuFind\Exception\Date * @return array Keyed data for display by template files */ protected function processTransactionsRow($row) { $dueStatus = false; // Convert Horizon Format to display format if (!empty($row['DUEDATE'])) { $dueDate = $this->dateFormat->convertToDisplayDate("M d Y", trim($row['DUEDATE'])); $now = time(); $dueTimeStamp = $this->dateFormat->convertFromDisplayDate("U", $dueDate); if (is_numeric($dueTimeStamp)) { if ($now > $dueTimeStamp) { $dueStatus = "overdue"; } else { if ($now > $dueTimeStamp - 1 * 24 * 60 * 60) { $dueStatus = "due"; } } } } return ['id' => $row['BIB_NUM'], 'item_id' => $row['ITEM_NUM'], 'duedate' => $dueDate, 'barcode' => $row['ITEM_BARCODE'], 'renew' => $row['RENEW'], 'request' => $row['REQUEST'], 'dueStatus' => $dueStatus, 'volume' => $row['VOLUME'], 'publication_year' => $row['PUBLICATION_YEAR'], 'title' => $row['TITLE']]; }
/** * Use a record driver to assign metadata to the current row. Return the * current object to allow fluent interface. * * @param \VuFind\RecordDriver\AbstractBase $driver The record driver * @param \VuFind\Date\Converter $converter Date converter * * @return \VuFind\Db\Row\Resource */ public function assignMetadata($driver, \VuFind\Date\Converter $converter) { // Grab title -- we have to have something in this field! $this->title = $driver->tryMethod('getSortTitle'); if (empty($this->title)) { $this->title = $driver->getBreadcrumb(); } // Try to find an author; if not available, just leave the default null: $author = $driver->tryMethod('getPrimaryAuthor'); if (!empty($author)) { $this->author = $author; } // Try to find a year; if not available, just leave the default null: $dates = $driver->tryMethod('getPublicationDates'); if (isset($dates[0]) && strlen($dates[0]) > 4) { try { $year = $converter->convertFromDisplayDate('Y', $dates[0]); } catch (DateException $e) { // If conversion fails, don't store a date: $year = ''; } } else { $year = isset($dates[0]) ? $dates[0] : ''; } if (!empty($year)) { $this->year = intval($year); } return $this; }
/** * Place Hold * * Attempts to place a hold or recall on a particular item and returns * an array with result details or throws an exception on failure of support * classes * * @param array $details An array of item and patron data * * @throws ILSException * @return mixed An array of data on the request including * whether or not it was successful and a system message (if available) */ public function placeHold($details) { list($bib, $sys_no) = $this->parseId($details['id']); $recordId = $bib . $sys_no; $itemId = $details['item_id']; $patron = $details['patron']; $pickupLocation = $details['pickUpLocation']; if (!$pickupLocation) { $pickupLocation = $this->getDefaultPickUpLocation($patron, $details); } $comment = $details['comment']; if (strlen($comment) <= 50) { $comment1 = $comment; } else { $comment1 = substr($comment, 0, 50); $comment2 = substr($comment, 50, 50); } try { $requiredBy = $this->dateConverter->convertFromDisplayDate('Ymd', $details['requiredBy']); } catch (DateException $de) { return ['success' => false, 'sysMessage' => 'hold_date_invalid']; } $patronId = $patron['id']; $body = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?>' . '<hold-request-parameters></hold-request-parameters>'); $body->addChild('pickup-location', $pickupLocation); $body->addChild('last-interest-date', $requiredBy); $body->addChild('note-1', $comment1); if (isset($comment2)) { $body->addChild('note-2', $comment2); } $body = 'post_xml=' . $body->asXML(); try { $this->doRestDLFRequest(['patron', $patronId, 'record', $recordId, 'items', $itemId, 'hold'], null, "PUT", $body); } catch (AlephRestfulException $exception) { $message = $exception->getMessage(); $note = $exception->getXmlResponse()->xpath('/put-item-hold/create-hold/note[@type="error"]'); $note = $note[0]; return ['success' => false, 'sysMessage' => "{$message} ({$note})"]; } return ['success' => true]; }
/** * Place Hold * * Attempts to place a hold or recall on a particular item and returns * an array with result details. * * @param array $holdDetails An array of item and patron data * * @return mixed An array of data on the request including * whether or not it was successful and a system message (if available) */ public function placeHold($holdDetails) { // Simulate failure: if (rand() % 2) { return array("success" => false, "sysMessage" => 'Demonstrating failure; keep trying and ' . 'it will work eventually.'); } if (!isset($this->session->holds)) { $this->session->holds = new ArrayObject(); } $lastHold = count($this->session->holds) - 1; $nextId = $lastHold >= 0 ? $this->session->holds[$lastHold]['item_id'] + 1 : 0; // Figure out appropriate expiration date: if (!isset($holdDetails['requiredBy']) || empty($holdDetails['requiredBy'])) { $expire = strtotime("now + 30 days"); } else { try { $dateFormat = new DateConverter(); $expire = $dateFormat->convertFromDisplayDate("U", $holdDetails['requiredBy']); } catch (DateException $e) { // Hold Date is invalid return array('success' => false, 'sysMessage' => 'hold_date_invalid'); } } if ($expire <= time()) { return array('success' => false, 'sysMessage' => 'hold_date_past'); } $this->session->holds->append(array("id" => $holdDetails['id'], "location" => $holdDetails['pickUpLocation'], "expire" => date("j-M-y", $expire), "create" => date("j-M-y"), "reqnum" => sprintf("%06d", $nextId), "item_id" => $nextId)); return array('success' => true); }
/** * Place ILL Request * * Attempts to place an ILL request on a particular item and returns * an array with result details * * @param array $details An array of item and patron data * * @return mixed An array of data on the request including * whether or not it was successful and a system message (if available) */ public function placeILLRequest($details) { if (!$this->ILLRequests) { return ['success' => false, 'sysMessage' => 'ILL requests are disabled.']; } // Simulate failure: if ($this->isFailing(__METHOD__, 50)) { return ['success' => false, 'sysMessage' => 'Demonstrating failure; keep trying and ' . 'it will work eventually.']; } $session = $this->getSession(); if (!isset($session->ILLRequests)) { $session->ILLRequests = new ArrayObject(); } $lastRequest = count($session->ILLRequests) - 1; $nextId = $lastRequest >= 0 ? $session->ILLRequests[$lastRequest]['item_id'] + 1 : 0; // Figure out appropriate expiration date: if (!isset($details['requiredBy']) || empty($details['requiredBy'])) { $expire = strtotime('now + 30 days'); } else { try { $expire = $this->dateConverter->convertFromDisplayDate('U', $details['requiredBy']); } catch (DateException $e) { // Expiration Date is invalid return ['success' => false, 'sysMessage' => 'ill_request_date_invalid']; } } if ($expire <= time()) { return ['success' => false, 'sysMessage' => 'ill_request_date_past']; } // Verify pickup library and location $pickupLocation = ''; $pickupLocations = $this->getILLPickupLocations($details['id'], $details['pickUpLibrary'], $details['patron']); foreach ($pickupLocations as $location) { if ($location['id'] == $details['pickUpLibraryLocation']) { $pickupLocation = $location['name']; break; } } if (!$pickupLocation) { return ['success' => false, 'sysMessage' => 'ill_request_place_fail_missing']; } $session->ILLRequests->append(['id' => $details['id'], 'source' => $this->getRecordSource(), 'location' => $pickupLocation, 'expire' => $this->dateConverter->convertToDisplayDate('U', $expire), 'create' => $this->dateConverter->convertToDisplayDate('U', time()), 'processed' => rand() % 3 == 0 ? $this->dateConverter->convertToDisplayDate('U', $expire) : '', 'reqnum' => sprintf('%06d', $nextId), 'item_id' => $nextId]); return ['success' => true]; }
/** * To Koha Date * * Turns a display date into a date format expected by Koha. * * @param string $display_date Date to be converted * * @throws ILSException * @return string $koha_date */ protected function toKohaDate($display_date) { $koha_date = ""; // Convert last interest date from format to Koha format $koha_date = $this->dateConverter->convertFromDisplayDate("Y-m-d", $display_date); $checkTime = $this->dateConverter->convertFromDisplayDate("U", $display_date); if (!is_numeric($checkTime)) { throw new DateException('Result should be numeric'); } if (time() > $checkTime) { // Hold Date is in the past throw new DateException('hold_date_past'); } return $koha_date; }
public function placeILLRequest($user, $attrs) { $payment = $attrs['payment']; unset($attrs['payment']); $new = $attrs['new']; unset($attrs['new']); $additional_authors = $attrs['additional_authors']; unset($attrs['additional_authors']); $source = $attrs['source']; $publisher = $attrs['publisher']; unset($attrs['source']); if (!isset($attrs['ill-unit'])) { $attrs['ill-unit'] = $this->defaultIllUnit; } if (!isset($attrs['pickup-location'])) { $attrs['pickup-location'] = $this->defaultIllPickupPlocation; } try { $attrs['last-interest-date'] = $this->dateConverter->convertFromDisplayDate('Ymd', $attrs['last-interest-date']); } catch (DateException $de) { return array('success' => false, 'sysMessage' => 'hold_date_invalid'); } $attrs['allowed-media'] = $attrs['media']; $attrs['send-directly'] = 'N'; $attrs['delivery-method'] = 'S'; if ($new == 'serial') { $new = 'SE'; } else { if ($new == 'monography') { $new = 'MN'; } } $patronId = $user['id']; $illDom = new \DOMDocument('1.0', 'UTF-8'); $illRoot = $illDom->createElement('ill-parameters'); $illRootNode = $illDom->appendChild($illRoot); foreach ($attrs as $key => $value) { $element = $illDom->createElement($key); $element->appendChild($illDom->createTextNode($value)); $illRootNode->appendChild($element); } $xml = $illDom->saveXML(); try { $path = array('patron', $patronId, 'record', $new, 'ill'); $result = $this->alephWebService->doRestDLFRequest($path, null, 'PUT', 'post_xml=' . $xml); } catch (\Exception $ex) { return array('success' => false, 'sysMessage' => $ex->getMessage()); } $baseAndDocNumber = $result->{'create-ill'}->{'request-number'}; $base = substr($baseAndDocNumber, 0, 5); $docNum = substr($baseAndDocNumber, 5); $findDocParams = array('base' => $base, 'doc_num' => $docNum); $document = $this->alephWebService->doXRequest('find-doc', $findDocParams, true); // create varfield for ILL request type $varfield = $document->{'record'}->{'metadata'}->{'oai_marc'}->addChild('varfield'); $varfield->addAttribute('id', 'PNZ'); $varfield->addAttribute('i1', ' '); $varfield->addAttribute('i2', ' '); $subfield = $varfield->addChild('subfield', $payment); $subfield->addAttribute('label', 'a'); if (!empty($additional_authors)) { $varfield = $document->{'record'}->{'metadata'}->{'oai_marc'}->addChild('varfield'); $varfield->addAttribute('id', '700'); $varfield->addAttribute('i1', '1'); $varfield->addAttribute('i2', ' '); $subfield = $varfield->addChild('subfield', $additional_authors); $subfield->addAttribute('label', 'a'); } if (!empty($source)) { $varfield = $document->{'record'}->{'metadata'}->{'oai_marc'}->addChild('varfield'); $varfield->addAttribute('id', '590'); $varfield->addAttribute('i1', ' '); $varfield->addAttribute('i2', ' '); $subfield = $varfield->addChild('subfield', htmlspecialchars($source)); $subfield->addAttribute('label', 'a'); } if (!empty($publisher)) { $varfield = $document->{'record'}->{'metadata'}->{'oai_marc'}->addChild('varfield'); $varfield->addAttribute('id', '260'); $varfield->addAttribute('i1', ' '); $varfield->addAttribute('i2', ' '); $subfield = $varfield->addChild('subfield', htmlspecialchars($source)); $subfield->addAttribute('label', 'b'); } $updateDocParams = array('library' => $base, 'doc_num' => $docNum); $updateDocParams['xml_full_req'] = $document->asXml(); $updateDocParams['doc_action'] = 'UPDATE'; try { $update = $this->alephWebService->doXRequestUsingPost('update-doc', $updateDocParams, true); } catch (\Exception $ex) { return array('success' => false, 'sysMessage' => $ex->getMessage()); } return array('success' => true, 'id' => $docNum); }