/** * Convert to Ebsco individual record syntax * * @param string $id * @return Url */ public function getRecordUrl($id) { if (!strstr($id, "-")) { throw new \Exception("could not find record"); } // database and id come in on same value, so split 'em $database = Parser::removeRight($id, "-"); $id = Parser::removeLeft($id, "-"); // get results $query = "AN {$id}"; // construct url $url = $this->host . '/Search?' . 'prof=' . $this->username . '&pwd=' . $this->password . '&authType=&ipprof=' . '&query=' . urlencode($query) . "&db={$database}" . '&startrec=1&numrec=1&format=detailed'; return new Url($url); }
/** * Convert to EDS individual record syntax * * @param string $id * @return Url */ public function getRecordUrl($id) { if ($id == "") { throw new \DomainException('No record ID supplied'); } $database = Parser::removeRight($id, "-"); $id = Parser::removeLeft($id, "-"); // build request $url = $this->server . 'retrieve?'; $url .= 'dbid=' . $database; $url .= '&an=' . urlencode($id); $url .= '&includefacets=n'; return new Url($url, $this->headers); }
/** * Return an individual record * * @param string record identifier * @return ResultSet */ protected function doGetRecord($id) { $results = new Search\ResultSet($this->config); // get the record from the database $record = $this->datamap->getRecordByID($id); // no record found? if ($record == null) { $results->total = 0; return $results; } // got one $results->total = 1; $result = $this->createSearchResult($record); // corrupted record, look out if ($result->corrupted == true) { $fixed = false; $data = $record->marc; // go back to the original search engine and fetch it again $class_name = 'Application\\Model\\' . ucfirst($result->source) . '\\Engine'; if (class_exists($class_name)) { try { $engine = new $class_name(); $new_results = $engine->getRecord($result->original_id); if ($new_results->total > 0) { $result = $new_results->getRecord(0); $fixed = true; } } catch (NotFoundException $e) { if (strstr($data, 'Xerxes_TransRecord')) { $data = '<?xml version="1.0"?>' . Parser::removeLeft($data, '<?xml version="1.0"?>'); $data = Parser::removeRight($data, '</xerxes_record>') . '</xerxes_record>'; $xerxes_record = new Xerxes\Record(); $xerxes_record->loadXML($data); $record->xerxes_record = $xerxes_record; // recreate the result, since we need the openurl and such $result = $this->createSearchResult($record); $fixed = true; } } } elseif (strstr($data, 'Xerxes_MetalibRecord')) { $data = '<?xml' . Parser::removeLeft($data, '<?xml'); $data = Parser::removeRight($data, '</x_server_response>') . '</x_server_response>'; $xerxes_record = new \Xerxes_MetalibRecord(); $xerxes_record->loadXML($data); $record->xerxes_record = $xerxes_record; // recreate the result, since we need the openurl and such $result = $this->createSearchResult($record); $fixed = true; } if ($fixed == false) { throw new \Exception('Sorry, this record has been corrupted'); } } // if a catalog record, fetch holdings if ($record->xerxes_record instanceof Solr\Record) { try { $engine = new Solr\Engine(); $solr_results = $engine->getRecord($result->original_id); $holdings = $solr_results->getRecord(0)->getHoldings(); $result->setHoldings($holdings); } catch (\Exception $e) { trigger_error('saved records holdings lookup: ' . $e->getMessage(), E_USER_WARNING); } } $results->addResult($result); return $results; }
public function map() { // score $this->score = (string) $this->document->documentElement->getAttribute("RANK"); // record data $record = $this->document->documentElement->getElementsByTagName("record")->item(0); // print $this->document->saveXML(); $control = $this->getElement($record, "control"); $display = $this->getElement($record, "display"); $links = $this->getElement($record, "links"); $search = $this->getElement($record, "search"); $sort = $this->getElement($record, "sort"); $addata = $this->getElement($record, "addata"); $facets = $this->getElement($record, "facets"); $sourceid = ""; if ($control != null) { $sourceid = $this->getElementValue($control, "sourceid"); } if ($display != null) { // database name $this->database_name = $this->getElementValue($display, "source"); $this->database_name = strip_tags($this->database_name); // journal $this->journal = $this->getElementValue($display, "ispartof"); // snippet $this->snippet = $this->getElementValue($display, "snippet"); $this->snippet = strip_tags($this->snippet); // description $this->abstract = $this->getElementValue($display, "description"); $this->abstract = strip_tags($this->abstract); // language $this->language = $this->getElementValue($display, "language"); // peer reviewed $peer_reviewed = $this->getElementValue($display, 'lds50'); if ($peer_reviewed == 'peer_reviewed') { $this->refereed = true; } } if ($search != null) { // record id $this->record_id = $this->getElementValue($search, "recordid"); // year $this->year = $this->getElementValue($search, "creationdate"); // issn $issn = $this->getElementValue($search, "issn"); $issn = preg_replace('/\\D/', "", $issn); array_push($this->issns, $issn); // authors $authors = $this->getElementValues($search, "creatorcontrib"); foreach ($authors as $author) { array_push($this->authors, new Xerxes\Record\Author($author, null, "personal")); } // format $format = $this->getElementValue($search, "rsrctype"); $this->format()->setInternalFormat($format); // create a readable display $format_display = self::createReadableLabel($format); $this->format()->setPublicFormat($format_display); } // article data if ($addata != null) { $this->journal_title = $this->start_page = $this->getElementValue($addata, "jtitle"); $this->volume = $this->getElementValue($addata, "volume"); $this->issue = $this->getElementValue($addata, "issue"); $this->start_page = $this->getElementValue($addata, "spage"); $this->end_page = $this->getElementValue($addata, "epage"); // primo's own ris type $ris_type = $this->getElementValue($addata, 'ristype'); if ($ris_type != "") { $this->format()->setNormalizedFormat($ris_type); } // abstract $abstract = $this->getElementValue($addata, "abstract"); if ($this->abstract == "") { $this->abstract = strip_tags($abstract); } } // subjects if ($facets != null) { $topics = $this->getElementValues($facets, "topic"); foreach ($topics as $topic) { $subject_object = new Xerxes\Record\Subject(); $subject_object->value = $topic; $subject_object->display = $topic; array_push($this->subjects, $subject_object); } } // title if ($sort != null) { $this->title = $this->getElementValue($sort, "title"); } // direct link $backlink = $this->getElementValue($links, "backlink"); if ($backlink != "") { $backlink = Parser::removeLeft($backlink, '$$U'); $url = Parser::removeRight($backlink, '$$E'); $message = Parser::removeLeft($backlink, '$$E'); $link = new Link($url); $link->setType(Link::ONLINE); $this->links[] = $link; } // Gale title clean-up, because for some reason unknown to man they put weird // notes and junk at the end of the title. so remove them here and add them to notes. if (stristr($sourceid, "gale") || stristr($sourceid, "muse")) { $gale_regex = '/\\(([^)]*)\\)/'; $matches = array(); if (preg_match_all($gale_regex, $this->title, $matches) != 0) { $this->title = preg_replace($gale_regex, "", $this->title); foreach ($matches[1] as $match) { array_push($this->notes, $match); } } if (strpos($this->abstract, 'the full-text of this article') !== false) { $this->abstract = Parser::removeLeft($this->abstract, 'Abstract:'); } } }
/** * Extracts the MARC data from the HTML response and converts it to MARC-XML * * @param string $marc marc data as string * @return DOMDocument marc-xml document */ protected function extractMarc($response) { $xml = Parser::convertToDOMDocument("<record xmlns=\"http://www.loc.gov/MARC21/slim\" />"); $marc = ""; // marc data as text $arrTags = array(); // array to hold each MARC tag if (!stristr($response, "<pre>")) { // didn't find a record return $xml; } // parse out MARC data $marc = Parser::removeLeft($response, "<pre>"); $marc = Parser::removeRight($marc, "</pre>"); // remove break-tabs for easier parsing $marc = str_replace(" \n ", " ", $marc); $marc = str_replace("\n ", " ", $marc); $marc = trim($marc); // assign the marc values to the array based on Unix LF as delimiter $arrTags = explode("\n", $marc); foreach ($arrTags as $strTag) { // assign tag # and identifiers $strTagNumber = substr($strTag, 0, 3); $strId1 = substr($strTag, 4, 1); $strId2 = substr($strTag, 5, 1); // assign data and clean it up $data = substr($strTag, 7); // only convert all data to utf8 if told to do so, // but always do it to the leader, since it has mangled chars if ($this->convert_to_utf8 == true || $strTagNumber == "LEA") { if (function_exists("mb_convert_encoding")) { $data = mb_convert_encoding($data, "UTF-8"); } else { $data = utf8_encode($data); } } $data = Parser::escapeXml($data); $data = trim($data); if ($strTagNumber == "LEA") { // leader $objLeader = $xml->createElementNS($this->marc_ns, "leader", $data); $xml->documentElement->appendChild($objLeader); } elseif ($strTagNumber == "REC") { // Pseudo-MARC "REC" data field to store the INNOPAC // bibliographic record number in subfield a. $objRecNum = $xml->createElementNS($this->marc_ns, "datafield"); $objRecNum->setAttribute("tag", "REC"); $objRecNum->setAttribute("ind1", ' '); $objRecNum->setAttribute("ind2", ' '); $objRecNumSub = $xml->createElementNS($this->marc_ns, "subfield", strtolower($data)); $objRecNumSub->setAttribute("code", 'a'); $objRecNum->appendChild($objRecNumSub); $xml->documentElement->appendChild($objRecNum); } elseif ((int) $strTagNumber <= 8) { // control fields $objControlField = $xml->createElementNS($this->marc_ns, "controlfield", $data); $objControlField->setAttribute("tag", $strTagNumber); $xml->documentElement->appendChild($objControlField); } else { // data fields $objDataField = $xml->createElementNS($this->marc_ns, "datafield"); $objDataField->setAttribute("tag", $strTagNumber); $objDataField->setAttribute("ind1", $strId1); $objDataField->setAttribute("ind2", $strId2); // if first character is not a pipe symbol, then this is the default |a subfield // so make that explicit for the array if (substr($data, 0, 1) != "|") { $data = "|a " . $data; } // split the subfield data on the pipe and add them in using the first // character after the delimiter as the subfield code $arrSubFields = explode("|", $data); foreach ($arrSubFields as $strSubField) { if ($strSubField != "") { $code = substr($strSubField, 0, 1); $data = trim(substr($strSubField, 1)); // check for a url, in which case we need to ensure there are no spaces; // which can happen on the wrap of the data in the marc display if (strlen($data) > 4) { if (substr($data, 0, 4) == "http") { $data = str_replace(" ", "", $data); } } $objSubField = $xml->createElementNS($this->marc_ns, "subfield", $data); $objSubField->setAttribute("code", $code); $objDataField->appendChild($objSubField); } } $xml->documentElement->appendChild($objDataField); } } return $xml; }
/** * Do the actual fetch of an individual record * * @param string record identifier * @return Results */ protected function doGetRecord($id) { if (!strstr($id, "-")) { throw new \Exception("could not find record"); } // database and id come in on same value, so split 'em $database = Parser::removeRight($id, "-"); $id = Parser::removeLeft($id, "-"); // get results $results = $this->doSearch("AN {$id}", $database, 1, 1); return $results; }
/** * Add links to the query object limits * * @param Query $query */ public function addQueryLinks(Query $query) { // we have to pass in the query object here rather than take // the property above because adding the links doesn't seem // to reflect back in the main object, even though they should // be references, maybe because limit objects are in an array? // add current query to query object itself $params = $query->extractSearchParams(); $params['controller'] = $this->request->getParam('controller'); $params['action'] = 'search'; $params['source'] = $this->request->getParam('source'); $params['sort'] = $this->request->getParam('sort'); // url $query->url = $this->request->url_for($params); // query only $query->url_query = Parser::removeLeft($query->url, '?'); // advanced search $params['action'] = 'advanced'; $query->url_advanced = $this->request->url_for($params); // search option links $search = $this->registry->getConfig('search'); if ($search instanceof \SimpleXMLElement) { $controller_map = $this->request->getControllerMap(); // combined results $combined = $controller_map->getUrlAlias('combined'); $combined_id = $combined . '_' . $query->getHash(); if ($this->request->getSessionData($combined_id) != null) { $params = $query->extractSearchParams(); $params['controller'] = $combined; $params['action'] = "results"; $search->combined_url = $this->request->url_for($params); } // individual search options foreach ($search->xpath("//option") as $option) { $id = (string) $option["id"]; if ((string) $option["source"] != '') { $id .= '_' . (string) $option["source"]; } $id .= '_' . $this->query->getHash(); // format the number // is this the current tab? if ($this->request->getControllerName() == (string) $option["id"] && ($this->request->getParam('source') == (string) $option["source"] || (string) $option["source"] == '')) { // mark as current $option->addAttribute('current', "1"); } // create url based on the search terms only! $params = $query->extractSearchParams(); $params['controller'] = $controller_map->getUrlAlias((string) $option["id"]); $params['action'] = "results"; $params['source'] = (string) $option["source"]; $params['sort'] = $this->request->getParam('sort'); // results url $url = $this->request->url_for($params); $option->addAttribute('url', $url); // hits url $params['action'] = 'hits'; $url = $this->request->url_for($params); $option->addAttribute('url_hits', $url); // cached search hit count? foreach ($this->request->getAllSessionData() as $session_id => $session_value) { // does this value in the cache have the save id as our tab? $id = str_replace("_" . $query->getHash(), "", $session_id); if ($id == (string) $option["id"]) { // yup, so add it $option->addAttribute('hits', Parser::number_format($session_value)); } } } // header('Content-type: text/xml'); echo $search->asXML(); exit; $this->registry->setConfig('search', $search); } // links to remove facets foreach ($query->getLimits() as $limit) { $params = $this->currentParams(); $value = $limit->value; if ($limit->display != "") { $value = $limit->display; } // urlencode here necessary to support the urlencode above on 'key' urls $params = Parser::removeFromArray($params, urlencode($limit->param), $value); $limit->remove_url = $this->request->url_for($params); } }
public function map() { // score $this->score = (string) $this->document->documentElement->getAttribute("RANK"); // record data $record = $this->document->documentElement->getElementsByTagName("record")->item(0); // print $this->document->saveXML(); $display = $this->getElement($record, "display"); $search = $this->getElement($record, "search"); $sort = $this->getElement($record, "sort"); $addata = $this->getElement($record, "addata"); $facets = $this->getElement($record, "facets"); if ($display != null) { // database name $this->database_name = $this->getElementValue($display, "source"); $this->database_name = strip_tags($this->database_name); // journal $this->journal = $this->getElementValue($display, "ispartof"); // snippet $this->snippet = $this->getElementValue($display, "snippet"); $this->snippet = strip_tags($this->snippet); // description $this->abstract = $this->getElementValue($display, "description"); $this->abstract = strip_tags($this->abstract); // language $this->language = $this->getElementValue($display, "language"); } if ($search != null) { // record id $this->record_id = $this->getElementValue($search, "recordid"); // year $this->year = $this->getElementValue($search, "creationdate"); // issn $issn = $this->getElementValue($search, "issn"); $issn = preg_replace('/\\D/', "", $issn); array_push($this->issns, $issn); // authors $authors = $this->getElementValues($search, "creatorcontrib"); foreach ($authors as $author) { array_push($this->authors, new Xerxes\Record\Author($author, null, "personal")); } // format // @todo: create map for internal $this->format->setFormat($this->getElementValue($search, "rsrctype")); } // article data if ($addata != null) { $this->journal_title = $this->start_page = $this->getElementValue($addata, "jtitle"); $this->volume = $this->getElementValue($addata, "volume"); $this->issue = $this->getElementValue($addata, "issue"); $this->start_page = $this->getElementValue($addata, "spage"); $this->end_page = $this->getElementValue($addata, "epage"); // abstract $abstract = $this->getElementValue($addata, "abstract"); if ($this->abstract == "") { $this->abstract = strip_tags($abstract); } // gale madness if (stristr($this->database_name, "gale")) { if (strpos($this->abstract, 'the full-text of this article') !== false) { $this->abstract = Parser::removeLeft($this->abstract, 'Abstract:'); } } } // subjects if ($facets != null) { $topics = $this->getElementValues($facets, "topic"); foreach ($topics as $topic) { $subject_object = new Xerxes\Record\Subject(); $subject_object->value = $topic; $subject_object->display = $topic; array_push($this->subjects, $subject_object); } } // title if ($sort != null) { $this->title = $this->getElementValue($sort, "title"); } // Gale title clean-up, because for some reason unknown to man they put weird // notes and junk at the end of the title. so remove them here and add them to notes. // @todo factor this out somehow? since this is very similar to Gale MetalibRecord code if (stristr($this->database_name, "gale") || stristr($this->database_name, "muse")) { $strGaleRegExp = '/\\(([^)]*)\\)/'; $arrMatches = array(); if (preg_match_all($strGaleRegExp, $this->title, $arrMatches) != 0) { $this->title = preg_replace($strGaleRegExp, "", $this->title); foreach ($arrMatches[1] as $strMatch) { array_push($this->notes, $strMatch); } } } }