Пример #1
0
 public function doExecute()
 {
     $configLinkResolver = $this->registry->getConfig("LINK_RESOLVER_ADDRESS", true);
     $configSID = $this->registry->getConfig("APPLICATION_SID", false, "calstate.edu:xerxes");
     $objXerxesRecord = new Xerxes_MetalibRecord();
     $objXerxesRecord->loadXML($this->getRecord());
     $this->request->setRedirect($objXerxesRecord->getOpenURL($configLinkResolver, $configSID));
     return 1;
 }
 public function doExecute()
 {
     // get properties from request
     $strUsername = $this->request->getSession("username");
     $strGroup = $this->request->getProperty("group");
     $strResultSet = $this->request->getProperty("resultSet");
     $iStartRecord = $this->request->getProperty("startRecord");
     // get the search start date
     $objSearchXml = $this->getCache($strGroup, "search", "SimpleXML");
     $strDate = (string) $objSearchXml->date;
     // construct a fully unique id for metalib record based on
     // date, resultset, and startrecord numbers
     $strID = "";
     $strID = $strDate . ":";
     $strID .= $strResultSet . ":";
     $strID .= str_pad($iStartRecord, 6, "0", STR_PAD_LEFT);
     // the save and delete action come in on the same onClick event from the search results page,
     // so we have to check here to see if it is a delete or save based on the session. This is a
     // bit dangerous, since maybe the session got out of sync? Oh well, it'll do for now, since
     // that's what was done with the previous cookie implementation.
     $objData = new Xerxes_DataMap();
     $bolAdd = !$this->isMarkedSaved($strResultSet, $iStartRecord);
     $strInsertedId = null;
     if ($bolAdd == true) {
         // add command
         // get record from metalib result set
         $objXerxesRecord = new Xerxes_MetalibRecord();
         $objXerxesRecord->loadXML($this->getRecord());
         // add to database
         $objData->addRecord($strUsername, "metalib", $strID, $objXerxesRecord);
         $strInsertedId = $objXerxesRecord->id;
         // mark saved for feedback on search results
         $this->markSaved($objXerxesRecord);
     } else {
         // delete command
         $objData->deleteRecordBySource($strUsername, "metalib", $strID);
         $this->unmarkSaved($strResultSet, $iStartRecord);
     }
     // build a response
     $objXml = new DOMDocument();
     $objXml->loadXML("<results />");
     if ($bolAdd == false) {
         // flag this as being a delete comand in the view, in the event
         // user has javascript turned off and we need to show them an actual page
         $objDelete = $objXml->createElement("delete", "1");
         $objXml->documentElement->appendChild($objDelete);
     } else {
         // add inserted id for ajax response
         $objInsertedId = $objXml->createElement("savedRecordID", $strInsertedId);
         $objXml->documentElement->appendChild($objInsertedId);
     }
     $this->request->addDocument($objXml);
     return 1;
 }
Пример #3
0
 /**
  * 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;
 }
Пример #4
0
 /**
  * Get a set of records from the user's saved records table 
  *
  * @param string $strUsername		[optional] username under which the records are saved
  * @param string $strView			[optional] 'brief' or 'full', defaults to 'full'.
  * @param string $strOrder			[optional] sort order of the results" 'year', 'author' or 'title', defaults to date added (desc)
  * @param array $arrID				[optional] array of id values
  * @param int $iStart				[optional] offset to start from, defaults to 1, unless $arrID specified
  * @param int $iCount				[optional] number of records to return, defaults to all, unless $arrID specified
  * @param string $strFormat			[optional] limit records to specific format
  * @param string $strLabel			[optiional] limit record to specific tag
  * @return array					array of Xerxes_Data_Record objects
  */
 private function returnRecords($strUsername = null, $strView = "full", $arrID = null, $strOrder = null, $iStart = 1, $iCount = null, $strFormat = null, $strLabel = null)
 {
     // esnure that we don't just end-up with a big database dump
     if ($arrID == null && $strUsername == null && $iCount == null) {
         throw new Exception("query must be limited by username, id(s), or record count limit");
     }
     #### construct the query
     $arrParams = array();
     // sql paramaters
     $strSQL = "";
     // main sql query
     $strTable = "";
     // tables to include
     $strColumns = "";
     // column portion of query
     $strCriteria = "";
     // where clause in query
     $strLimit = "";
     // record limit and off-set
     $strSort = "";
     // sort part query
     // set the start record, limit and offset; mysql off-set is zero-based
     if ($iStart == null) {
         $iStart = 1;
     }
     $iStart--;
     // we'll only apply a limit if there was a count
     if ($iCount != null) {
         $strLimit = " LIMIT {$iStart}, {$iCount} ";
     }
     // which columns to include -- may not actually use brief any more
     $strTable = " xerxes_records ";
     $strColumns = " * ";
     if ($strView == "brief") {
         $strColumns = " xerxes_records.id, xerxes_records.original_id, xerxes_records.source, \r\n\t\t\t\txerxes_records.username, xerxes_records.nonsort, xerxes_records.title, xerxes_records.author, \r\n\t\t\t\txerxes_records.format, xerxes_records.year, xerxes_records.refereed ";
     } else {
         $strColumns = " xerxes_records.* ";
     }
     // limit to a specific user
     if ($strUsername != "") {
         $strCriteria = " WHERE xerxes_records.username = :username ";
         $arrParams[":username"] = $strUsername;
     } else {
         $strCriteria = " WHERE xerxes_records.username LIKE '%' ";
     }
     // limit to specific tag
     if ($strLabel != "") {
         // need to include the xerxes tags table
         $strTable .= ", xerxes_tags ";
         // and limit the results to only those where the tag matches!
         $strCriteria .= " AND xerxes_tags.record_id = xerxes_records.id ";
         $strCriteria .= " AND xerxes_tags.tag = :tag ";
         $arrParams[":tag"] = $strLabel;
     }
     // limit to specific format
     if ($strFormat != "") {
         $strCriteria .= " AND format = :format ";
         $arrParams[":format"] = $strFormat;
     }
     // limit to specific records by id
     if ($arrID != null) {
         // make sure we've got an array
         if (!is_array($arrID)) {
             $arrID = array($arrID);
         }
         $strCriteria .= " AND (";
         for ($x = 0; $x < count($arrID); $x++) {
             if ($x > 0) {
                 $strCriteria .= " OR";
             }
             $num = sprintf("%04d", $x);
             // pad it to keep id's unique for mssql
             $strCriteria .= " id = :id{$num} ";
             $arrParams[":id{$num}"] = $arrID[$x];
         }
         $strCriteria .= ")";
     }
     // sort option
     // order by supplied sort criteria otherwise by id
     // to show most recently added first
     switch ($strOrder) {
         case "year":
             $strSort = " ORDER BY year DESC";
             break;
         case "author":
             $strSort = " ORDER BY author";
             break;
         case "title":
             $strSort = " ORDER BY title";
             break;
         default:
             $strSort = " ORDER BY id DESC";
             break;
     }
     // kind of a funky query, but do it this way to limit to 10 (or whatever) records
     // per page, while joining in as many tags as exist
     $strSQL = "SELECT * FROM \r\n\t\t\t(SELECT {$strColumns} FROM {$strTable} {$strCriteria} {$strSort} {$strLimit} ) as xerxes_records\r\n\t\t\tLEFT OUTER JOIN xerxes_tags on xerxes_records.id = xerxes_tags.record_id";
     // ms sql server specific code
     $sql_server_clean = null;
     if ($this->rdbms == "mssql") {
         // mimicking the MySQL LIMIT clause
         $strMSPage = "";
         if ($iCount != null) {
             $strMSLimit = $iStart + $iCount;
             $strMSPage = "WHERE row > {$iStart} and row <= {$strMSLimit}";
         }
         $strSQL = "SELECT * FROM\r\n\t\t\t\t( SELECT * FROM ( SELECT {$strColumns} , ROW_NUMBER() OVER ( {$strSort} ) as row FROM {$strTable} {$strCriteria} ) \r\n\t\t\t\t\tas tmp {$strMSPage} ) as xerxes_records \r\n\t\t\t\tLEFT OUTER JOIN xerxes_tags on xerxes_records.id = xerxes_tags.record_id";
         $sql_server_clean = array(":username", ":tag", ":format");
         for ($x = 0; $x < count($arrID); $x++) {
             $num = sprintf("%04d", $x);
             // pad it to keep id's unique for mssql
             array_push($sql_server_clean, ":id{$num}");
         }
     }
     #### return the objects
     $arrResults = array();
     // results as array
     $arrRecords = array();
     // records as array
     $arrResults = $this->select($strSQL, $arrParams, $sql_server_clean);
     if ($arrResults != null) {
         $objRecord = new Xerxes_Data_Record();
         foreach ($arrResults as $arrResult) {
             // if the previous row has a different id, then we've come
             // to a new database, otherwise these are values from the outter join
             if ($arrResult["id"] != $objRecord->id) {
                 if ($objRecord->id != null) {
                     array_push($arrRecords, $objRecord);
                 }
                 $objRecord = new Xerxes_Data_Record();
                 $objRecord->load($arrResult);
                 // only full display will include marc records
                 if (array_key_exists("marc", $arrResult)) {
                     if ($arrResult["record_type"] == "xerxes_record") {
                         // new-style saved record
                         $objRecord->xerxes_record = unserialize($arrResult["marc"]);
                     } else {
                         // old style
                         $objXerxes_Record = new Xerxes_MetalibRecord();
                         $objXerxes_Record->loadXML($arrResult["marc"]);
                         $objRecord->xerxes_record = $objXerxes_Record;
                     }
                 }
             }
             // if the current row's outter join value is not already stored,
             // then then we've come to a unique value, so add it
             $arrColumns = array("tag" => "tags");
             foreach ($arrColumns as $column => $identifier) {
                 if (array_key_exists($column, $arrResult)) {
                     if (!in_array($arrResult[$column], $objRecord->{$identifier})) {
                         array_push($objRecord->{$identifier}, $arrResult[$column]);
                     }
                 }
             }
         }
         // get the last one
         array_push($arrRecords, $objRecord);
     }
     return $arrRecords;
 }
Пример #5
0
 public function doExecute()
 {
     $this->add_export_options();
     // get request paramaters
     $strUsername = $this->request->getSession("username");
     $strOrder = $this->request->getProperty("sortKeys");
     $iStart = $this->request->getProperty("startRecord");
     $strReturn = $this->request->getProperty("return");
     $strLabel = $this->request->getProperty("label");
     $strType = $this->request->getProperty("type");
     $strView = $this->request->getProperty("view");
     // id numbers can come in the form of multiple 'record' params or a single
     // 'records' param, with the ids comma separated
     $arrID = $this->request->getProperty("record", true);
     $strIDs = $this->request->getProperty("records");
     if ($strIDs != null) {
         $arrID = explode(",", $strIDs);
     }
     // these are typically set in actions.xml
     $strLimit = $this->request->getProperty("limit");
     $strLoginOverride = $this->request->getProperty("doNotEnforceLogin");
     // configuration settings
     // default records per page is either set explicitly in saved_record_per_page in config
     // or is the main (metasearch) defaul_records_per_page or 20 which is the const
     $defaultMax = $this->registry->getConfig("DEFAULT_RECORDS_PER_PAGE", false, self::DEFAULT_RECORDS_PER_PAGE);
     $iCount = $this->registry->getConfig("SAVED_RECORDS_PER_PAGE", false, $defaultMax);
     $iCountExport = $this->registry->getConfig("MAXIMUM_RECORD_EXPORT_LIMIT", false, 1000);
     $configMarcBrief = $this->registry->getConfig("XERXES_BRIEF_INCLUDE_MARC", false, false);
     $configMarcFull = $this->registry->getConfig("XERXES_FULL_INCLUDE_MARC", false, false);
     // brief records and export actions should be set to export limit
     if ($strLimit == null) {
         $iCount = $iCountExport;
     }
     // save the return url back to metasearch page if specified
     if ($strReturn != "") {
         $this->request->setSession("SAVED_RETURN", $strReturn);
     }
     ### access control
     // can only override login if username is *NOT* supplied in the paramaters,
     // this prevents people from manually attempting this; 'doNotEnforceLogin'
     // must then only be used in conjunction with specific id numbers
     if ($this->request->getProperty("username") != null && $strLoginOverride != null) {
         throw new Exception("access denied");
     }
     // ensure this is the same user, unless 'doNotEnforceLogin' overrides this,
     // such as with RefWorks or other third-party export
     if ($strLoginOverride == null) {
         $strRedirect = $this->enforceUsername();
         if ($strRedirect != null) {
             $this->request->setRedirect($strRedirect);
             return 1;
         }
     }
     ### records
     // get the total number of records
     $iTotal = $this->getTotal($strUsername, $strLabel, $strType);
     // fetch result(s) from the database
     $objData = new Xerxes_DataMap();
     $arrResults = array();
     if ($arrID != "") {
         $arrResults = $objData->getRecordsByID($arrID);
     } elseif ($strLabel != "") {
         $arrResults = $objData->getRecordsByLabel($strUsername, $strLabel, $strOrder, $iStart, $iCount);
     } elseif ($strType != "") {
         $arrResults = $objData->getRecordsByFormat($strUsername, $strType, $strOrder, $iStart, $iCount);
     } else {
         $arrResults = $objData->getRecords($strUsername, $strView, $strOrder, $iStart, $iCount);
     }
     // create master results xml doc
     $objXml = new DOMDocument();
     $objXml->recover = true;
     $objXml->loadXML("<results />");
     if (count($arrResults) > 0) {
         $objRecords = $objXml->createElement("records");
         $objXml->documentElement->appendChild($objRecords);
         // @todo move this to point of save for search arch
         /* 
         enhance records with links generated from metalib templates,
         and get a list of databases too. We need to get the Xerxes_Records 
         out of our list of Xerxes_Data_Records first.
         */
         $xerxes_records = array();
         $database_links_dom = "";
         foreach ($arrResults as $objDataRecord) {
             if ($objDataRecord->xerxes_record instanceof Xerxes_MetalibRecord) {
                 array_push($xerxes_records, $objDataRecord->xerxes_record);
             }
         }
         if (count($xerxes_records) > 0) {
             Xerxes_MetalibRecord::completeUrlTemplates($xerxes_records, $this->request, $this->registry, $database_links_dom);
             $database_links = $objXml->importNode($database_links_dom->documentElement, true);
             $objXml->documentElement->appendChild($database_links);
         }
         /*  Add the records */
         foreach ($arrResults as $objDataRecord) {
             // create a new record
             $objRecord = $objXml->createElement("record");
             $objRecords->appendChild($objRecord);
             // full record url
             $arrParams = array("base" => "folder", "action" => "full", "username" => $strUsername, "record" => $objDataRecord->id);
             $url = $this->request->url_for($arrParams);
             $objUrlFull = $objXml->createElement("url_full", $url);
             $objRecord->appendChild($objUrlFull);
             // delete url
             $arrParams = array("base" => "folder", "action" => "delete", "username" => $strUsername, "source" => $objDataRecord->source, "id" => $objDataRecord->original_id, "type" => $strType, "label" => $strLabel, "startRecord" => $iStart, "total" => $iTotal, "sortKeys" => $strOrder, "recordsPerPage" => $iCount);
             $url = $this->request->url_for($arrParams);
             $objUrlDelete = $objXml->createElement("url_delete", $url);
             $objRecord->appendChild($objUrlDelete);
             // openurl link
             $arrParams = array("base" => "folder", "action" => "redirect", "type" => "openurl", "id" => $objDataRecord->id);
             $configLinkResolver = $this->registry->getConfig("LINK_RESOLVER_ADDRESS", true);
             $configSID = $this->registry->getConfig("APPLICATION_SID", false, "calstate.edu:xerxes");
             foreach ($objDataRecord->properties() as $key => $value) {
                 if ($key == "username" && $strLoginOverride != null) {
                     // exclude the username if login overridden, for privacy
                 } elseif ($key == "xerxes_record" && $value != null) {
                     // import the xerxes record
                     $objXerxesRecord = $value;
                     $objBibRecord = new DOMDocument();
                     $objBibRecord = $objXerxesRecord->toXML();
                     // import it
                     $objImportNode = $objXml->importNode($objBibRecord->documentElement, true);
                     $objRecord->appendChild($objImportNode);
                     // and openurl kev context object from record
                     $kev = Xerxes_Framework_Parser::escapeXml($objXerxesRecord->getOpenURL(null, $configSID));
                     $objOpenUrl = $objXml->createElement("openurl_kev_co", $kev);
                     $objRecord->appendChild($objOpenUrl);
                     // full open url
                     $url = Xerxes_Framework_Parser::escapeXml($objXerxesRecord->getOpenURL($configLinkResolver, $configSID));
                     $objUrlOpen = $objXml->createElement("url_open", $url);
                     $objRecord->appendChild($objUrlOpen);
                     // import the marc record, but only if configured to do so; since both brief
                     // and full record display come in on the same command, we'll use the record count
                     // here as an approximate for the brief versus full view -- hacky, hacky
                     $iNumRecords = count($arrID);
                     if ($strView != "brief" && $configMarcFull == true && $iNumRecords == 1 || $strView != "brief" && $configMarcBrief == true && $iNumRecords != 1) {
                         $objOriginalXml = $objXerxesRecord->getOriginalXML();
                         $objImportNode = $objXml->importNode($objOriginalXml->documentElement, true);
                         $objRecord->appendChild($objImportNode);
                     }
                 } else {
                     $objElement = $objXml->createElement($key, Xerxes_Framework_Parser::escapeXml($value));
                     $objRecord->appendChild($objElement);
                 }
             }
             $arrMulti = array("tags");
             foreach ($arrMulti as $multi) {
                 foreach ($objDataRecord->{$multi} as $value) {
                     // remove the trailing 's'
                     $single = substr($multi, 0, strlen($multi) - 1);
                     if ($value != null) {
                         $objElement = $objXml->createElement($single, Xerxes_Framework_Parser::escapeXml($value));
                         $objRecord->appendChild($objElement);
                     }
                 }
             }
         }
     }
     $this->request->addDocument($objXml);
     return 1;
 }
 public function testMultipleISSNs()
 {
     $this->Xerxes_MetalibRecord_Document->load($this->dir . "/data/metalib-wos.xml");
     $record = $this->Xerxes_MetalibRecord_Document->record(1);
     $this->assertEquals(count($record->getAllISSN()), 1);
 }
Пример #7
0
 /**
  * Converts records from marc to xerxes_record and adds them to the master xml response
  * Also adds info on whether the record has already been saved this session. 
  *
  * @param DOMDOcument $objXml		master xml document
  * @param array $arrRecords			an array of marc records
  * @param bool $configMarcResults	whether to append the original marc records to the response
  * @return DOMDOcument				master xml response updated with record data
  */
 protected function addRecords($objXml, $arrRecords, $configMarcResults)
 {
     $objRecords = $objXml->createElement("records");
     $arrXerxesRecords = array();
     foreach ($arrRecords as $objRecord) {
         $objXerxesRecord = new Xerxes_MetalibRecord();
         $objXerxesRecord->loadXml($objRecord);
         array_push($arrXerxesRecords, $objXerxesRecord);
     }
     // enhance with links computed from metalib templates.
     Xerxes_MetalibRecord::completeUrlTemplates($arrXerxesRecords, $this->request, $this->registry);
     $position = $this->request->getProperty("startRecord");
     if ($position == "") {
         $position = 1;
     }
     foreach ($arrXerxesRecords as $objXerxesRecord) {
         $objRecordContainer = $objXml->createElement("record");
         $objRecords->appendChild($objRecordContainer);
         // basis for most of the links below
         $arrParams = array("base" => "metasearch", "group" => $this->request->getProperty("group"), "resultSet" => $objXerxesRecord->getResultSet(), "startRecord" => $objXerxesRecord->getRecordNumber());
         // full-text link
         $arrFullText = $arrParams;
         $arrFullText["action"] = "record";
         if ($this->request->getProperty("facet") != "") {
             // append this so the full record page knows how to get back
             $arrFullText["return"] = Xerxes_Framework_Parser::escapeXml($this->request->getServer("REQUEST_URI"));
         } else {
             // this is a regular (non-facet) result
             // we keep current resultset and position (rather than original resultset
             // and recordNumber) for the benefit of the merged set where these are different
             $arrFullText["resultSet"] = $this->request->getProperty("resultSet");
             $arrFullText["startRecord"] = $position;
         }
         $url = $this->request->url_for($arrFullText);
         $objUrlFull = $objXml->createElement("url_full", $url);
         $objRecordContainer->appendChild($objUrlFull);
         // save-delete link
         $arrSave = $arrParams;
         $arrSave["action"] = "save-delete";
         $url = $this->request->url_for($arrSave);
         $objUrlSave = $objXml->createElement("url_save_delete", $url);
         $objRecordContainer->appendChild($objUrlSave);
         // openurl redirect link
         $arrOpen = $arrParams;
         $arrOpen["action"] = "sfx";
         $url = $this->request->url_for($arrOpen);
         $objOpenUrl = $objXml->createElement("url_open", $url);
         $objRecordContainer->appendChild($objOpenUrl);
         // openurl kev context object please
         $configSID = $this->registry->getConfig("APPLICATION_SID", false, "calstate.edu:xerxes");
         $kev = Xerxes_Framework_Parser::escapeXml($objXerxesRecord->getOpenURL(null, $configSID));
         $objOpenUrl = $objXml->createElement("openurl_kev_co", $kev);
         $objRecordContainer->appendChild($objOpenUrl);
         // import xerxes xml
         $objXerxesXml = $objXerxesRecord->toXML();
         $objImportRecord = $objXml->importNode($objXerxesXml->documentElement, true);
         $objRecordContainer->appendChild($objImportRecord);
         // optionally import marc-xml
         if ($configMarcResults == true) {
             $objMarcRecord = $objXerxesRecord->getMarcXML();
             $objImportRecord = $objXml->importNode($objMarcRecord->getElementsByTagName("record")->item(0), true);
             $objRecordContainer->appendChild($objImportRecord);
         }
         $position++;
     }
     $objXml->documentElement->appendChild($objRecords);
     return $objXml;
 }