/** * Return top level Metalib KB categories as XML * * @param Xerxes_Framework_Request $objRequest * @param Xerxes_Framework_Registry $objRegistry * @return int status */ public function doExecute() { $objXml = new DOMDOcument(); $objData = new Xerxes_DataMap(); $lang = $this->request->getProperty("lang"); $arrResults = $objData->getCategories($lang); $x = 1; if (count($arrResults) > 0) { $objXml->loadXML("<categories />"); foreach ($arrResults as $objCategoryData) { $objCategory = $objXml->createElement("category"); $objCategory->setAttribute("position", $x); foreach ($objCategoryData->properties() as $key => $value) { if ($value != null) { $objElement = $objXml->createElement("{$key}", Xerxes_Framework_Parser::escapeXml($value)); $objCategory->appendChild($objElement); } } // add the url for the category $arrParams = array("base" => "databases", "action" => "subject", "subject" => $objCategoryData->normalized); $url = Xerxes_Framework_Parser::escapeXml($this->request->url_for($arrParams)); $objElement = $objXml->createElement("url", $url); $objCategory->appendChild($objElement); $objXml->documentElement->appendChild($objCategory); $x++; } } $this->request->addDocument($objXml); return 1; }
public function doExecute() { $arrSaved = array(); $arrMatch = array(); $objData = new Xerxes_DataMap(); // find all of the xerxes records $objRecords = $this->request->getData("//xerxes_record", null, "DOMNodeList"); if ($objRecords->length > 0) { foreach ($objRecords as $objXerxesRecord) { $strResultSet = ""; $strRecordNumber = ""; $objResultSet = $objXerxesRecord->getElementsByTagName("result_set")->item(0); $objRecordNumber = $objXerxesRecord->getElementsByTagName("record_number")->item(0); if ($objResultSet != null) { $strResultSet = $objResultSet->nodeValue; } if ($objRecordNumber != null) { $strRecordNumber = $objRecordNumber->nodeValue; } if ($strRecordNumber != "" && $strResultSet != "") { // see if it's listed in session as being saved if (Xerxes_Helper::isMarkedSaved($strResultSet, $strRecordNumber)) { $key = Xerxes_Helper::savedRecordKey($strResultSet, $strRecordNumber); $id = $_SESSION['resultsSaved'][$key]['xerxes_record_id']; array_push($arrSaved, $id); $arrMatch[$id] = $strResultSet . ":" . $strRecordNumber; } } } if (count($arrSaved) == 0) { return 0; } // fetch all the saved records on this page in one query to the database $arrResults = $objData->getRecordsByID($arrSaved); if (count($arrResults) == 0) { return 0; } else { $objXml = new DOMDocument(); $objXml->loadXML("<saved_records />"); foreach ($arrResults as $objSavedRecord) { // id $objSavedRecordXml = $objXml->createElement("saved"); $objSavedRecordXml->setAttribute("id", $arrMatch[$objSavedRecord->id]); $objIDXml = $objXml->createElement("id", $objSavedRecord->id); $objSavedRecordXml->appendChild($objIDXml); // labels foreach ($objSavedRecord->tags as $tag) { $objTagXml = $objXml->createElement("tag", Xerxes_Framework_Parser::escapeXml($tag)); $objSavedRecordXml->appendChild($objTagXml); } $objXml->documentElement->appendChild($objSavedRecordXml); } $this->request->addDocument($objXml); return 1; } } }
public function doExecute() { $lang = $this->request->getProperty("lang"); // main list of subcategories and databases $objXml = new DOMDocument(); $objXml->loadXML("<category />"); // list of subcategories that should go in the sidebar $objSidebar = new DOMDocument(); $objSidebar->loadXML("<sidebar />"); $strOld = $this->request->getProperty("category"); $strSubject = $this->request->getProperty("subject"); $configSidebar = $this->registry->getConfig("SUBCATEGORIES_SIDEBAR", false, null, $lang); $arrSidebar = explode(",", $configSidebar); // look up home page default subject from config if no subject was specified, and we were // instructed to look it up with use_categories_quicksearch=true if ($strSubject == "" && $this->request->getProperty("use_categories_quicksearch") == "true") { $strSubject = $this->registry->getConfig("categories_quicksearch", false, "quick-search", $lang); } $objData = new Xerxes_DataMap(); $objCategoryData = $objData->getSubject($strSubject, $strOld, "metalib", null, $lang); $y = 1; if ($objCategoryData != null) { $objXml->documentElement->setAttribute("name", $objCategoryData->name); $objXml->documentElement->setAttribute("normalized", $objCategoryData->normalized); // standard url for the category $arrParams = array("base" => "databases", "action" => "subject", "subject" => $objCategoryData->normalized); $url = Xerxes_Framework_Parser::escapeXml($this->request->url_for($arrParams)); $objElement = $objXml->createElement("url", $url); $objXml->documentElement->appendChild($objElement); // the attributes of the subcategories $db_list_index = 1; foreach ($objCategoryData->subcategories as $objSubData) { $objSubCategory = $objXml->createElement("subcategory"); $objSubCategory->setAttribute("name", $objSubData->name); $objSubCategory->setAttribute("position", $y); $objSubCategory->setAttribute("id", $objSubData->id); $y++; // the database information foreach ($objSubData->databases as $objDatabaseData) { $objDatabase = Xerxes_Helper::databaseToNodeset($objDatabaseData, $this->request, $this->registry, $db_list_index); $objDatabase = $objXml->importNode($objDatabase, true); $objSubCategory->appendChild($objDatabase); } // if marked for the sidebar, put it there if (in_array($objSubData->name, $arrSidebar)) { $objImport = $objSidebar->importNode($objSubCategory, true); $objSidebar->documentElement->appendChild($objImport); } else { $objXml->documentElement->appendChild($objSubCategory); } } } $this->request->addDocument($objXml); $this->request->addDocument($objSidebar); return 1; }
public function doExecute() { // ensure this is the same user $strRedirect = $this->enforceUsername(); if ($strRedirect != null) { $this->request->setRedirect($strRedirect); return 1; } $strEmail = ""; // email address $strSubject = ""; // subject entered by the user $strBody = ""; // body of the email $strNotes = ""; // notes entered by the user $strRecords = ""; // results in citation style $headers = ""; // to specify html as the format of the email // get the records from the previous results command $objXml = $this->request->toXML(); // get user entered values $strEmail = $this->request->getProperty("email"); $strSubject = $this->request->getProperty("subject"); $strNotes = $this->request->getProperty("notes"); $strUsername = $this->request->getSession("username"); // get configuration options $configFromEmail = $this->registry->getConfig("EMAIL_FROM", false, null); if ($strEmail == null) { throw new Exception("text_folder_error_no_email"); } // transform the documents to a basic style for now // will give them citation style options in the future $strRecords = Xerxes_Framework_Parser::transform($objXml, "xsl/citation/basic.xsl"); // add notes and records to body $strBody = $strNotes . "\r\n\r\n"; $strBody .= $strRecords; // set an explcit 'from' address if configured if ($configFromEmail != null) { $headers .= "From: {$configFromEmail} \r\n"; } // send the user back out, so they don't step on this again if (mail($strEmail, $strSubject, $strBody, $headers)) { // send the user back out, so they don't step on this again $arrParams = array("base" => "folder", "action" => "output_email", "username" => $strUsername, "message" => "done"); $url = $this->request->url_for($arrParams); $this->request->setRedirect($url); return 1; } else { throw new Exception("text_folder_error_email_not_sent"); } }
public function doExecute() { $url = $this->request->getProperty("url"); $size = $this->registry->getConfig("LIBRARIAN_IMAGE_SIZE", false, 150); $domains = $this->registry->getConfig("LIBRARIAN_IMAGE_DOMAINS", false); // images can only come from these domains, for added security if ($domains != null) { $bolPassed = Xerxes_Framework_Parser::withinDomain($url, $domains); if ($bolPassed == false) { throw new Exception("librarian image not allowed from that domain"); } } if (!function_exists("gd_info")) { $this->request->setRedirect($url); return 1; } else { $image_string = file_get_contents($url); header("Content-type: image/jpg"); if ($image_string == "") { $this->createblank(); } else { // convert to a thumbnail $original = imagecreatefromstring($image_string); if ($original == false) { $this->createblank(); exit; } $old_x = imagesx($original); $old_y = imagesy($original); if ($old_x > $old_y) { $thumb_w = $size; $thumb_h = $old_y * ($size / $old_x); } if ($old_x < $old_y) { $thumb_w = $old_x * ($size / $old_y); $thumb_h = $size; } if ($old_x == $old_y) { $thumb_w = $size; $thumb_h = $size; } $thumb = imagecreatetruecolor($thumb_w, $thumb_h); imagecopyresampled($thumb, $original, 0, 0, 0, 0, $thumb_w, $thumb_h, $old_x, $old_y); imagejpeg($thumb, null, 100); imagedestroy($thumb); imagedestroy($original); } return 1; } }
/** * Parses a validation response from a CAS server to see if the returning CAS request is valid * * @param string $strResults xml or plain text response from cas server * @return bool true if valid, false otherwise * @exception throws exception if cannot parse response or invalid version */ private function isValid() { // values from the request $strTicket = $this->request->getProperty("ticket"); // configuration settings $configCasValidate = $this->registry->getConfig("CAS_VALIDATE", true); // figure out which type of response this is based on the service url $arrURL = explode("/", $configCasValidate); $service = array_pop($arrURL); // now get it! $strUrl = $configCasValidate . "?ticket=" . $strTicket . "&service=" . urlencode($this->validate_url); $strResults = Xerxes_Framework_Parser::request($strUrl); // validate is plain text if ($service == "validate") { $arrMessage = explode("\n", $strResults); if (count($arrMessage) >= 2) { if ($arrMessage[0] == "yes") { return $arrMessage[1]; } } else { throw new Exception("Could not parse CAS validation response."); } } elseif ($service == "serviceValidate" || $service == "proxyValidate") { // these are XML based $objXml = new DOMDocument(); $objXml->loadXML($strResults); $strCasNamespace = "http://www.yale.edu/tp/cas"; $objUser = $objXml->getElementsByTagNameNS($strCasNamespace, "user")->item(0); $objFailure = $objXml->getElementsByTagNameNS($strCasNamespace, "authenticationFailure")->item(0); if ($objUser != null) { if ($objUser->nodeValue != "") { return $objUser->nodeValue; } else { throw new Exception("CAS validation response missing username value"); } } elseif ($objFailure != null) { // see if error, rather than failed authentication if ($objFailure->getAttribute("code") == "INVALID_REQUEST") { throw new Exception("Invalid request to CAS server: " . $objFailure->nodeValue); } } else { throw new Exception("Could not parse CAS validation response."); } } else { throw new Exception("Unsupported CAS version."); } // if we got this far, the request was invalid return false; }
/** * Converts a sting to a normalized (no-spaces, non-letters) string * * @param string $strSubject original string * @return string normalized string */ public static function normalize($strSubject) { $strNormalized = iconv('UTF-8', 'ASCII//TRANSLIT', $strSubject); // this is influenced by the setlocale() call with category LC_CTYPE; see PopulateDatabases.php $strNormalized = Xerxes_Framework_Parser::strtolower($strNormalized); $strNormalized = str_replace("&", "", $strNormalized); $strNormalized = str_replace("'", "", $strNormalized); $strNormalized = str_replace("+", "-", $strNormalized); $strNormalized = str_replace(" ", "-", $strNormalized); $strNormalized = Xerxes_Framework_Parser::preg_replace('/\\W/', "-", $strNormalized); while (strstr($strNormalized, "--")) { $strNormalized = str_replace("--", "-", $strNormalized); } return $strNormalized; }
public function doExecute() { $configToken = $this->registry->getConfig("BX_TOKEN", false); if ($configToken != null) { $configBX = $this->registry->getConfig("BX_SERVICE_URL", false, "http://recommender.service.exlibrisgroup.com/service"); $configLinkResolver = $this->registry->getConfig("LINK_RESOLVER_ADDRESS", true); $configSID = $this->registry->getConfig("APPLICATION_SID", false, "calstate.edu:xerxes"); $configMaxRecords = $this->registry->getConfig("BX_MAX_RECORDS", false, "10"); $configMinRelevance = $this->registry->getConfig("BX_MIN_RELEVANCE", false, "0"); $open_url = $this->request->getData("//openurl_kev_co"); $url = $configBX . "/recommender/openurl?token={$configToken}&{$open_url}&res_dat=source=global&threshold={$configMinRelevance}&maxRecords={$configMaxRecords}"; try { $xml = Xerxes_Framework_Parser::request($url, 4); if ($xml == "") { throw new Exception("No response from bx service"); } } catch (Exception $e) { trigger_error("Could not get result from bX service: " . $e->getTraceAsString(), E_USER_WARNING); return 1; } // header("Content-type: text/xml"); echo $xml; exit; $doc = new Xerxes_BxRecord_Document(); $doc->loadXML($xml); $objXml = new DOMDocument(); $objXml->loadXML("<recommendations />"); $results = $doc->records(); $x = 0; if (count($results) > 1) { foreach ($doc->records() as $record) { // first one is the same document if ($x == 0) { $x++; continue; } $objRecord = $objXml->createElement("record"); $objXml->documentElement->appendChild($objRecord); $objImport = $objXml->importNode($record->toXML()->documentElement, true); $objRecord->appendChild($objImport); $strOpenURL = $record->getOpenURL($configLinkResolver, $configSID); $objOpenURL = $objXml->createElement("url_open", Xerxes_Framework_Parser::escapeXML($strOpenURL)); $objRecord->appendChild($objOpenURL); } } $this->request->addDocument($objXml); } return 1; }
public function doExecute() { // If supplied in URL, use that (for future API use). // Nevermind, this is a privacy problem until we right access // controls for that future API use. //$username = $this->request->getProperty("username"); //if ( ! $username ) { // default to logged in user $username = $this->request->getSession("username"); //} // we can only do this if we have a real user (not temp user), otherwise // just add no XML. if ($username == null || !Xerxes_Framework_Restrict::isAuthenticatedUser($this->request)) { return 0; } $objXml = new DOMDOcument(); $objData = new Xerxes_DataMap(); $arrResults = $objData->getUserCreatedCategories($username); $x = 1; if (count($arrResults) > 0) { $objXml->loadXML("<userCategories />"); foreach ($arrResults as $objCategoryData) { $objCategory = $objXml->createElement("category"); $objCategory->setAttribute("position", $x); foreach ($objCategoryData->properties() as $key => $value) { if ($value != null) { $objElement = $objXml->createElement("{$key}", Xerxes_Framework_Parser::escapeXml($value)); $objCategory->appendChild($objElement); } } // add the url for the category $arrParams = array("base" => "collections", "action" => "subject", "username" => $username, "subject" => $objCategoryData->normalized); $url = Xerxes_Framework_Parser::escapeXml($this->request->url_for($arrParams)); $objElement = $objXml->createElement("url", $url); $objCategory->appendChild($objElement); $objXml->documentElement->appendChild($objCategory); $x++; } } $this->request->addDocument($objXml); return 1; }
public function setTagsCache($arrResults) { // we'll store the tags summary in session so that edits can be // done without round-tripping to the database; xslt can display // the summary by getting it from the request xml // make sure they are alphabetical ksort($arrResults); $this->request->setSession("tags", $arrResults); // but also add it to the request with urls $objXml = new DOMDocument(); $objXml->loadXML("<tags />"); foreach ($arrResults as $label => $total) { $objTag = $objXml->createElement("tag"); $objXml->documentElement->appendChild($objTag); $arrUrl = array("base" => "folder", "action" => "home", "username" => $this->request->getSession("username"), "label" => $label); $objTag->setAttribute("label", $label); $objTag->setAttribute("total", $total); $objTag->setAttribute("url", Xerxes_Framework_Parser::escapeXml($this->request->url_for($arrUrl))); } $this->request->addDocument($objXml); }
/** * Pulls down a compiled list of all database from Metalib and saves in database * */ private function databases() { $arrDatabases = array(); // get all databases and convert to local format $objXml = new DOMDocument(); $objXml = $this->objSearch->allDatabases($this->configInstitute, true, $this->configChunk); $strXml = Xerxes_Framework_Parser::transform($objXml, "xsl/utility/marc-to-database.xsl"); if ($this->request->getProperty("test")) { $objXml->save("metalib.xml"); file_put_contents("xerxes.xml", $strXml); } $strXml = Xerxes_Framework_Parser::transform($objXml, "xsl/utility/marc-to-database.xsl"); // get just the database info $objSimple = new SimpleXMLElement($strXml); $arrDBs = $objSimple->xpath("//database"); if (count($arrDBs) < 1) { throw new Exception("Could not find any databases in the Metalib KB. " . $this->objSearch->getWarnings(true)); } foreach ($arrDBs as $objDatabase) { // populate data object with properties $objData = new Xerxes_Data_Database(); $objData->metalib_id = (string) $objDatabase->metalib_id; $objData->title_display = (string) $objDatabase->title_display; $objData->type = (string) $objDatabase->type; $objData->data = $objDatabase->asXML(); $arrDatabases[$objData->metalib_id] = $objData; } return $arrDatabases; }
public function doExecute() { $objSearch = $this->getSearchObject(); // metalib search object $bolRedirect = false; // final determination to redirect on merge $objStatus = new DOMDocument(); // search status $objMerge = new DOMDocument(); // merge information $iProgress = null; // number of times metalib status polled // params from the request $id = $this->request->getProperty("group"); $strGroup = $this->getGroupNumber(); $strMergeRedirect = $this->request->getProperty("mergeRedirect"); // configuration options $configShowMergedResults = $this->registry->getConfig("IMMEDIATELY_SHOW_MERGED_RESULTS", false, true); $configApplication = $this->registry->getConfig("APPLICATION_SID", false, "calstate.edu:xerxes"); $configFacets = $this->registry->getConfig("FACETS", false, false); $configRecordsPerPage = $this->registry->getConfig("RECORDS_PER_PAGE", false, 10); $iRefreshSeconds = $this->registry->getConfig("SEARCH_PROGRESS_CAP", false, 35); $configHitsCap = (string) $iRefreshSeconds / 5; $configSortPrimary = $this->registry->getConfig("SORT_ORDER_PRIMARY", false, "rank"); $configSortSecondary = $this->registry->getConfig("SORT_ORDER_SECONDARY", false, "year"); // access control $objSearchXml = $this->getCache($id, "search", "DOMDocument"); Xerxes_Helper::checkDbListSearchableByUser($objSearchXml, $this->request, $this->registry); // redirect link base $arrParams = array("base" => "metasearch", "action" => "results", "group" => $id); // determine if redirect after merge if ($configShowMergedResults == true) { $bolRedirect = true; } if ($strMergeRedirect == "false") { $bolRedirect = false; } else { if ($strMergeRedirect == "true") { $bolRedirect = true; } } // get status of the search and cache result $objStatus = $objSearch->searchStatus($strGroup); $this->setCache($id, "group", $objStatus); // cap the number of refreshes if ($this->request->getSession("refresh-{$strGroup}") != null) { // get refresh count $iProgress = (int) $this->request->getSession("refresh-{$strGroup}"); // if we hit limit, set metalib finish flag to true if ($iProgress >= (int) $configHitsCap) { $objSearch->setFinished(true); } else { $iProgress++; $this->request->setSession("refresh-{$strGroup}", $iProgress); } } else { $this->request->setSession("refresh-{$strGroup}", 1); } // if done see if there are results and merge and redirect, // otherwise this will fall thru and continue with auto refreshing if ($objSearch->getFinished() == true) { $this->request->setSession("refresh-{$strGroup}", 10); // check to see if there are any documents to merge, and then merge // and create facets $iGroupTotal = 0; // total number of hits in the group $arrDatabaseHits = array(); // total number of databases with hits $objSimpleXml = simplexml_import_dom($objStatus->documentElement); $bolSearchLinkHit = false; $strSearchLinkSet = ""; foreach ($objSimpleXml->xpath("//base_info") as $objBase) { if ((string) $objBase->no_of_documents == "888888888") { $bolSearchLinkHit = true; $strSearchLinkSet = (string) $objBase->set_number; } elseif ((int) $objBase->no_of_documents > 0) { // we'll only count the databases with hits $iGroupTotal += (int) $objBase->no_of_documents; array_push($arrDatabaseHits, (string) $objBase->set_number); } } // only got a search-and-link database if ($iGroupTotal == 0 && $bolSearchLinkHit == true) { $arrParams["resultSet"] = $strSearchLinkSet; $this->request->setRedirect($this->request->url_for($arrParams)); return 1; } // got hits if ($iGroupTotal > 0) { // we'll only issue the merge command if there is more than one database // with hits, otherwise there's no point if (count($arrDatabaseHits) == 1) { $strSetNumber = $arrDatabaseHits[0]; // redirect to results page $arrParams["resultSet"] = $strSetNumber; $this->cache->save(); $this->request->setRedirect($this->request->url_for($arrParams)); return 1; } else { $strMergeSet = ""; // merge set identifier $iMergeCount = 0; // count of documents in the merge set // merge the top results $objMerge = $objSearch->merge($strGroup, $configSortPrimary, $configSortSecondary); // get the newly updated status that resulted from that merge // operation and cache $objStatus = $objSearch->searchStatus($strGroup); $this->setCache($id, "group", $objStatus); $objXPath = new DOMXPath($objMerge); // extract new merge set number and total hits for merge set if ($objXPath->query("//new_set_number")->item(0) != null) { $strMergeSet = $objXPath->query("//new_set_number")->item(0)->nodeValue; } if ($objXPath->query("//no_of_documents")->item(0) != null) { $iMergeCount = (int) $objXPath->query("//no_of_documents")->item(0)->nodeValue; } if ($strMergeSet == "") { //throw new Exception( "Result from Metalib returned no set number" ); } // cache the facets response, but only if there are more results than a single page // and facets have been turned on if ($iMergeCount > $configRecordsPerPage && $configFacets == true) { $objFacetXml = $objSearch->facets($strMergeSet, "all", $configApplication); $this->setCache($id, "facets", $objFacetXml); // cache a slimmed down version of the facets as well // to ease the load on the interface $strFacetSlim = Xerxes_Framework_Parser::transform($objFacetXml, "xsl/utility/facets-slim.xsl"); $this->setCache($id, "facets_slim", $strFacetSlim); } } // redirect to results page with merge set if ($bolRedirect == true) { // catch no hits if ($iMergeCount == 0) { // check to see if any of the individual dbs had a search-and-link with // a 'results found' indicator $bolIndividual = false; $strIndividualSet = ""; foreach ($objStatus->getElementsByTagName("base_info") as $objDb) { foreach ($objDb->getElementsByTagName("no_of_documents") as $objDocs) { if ((int) $objDocs->nodeValue > 0) { $bolIndividual = true; if ($objDb->getElementsByTagName("set_number")->item(0) != null) { $strIndividualSet = $objDb->getElementsByTagName("set_number")->item(0)->nodeValue; break 2; } } } } if ($bolIndividual == true) { // redirect to individual results page $arrParams["resultSet"] = $strIndividualSet; $this->cache->save(); $this->request->setRedirect($this->request->url_for($arrParams)); return 1; } } else { // redirect to merged results page $arrParams["resultSet"] = $strMergeSet; $this->cache->save(); $this->request->setRedirect($this->request->url_for($arrParams)); return 1; } } } } // build the response from previous cached data $objXml = new DOMDocument(); $objXml = $this->documentElement(); $objXml = $this->addSearchInfo($objXml, $id); $objXml = $this->addStatus($objXml, $id); $objXml = $this->addProgress($objXml, $this->request->getSession("refresh-{$strGroup}")); $this->request->addDocument($objXml); $this->saveCache(); return 1; }
public static function execute() { // calculate current file, this directory $this_directory = dirname(__FILE__); // calculate root directory of the app ../../ from here $path_to_parent = $this_directory; $path_to_parent = str_replace("\\", "/", $path_to_parent); $arrPath = explode("/", $path_to_parent); array_pop($arrPath); array_pop($arrPath); $path_to_parent = implode("/", $arrPath); // here so other framework files can reference it self::$parent_directory = $path_to_parent; // register framework any main xerxes class files self::registerClasses("{$path_to_parent}/lib/framework", "Xerxes_Framework"); // initialize the configuration setting (Registry), // command-view mapping (ControllerMap), and // language translation (Languages) objects $objRegistry = Xerxes_Framework_Registry::getInstance(); $objRegistry->init(); $objControllerMap = Xerxes_Framework_ControllerMap::getInstance(); $objControllerMap->init(); // set the version number, for interface or other places $objRegistry->setConfig("XERXES_VERSION", $objControllerMap->getVersion(), true); // dynamically set the web path, if config says so, // doesn't work on all webserver/php set-ups, so an // explicit web path from config is preferred if ($objRegistry->getConfig("base_web_path", false) == '{dynamic}') { if (isset($_SERVER)) { $script_name = $_SERVER['SCRIPT_NAME']; $script_name = str_replace("/index.php", "", $script_name); $objRegistry->setConfig("base_web_path", $script_name); } } // give our session a name to keep sessions distinct between multiple // instances of xerxes on one server. use base_path (preferably) or // application_name config directives. $path_base = $objRegistry->getConfig("base_web_path", false); $path_key = preg_replace('/\\W/', '_', $path_base); $session_name = "xerxessession_" . $path_key; if ($path_base == "") { $path_base = "/"; } $session_path = $objRegistry->getConfig("session_path", false, $path_base); $session_domain = $objRegistry->getConfig("session_domain", false, null); session_name($session_name); session_set_cookie_params(0, $session_path, $session_domain); session_start(); // processes the incoming request $objRequest = Xerxes_Framework_Request::getInstance(); $objRequest->init(); // utility classes // assists with basic paging/navigation elements for the view $objPage = new Xerxes_Framework_Page($objRequest, $objRegistry); // functions for special logging or handling of errors $objError = new Xerxes_Framework_Error(); // language names $objLanguage = Xerxes_Framework_Languages::getInstance(); $objLanguage->init(); // we'll put the remaining code in a try-catch block in order to show friendly error page // for any uncaught exceptions try { #################### # DISPLAY ERRORS # #################### if ($objRegistry->getConfig("DISPLAY_ERRORS") == true) { error_reporting(E_ALL); ini_set('display_errors', '1'); } #################### # DEFAULTS # #################### // labels $objLabels = Xerxes_Framework_Labels::getInstance(); $lang = $objRequest->getProperty("lang"); $objLabels->init($lang); // make sure application_name is passthrough, and has a value. $objRegistry->setConfig("application_name", $objRegistry->getConfig("APPLICATION_NAME", false, "Xerxes", $lang), true); #################### # SET PATHS # #################### ### reverse proxy // check to see if xerxes is running behind a reverse proxy and swap // host and remote ip here with their http_x_forwarded counterparts; // but only if configured for this, since client can spoof the header // if xerxes is not, in fact, behind a reverse proxy if ($objRegistry->getConfig("REVERSE_PROXY", false, false) == true) { $forward_host = $objRequest->getServer('HTTP_X_FORWARDED_HOST'); $forward_address = $objRequest->getServer('HTTP_X_FORWARDED_FOR'); if ($forward_host != "") { $objRequest->setServer('SERVER_NAME', $forward_host); } // last ip address is the user's if ($forward_address != "") { $arrIP = explode(",", $forward_address); $objRequest->setServer('REMOTE_ADDR', trim(array_pop($arrIP))); } } // the working directory is the instance, so any relative paths will // be executed in relation to the root directory of the instance $working_dir = getcwd(); $working_dir = str_replace("\\", "/", $working_dir); // full web path // // NOTE :if you change this code make sure you make a corresponding // change in lib/framework/Error.php, since there is redundant code // there in case something goes horribly wrong and we need to set the // web path for proper display of a (friendly) error page $base_path = $objRegistry->getConfig('BASE_WEB_PATH', false, ""); $this_server_name = $objRequest->getServer('SERVER_NAME'); // check for a non-standard port $port = $objRequest->getServer('SERVER_PORT'); if ($port == 80 || $port == 443) { $port = ""; } else { $port = ":" . $port; } $protocol = "http://"; if ($objRequest->getServer("HTTPS")) { $protocol = "https://"; } $web = $protocol . $this_server_name . $port; // register these values $objRegistry->setConfig("SERVER_URL", $web); $objRegistry->setConfig("PATH_PARENT_DIRECTORY", $path_to_parent); $objRegistry->setConfig("APP_DIRECTORY", $working_dir); $objRegistry->setConfig("BASE_URL", $web . $base_path, true); #################### # INSTRUCTIONS # #################### // ControllerMap contains instructions for commands and views // based on the url parameters 'base' and 'action' $strBase = $objRequest->getProperty("base"); $strAction = $objRequest->getProperty("action"); $objControllerMap->setAction($strBase, $strAction, $objRequest); #################### # ACCESS CONTROL # #################### // if this part of the application is restricted to a local ip range, or requires a named login, then the // Restrict class will check the user's ip address or if they have logged in; failure stops the flow // and redirects user to a login page with the current request passed as 'return' paramater in the url $objRestrict = new Xerxes_Framework_Restrict($objRequest); // command line scripts will ignore access rules if ($objRequest->isCommandLine() != true) { if ($objControllerMap->isRestricted() == true) { if ($objControllerMap->requiresLogin() == true) { // resource requires a valid named username $objRestrict->checkLogin(); } else { // resource is resricted, but local ip range is okay $objRestrict->checkIP(); } } else { // go ahead and register local users, but don't prompt for login $objRestrict->checkIP(false); } } // if this action is set to only be run via the command line, in order to prevent // web execution of potentially long-running tasks, then restrict it here if (!$objRequest->isCommandLine() && $objControllerMap->restrictToCLI()) { throw new Exception("cannot run command from web"); } #################### # INCLUDES # #################### // files and directories that have been set to be included by the config file foreach ($objControllerMap->getIncludes() as $path_to_include) { self::registerClasses($path_to_parent . "/{$path_to_include}"); } #################### # DATA # #################### // set-up the data by defining the root element $strDocumentElement = $objControllerMap->getDocumentElement(); $objRequest->setDocumentElement($strDocumentElement); // pass config values that should be made available to the XSLT $objRequest->addDocument($objRegistry->publicXML()); // the data will be built-up by calling one or more command classes // which will fetch their data based on other parameters supplied in // the request; returning that data as xml to a master xml dom document // inside the Xerxes_Framework_Request class, or in some cases specififying // a url to redirect the user out $commands = $objControllerMap->getCommands(); foreach ($commands as $arrCommand) { $strDirectory = $arrCommand[0]; // directory where the command class is located $strNamespace = $arrCommand[1]; // prefix namespace of the command class $strClassFile = $arrCommand[2]; // suffix name of the command class // directory where commands live $command_path = "{$path_to_parent}/commands/{$strDirectory}"; // allow for a local override, even $local_command_path = "commands/{$strDirectory}"; // echo "<h3>$strClassFile</h3>"; // first, include any parent class, assuming that the parent class will // follow the naming convention of having the same name as the directory $strParentClass = Xerxes_Framework_Parser::strtoupper(substr($strDirectory, 0, 1)) . substr($strDirectory, 1); if (file_exists("{$local_command_path}/{$strParentClass}.php")) { require_once "{$local_command_path}/{$strParentClass}.php"; } elseif (file_exists("{$command_path}/{$strParentClass}.php")) { require_once "{$command_path}/{$strParentClass}.php"; } // if the specified command class exists in the distro or local commands folder, then // instantiate an object and execute it $strClass = $strNamespace . "_Command_" . $strClassFile; $local_command = file_exists("{$local_command_path}/{$strClassFile}.php"); if (file_exists("{$command_path}/{$strClassFile}.php") || $local_command) { // if the instance has a local version, take it! if ($local_command) { require_once "{$local_command_path}/{$strClassFile}.php"; } else { require_once "{$command_path}/{$strClassFile}.php"; } // instantiate the command class and execute it, but only // if it extends xerxes_framework_command $objCommand = new $strClass(); if ($objCommand instanceof Xerxes_Framework_Command) { $objCommand->execute($objRequest, $objRegistry); } else { throw new Exception("command classes must be instance of Xerxes_Framework_Command"); } } else { // if no command but a view was specified, then go ahead and show the view // minus any data, since the view is doin' its own thang if (!file_exists($objControllerMap->getView())) { throw new Exception("invalid command {$strClass}"); } } } #################### # COOKIES # #################### // any cookies specified in the reuqest object? if so, set em now. $cookieSetParams = $objRequest->cookieSetParams(); foreach ($cookieSetParams as $cookieParams) { set_cookie($cookieParams[0], $cookieParams[1], $cookieParams[2], $cookieParams[3], $cookieParams[4], $cookieParams[5]); } #################### # REDIRECT # #################### // if the result of the command is a redirect, we will stop the // flow and redirect the user out, unless overridden by the noRedirect // directive if ($objRequest->getRedirect() != null) { if ($objRequest->getProperty("noRedirect") == null) { header("Location: " . $objRequest->getRedirect()); exit; } else { // include in the resposne what the redirect would have been $objRequest->setProperty("redirect", $objRequest->getRedirect()); } } #################### # VIEW # #################### // SET THE HTTP HEADER // // we'll set the content-type, and potentially other header elements, based on the paramater 'format'; // format must correspond to one of the pre-defined format content-types in setHeader() or can be a user- // defined format set in action.xml $format = $objRequest->getProperty("format"); if ($objControllerMap->getFormat($format) != null) { header($objControllerMap->getFormat($format)); } else { self::setHeader($format); } // get the xml from the request object, but exclude any server information // from being included if format=source $bolShowServer = true; if ($format == "xerxes") { $bolShowServer = false; } $objXml = new DOMDocument(); $objXml = $objRequest->toXML($bolShowServer); // RAW XML DISPLAY // // you can append 'format=xerxes' to the querystring to have this controller spit back // the response in plain xml, which can be useful in some cases, like maybe AJAX? if ($format == "xerxes") { echo $objXml->saveXML(); } else { // VIEW CODE // // ControllerMap contains instructions on what file to include for the view; typically // this will be an xslt file, but could be a php file if the xslt does not // provide enough flexibility; php page will inherit the xml dom document and // can go from there if ($objControllerMap->getView() == "") { // No view specified, no view will be executed. return; } // PHP CODE if ($objControllerMap->getViewType() != "xsl" && $objControllerMap->getViewType() != null) { $file = $objControllerMap->getView(); $distro_file = $objRegistry->getConfig("PATH_PARENT_DIRECTORY", true) . "/lib/{$file}"; if (file_exists($file)) { require_once $file; } elseif (file_exists($distro_file)) { require_once $distro_file; } else { throw new Exception("Could not find non-xsl view specified to include: {$file}"); } } else { // XSLT CODE $output = $objPage->transform($objXml, $objControllerMap->getView(), null); // EMBEDED JAVASCRIPT DISPLAY // // you can append 'format=embed_html_js' to the querystring to output // the content as a javascript source document with everything wrapped in // document.write() statements if ($format == "embed_html_js") { // first escape any single quotes $output = str_replace("'", "\\'", $output); // now break the html into lines and output with document.write('') $lines = explode("\n", $output); $new_lines = array("// Javascript output. "); foreach ($lines as $line) { array_push($new_lines, "document.write('" . $line . "');"); } $output = implode("\n", $new_lines); } echo $output; } //remove the flash message, intended for one display only. $objRequest->setSession("flash_message", null); } } catch (Exception $e) { $objError->handle($e, $objRequest, $objRegistry); } }
public function doExecute() { $start = microtime(true); $arrFields = array(); // fields to return in response $iMaximumRecords = 10; // maximum number of records to return $iTotalHits = 0; // total number of hits in response $arrResults = array(); // holds results returned // metalib search object $objSearch = $this->getSearchObject(); // parameters from request $id = $this->request->getProperty("group"); $strGroup = $this->getGroupNumber(); $strResultSet = $this->request->getProperty("resultSet"); $iStartRecord = (int) $this->request->getProperty("startRecord"); // access control $objSearchXml = $this->getCache($id, "search", "DOMDocument"); Xerxes_Helper::checkDbListSearchableByUser($objSearchXml, $this->request, $this->registry); // marc fields to return from metalib; we specify these here in order to keep // the response size as small (and thus as fast) as possible $strMarcFields = self::MARC_FIELDS_BRIEF; // $strMarcFields = "#####, OPURL"; // configuration options $configRecordPerPage = $this->registry->getConfig("RECORDS_PER_PAGE", false, self::DEFAULT_RECORDS_PER_PAGE); $configMarcFields = $this->registry->getConfig("MARC_FIELDS_BRIEF", false); $configIncludeMarcRecord = $this->registry->getConfig("XERXES_BRIEF_INCLUDE_MARC", false, false); $configFacets = $this->registry->getConfig("FACETS", false, false); // add additional marc fields specified in the config file if ($configMarcFields != null) { $configMarcFields .= ", " . $strMarcFields; } else { $configMarcFields = $strMarcFields; } // empty querystring values will return as 0, so fix here in case if ($iStartRecord == 0) { $iStartRecord = 1; } $iMaximumRecords = (int) $configRecordPerPage; // extract total hits from this result set $objXml = $this->getCache($id, "group", "SimpleXML"); foreach ($objXml->xpath("//base_info") as $base_info) { if ($base_info->set_number == $strResultSet) { $strTotalHits = $base_info->no_of_documents; if ($strTotalHits == "888888888") { $iTotalHits = 1; } else { $iTotalHits = (int) $strTotalHits; } } } // set marc fields to return in response $arrFields = explode(",", $configMarcFields); // get results from metalib $objResultsXml = $objSearch->retrieve($strResultSet, $iStartRecord, $iMaximumRecords, $iTotalHits, "customize", $arrFields); // build the response, including previous cached data $objXml = new DOMDocument(); $objXml = $this->documentElement(); $objXml = $this->addSearchInfo($objXml, $id); $objXml = $this->addStatus($objXml, $id, $strResultSet, $iTotalHits); $objXml = $this->addProgress($objXml, $this->request->getSession("refresh-{$strGroup}")); // if this is a search-and-link resource add the original xml that contains the link if ($objResultsXml->getElementsByTagName("search_and_link")->item(0) != null) { $objImport = $objXml->importNode($objResultsXml->documentElement, true); $objXml->documentElement->appendChild($objImport); // this is a http post submission, so we need to see if we have added the post // data to the alternate record link in the IRD, since X-Server bug prevents this // from coming through in the response $objSearchType = $objResultsXml->getElementsByTagName("search_and_link_type")->item(0); if ($objSearchType != null) { if ($objSearchType->nodeValue == "POST") { $objSearchXml = $this->getCache($id, "search", "SimpleXML"); $objGroupXml = $this->getCache($id, "group", "SimpleXML"); $databases_id = $objGroupXml->xpath("//base_info[set_number = '{$strResultSet}']/base_001"); if (count($databases_id) != 1) { throw new Exception("cannot find search-and-link database in group cache"); } $metalib_id = (string) $databases_id[0]; $databases = $objSearchXml->xpath("//database[@metalib_id='{$metalib_id}']"); if (count($databases) != 1) { throw new Exception("cannot find database '{$metalib_id}' in search cache"); } $database = $databases[0]; // the form action $post = (string) $database->link_search_post; // the data to be posted $data = (string) $database->link_native_record_alternative; if ($post == "" || $data == "") { throw new Exception("cannot create http post elements for search-and-link database"); } // xml close to what we need in html, just to make this easy $objPostXML = $objXml->createElement("post"); $objXml->documentElement->appendChild($objPostXML); $objForm = $objXml->createElement("form"); $objForm->setAttribute("action", Xerxes_Framework_Parser::escapeXml($post)); $objPostXML->appendChild($objForm); foreach (explode("&", $data) as $pair) { $arrKeys = explode("=", $pair); $key = $arrKeys[0]; $value = $arrKeys[1]; // metalib docs say only TERM1 is used in the 'URL mask', if ($value == "TERM1") { $value = (string) $objSearchXml->pair[0]->query; } $objInput = $objXml->createElement("input"); $objInput->setAttribute("name", $key); $objInput->setAttribute("value", $value); $objForm->appendChild($objInput); } } } } else { // add the records themselves foreach ($objResultsXml->getElementsByTagName("record") as $objRecord) { array_push($arrResults, $objRecord); } // this will also convert the marc-xml to xerxes_record, and check for an already // saved record $objXml = $this->addRecords($objXml, $arrResults, $configIncludeMarcRecord); } $objXml = $this->addFacets($objXml, $id, $configFacets); $this->request->addDocument($objXml); // echo time(true) - $start . "<br>"; return 1; }
protected function linkOther($result, $results_xml, $record_container) { // author links $arrAuthorsReverse = $result->getAuthors(false, true, true); $arrAuthorsForward = $result->getAuthors(false, true); for ($a = 0; $a < count($arrAuthorsReverse); $a++) { $strAuthorReverse = $arrAuthorsReverse[$a]; $strAuthorForward = $arrAuthorsForward[$a]; $arrLink = array("base" => $this->request->getProperty("base"), "action" => "search", "source" => $this->request->getProperty("source"), "query" => Xerxes_Framework_Parser::escapeXML($strAuthorReverse), "field" => "au", "spell" => "none"); $author_url = $this->request->url_for($arrLink); $objAuthorLink = $results_xml->createElement("author_link", Xerxes_Framework_Parser::escapeXML($strAuthorForward)); $objAuthorLink->setAttribute("link", $author_url); $record_container->appendChild($objAuthorLink); } // lateral subject links foreach ($result->getSubjects() as $subject) { $arrLink = array("base" => $this->request->getProperty("base"), "action" => "search", "source" => $this->request->getProperty("source"), "query" => Xerxes_Framework_Parser::escapeXML($subject->value), "field" => "su", "spell" => "none"); $subject_url = $this->request->url_for($arrLink); $objSubjectLink = $results_xml->createElement("subject_link", Xerxes_Framework_Parser::escapeXML($subject->display)); $objSubjectLink->setAttribute("link", $subject_url); $record_container->appendChild($objSubjectLink); } }
/** * Do something with uncaught errors */ public static function handle($e, Xerxes_Framework_Request $objRequest, Xerxes_Framework_Registry $objRegistry) { if ($objRegistry->getConfig("DISPLAY_ERRORS", false, false)) { throw $e; } // flag certain exception types for special handling in the xslt $strErrorType = get_class($e); // might be a sub-class, reset so view will catch. if ($e instanceof PDOException) { $strErrorType = "PDOException"; } // if this is the command line, just rethrow the error so we can see it; might // make this a little better formatted in the future if ($objRequest->isCommandLine()) { throw $e; } else { // translate heading and message $labels = Xerxes_Framework_Labels::getInstance(); if ($e instanceof Xerxes_Exception) { $heading = $e->heading(); } else { $heading = "text_error"; } $heading = $labels->getLabel($heading); $message = $labels->getLabel($e->getMessage()); // first output to apache error log error_log("Xerxes error: " . $message . ": " . $e->getTraceAsString()); //set proper http response code $resultStatus = 500; if ($e instanceof Xerxes_Exception_AccessDenied) { $resultStatus = 403; } else { if ($e instanceof Xerxes_Exception_NotFound) { $resultStatus = 404; } } header(' ', true, $resultStatus); // send back http status as internal server error or other specified status // for the web, we'll convert the error message to xml along with the type // of exception and hand display off to the error.xsl file $objError = new DOMDocument(); $objError->loadXML("<error />"); $objMessage = $objError->createElement("message", $message); $objMessage->setAttribute("type", $strErrorType); $objError->documentElement->appendChild($objMessage); $objHeading = $objError->createElement("heading", $heading); $objError->documentElement->appendChild($objHeading); // make sure we're showing the main error file $objRegistry->setConfig("XSL_PARENT_DIRECTORY", null); // set the base url for the error.xsl file's benefit; don't want to assume that // the earlier code to this effect was executed before an exception, so this is redundant $base_path = $objRegistry->getConfig('BASE_WEB_PATH', false, ""); $this_server_name = $objRequest->getServer('SERVER_NAME'); // check for a non-standard port $port = $objRequest->getServer('SERVER_PORT'); if ($port == 80 || $port == 443) { $port = ""; } else { $port = ":" . $port; } $protocol = "http://"; if ($objRequest->getServer("HTTPS")) { $protocol = "https://"; } $web = $protocol . $this_server_name . $port . $base_path; $objBaseURL = $objError->createElement("base_url", $web); $objError->documentElement->appendChild($objBaseURL); // if it's a db denied exception, include info on dbs. if ($e instanceof Xerxes_Exception_DatabasesDenied) { $excluded_xml = $objError->createElement("excluded_dbs"); $objError->documentElement->appendChild($excluded_xml); foreach ($e->deniedDatabases() as $db) { $element = Xerxes_Helper::databaseToNodeset($db, $objRequest, $objRegistry); $element = $objError->importNode($element, true); $excluded_xml->appendChild($element); } } // add in the request object's stuff $request_xml = $objRequest->toXML(); $imported = $objError->importNode($request_xml->documentElement, true); foreach ($imported->childNodes as $childNode) { $objError->documentElement->appendChild($childNode); } if ($objRequest->getProperty("format") == "xerxes") { header('Content-type: text/xml'); echo $objError->saveXML(); } else { // display it to the user. Transform will pick up local // xsl for error page too, great. echo Xerxes_Framework_Parser::transform($objError, "xsl/error.xsl"); } } // need to incorporate methods for doing additional actions based on the type // of error -- probably a config option }
public function toXML() { $xml = new DOMDocument(); $xml->loadXML("<item />"); foreach ($this as $key => $value) { if ($value == "") { continue; } $key = preg_replace('/\\W|\\s/', '', $key); $element = $xml->createElement($key, Xerxes_Framework_Parser::escapeXml($value)); $xml->documentElement->appendChild($element); } return $xml; }
public function publicXML() { // pass any configuration options defined as type=pass to the xml $objConfigXml = new DOMDocument(); $objConfigXml->loadXML("<config />"); foreach ($this->getPass() as $key => $value) { if ($value instanceof SimpleXMLElement) { // just spit it back out again as XML $objElement = $objConfigXml->createElement($key); $objConfigXml->documentElement->appendChild($objElement); foreach ($value->children() as $child) { // need to convert to DOMDocument. $domValue = dom_import_simplexml($child); $domValue = $objConfigXml->importNode($domValue, true); $objElement->appendChild($domValue); } } else { // simple string value $objElement = $objConfigXml->createElement($key, Xerxes_Framework_Parser::escapeXml($value)); $objConfigXml->documentElement->appendChild($objElement); } } return $objConfigXml; }
/** * Get localized language name of provided ISO 639 code * * @param string $type the standard according to which the code will be interpreted; * one of: iso_639_1_code, iso_639_2B_code * @param string $code the 2-letter language code * @param string $override_locale use this locale instead of Xerxes locale * @return mixed A string with the localized language name or NULL if the code is not valid */ public function getNameFromCode($type, $code, $override_locale = null) { if ($type != 'name') { $code = Xerxes_Framework_Parser::strtolower($code); } $elements = $this->xpath->query("//iso_639_entry[@{$type}='{$code}']"); if (!is_null($elements)) { foreach ($elements as $element) { $name = $element->getAttribute('name'); if ($this->gettext == false) { return $name; } $originalLocale = $this->getXerxesLocale(); if ($override_locale == null) { $this->setXerxesLocale($this->locale); } else { $this->setXerxesLocale($override_locale); } $languageName = dgettext($this->domain, $name); $this->setXerxesLocale($originalLocale); return $languageName; } } else { return null; } }
public function doExecute() { $strUsername = $this->request->getSession("username"); $iRecord = $this->request->getProperty("record"); $strTags = $this->request->getProperty("tags"); // updated tags $strShadowTags = $this->request->getProperty("tagsShaddow"); // original tags // split tags out on comma $arrShadow = explode(",", $strShadowTags); $arrTags = explode(",", $strTags); for ($x = 0; $x < count($arrTags); $x++) { $arrTags[$x] = Xerxes_Framework_Parser::strtolower(trim($arrTags[$x])); } for ($x = 0; $x < count($arrShadow); $x++) { $arrShadow[$x] = Xerxes_Framework_Parser::strtolower(trim($arrShadow[$x])); } // remove any duplicates $arrTags = array_unique($arrTags); // update the database $objData = new Xerxes_DataMap(); $objData->assignTags($strUsername, $arrTags, $iRecord); // now update the cached version without recalculating all the // totals with a round-trip to the database $arrStored = $this->request->getSession("tags"); // see which tags are new and which are actually being deleted or changed $arrDelete = array_diff($arrShadow, $arrTags); $arrAdded = array_diff($arrTags, $arrShadow); // deletes! foreach ($arrDelete as $strTag) { foreach ($arrStored as $strStoredKey => $iStoredValue) { if (Xerxes_Framework_Parser::strtoupper($strTag) == Xerxes_Framework_Parser::strtoupper($strStoredKey)) { $iStoredValue = (int) $iStoredValue; if ($iStoredValue > 1) { // just deincrement it $iStoredValue--; $arrStored[$strStoredKey] = $iStoredValue; } else { // this was the only entry for the tag so remove it unset($arrStored[$strStoredKey]); } } } } // adds! foreach ($arrAdded as $strTag) { if ($strTag != "") { $bolExists = false; foreach ($arrStored as $strStoredKey => $iStoredValue) { if (Xerxes_Framework_Parser::strtoupper($strTag) == Xerxes_Framework_Parser::strtoupper($strStoredKey)) { // there is one in here already so increment $iStoredValue = (int) $iStoredValue; $iStoredValue++; $arrStored[$strStoredKey] = $iStoredValue; $bolExists = true; } } // if it wasn't in there already, add it as the first if ($bolExists == false) { $arrStored[$strTag] = 1; } } } // now store it back in session $this->setTagsCache($arrStored); return 1; }
public function checkSpelling() { $registry = Xerxes_Framework_Registry::getInstance(); $strAltYahoo = $registry->getConfig("ALTERNATE_YAHOO_LOCATION", false); $configYahooID = $registry->getConfig("YAHOO_ID", false, "calstate"); $spell_return = array(); // we'll return this one for ($x = 0; $x < count($this->query_list); $x++) { $term = $this->query_list[$x]; $url = ""; if ($strAltYahoo != "") { $url = $strAltYahoo; } else { $url = "http://api.search.yahoo.com/WebSearchService/V1/spellingSuggestion"; } $url .= "?appid=" . $configYahooID . "&query=" . urlencode($term->phrase); $strResponse = Xerxes_Framework_Parser::request($url); $objSpelling = new DOMDocument(); $objSpelling->loadXML($strResponse); if ($objSpelling->getElementsByTagName("Result")->item(0) != null) { $term->spell_correct = $objSpelling->getElementsByTagName("Result")->item(0)->nodeValue; $spell_return[$term->id] = $term->spell_correct; } // also put it here so we can return it $this->query_list[$x] = $term; } return $spell_return; }
/** * Simple XSLT transformation function * * @param mixed $xml DOMDocument or string containing xml * @param string $strXslt physical path to xslt document * @param array $arrParams [optional] array of parameters to pass to stylesheet * @param array $arrIncludes [optional] additional stylesheets that should be included in the transform * @return string newly formatted document */ public function transform($xml, $strXslt, $arrParams = null, $arrIncludes = array()) { $html = Xerxes_Framework_Parser::transform($xml, $strXslt, $arrParams, false, $arrIncludes); // as of metalib 4.3 we _still_ need to do this to catch html entity references that // have been escaped for xml compatibility $noEscape = $this->registry->getConfig("FIX_AMERSANDS", false, true); // but make sure we don't do it on an XML output, like the open search option $format = $this->request->getProperty("format"); if ($format == "xml") { $noEscape = false; } if ($noEscape === true) { $html = str_replace("&", "&", $html); } return $html; }
public function doExecute() { $objXml = new DOMDOcument(); $objXml->loadXML("<category />"); $strSubject = $this->request->getProperty("subject"); $strUser = $this->request->getProperty("username"); $objData = new Xerxes_DataMap(); $objCategoryData = null; // only fetch if we actually have params, avoid the fetch-everything phenomena if ($strSubject && $strUser) { $objCategoryData = $objData->getSubject($strSubject, null, Xerxes_DataMap::userCreatedMode, $strUser); } // if there hasn't if (!$objCategoryData) { if ($this->request->getRedirect()) { // nevermind, we're in the creation process, already redirected, // just end now. return 1; } else { throw new Xerxes_Exception_NotFound("text_collections_error_personal_collection_not_found"); } } // make sure they have access if (!$objCategoryData->published) { Xerxes_Helper::ensureSpecifiedUser($objCategoryData->owned_by_user, $this->request, $this->registry, "text_collections_error_private_collection"); } $y = 1; if ($objCategoryData != null) { $objXml->documentElement->setAttribute("name", $objCategoryData->name); $objXml->documentElement->setAttribute("normalized", $objCategoryData->normalized); $objXml->documentElement->setAttribute("owned_by_user", $objCategoryData->owned_by_user); $objXml->documentElement->setAttribute("published", $objCategoryData->published); // we treat the 'default' collection (usually 'My Saved Records') special // giving it less flexibility for simplicity, in the XSL/javascript. if ($this->isDefaultCollection($objCategoryData)) { $objXml->documentElement->setAttribute("is_default_collection", "yes"); } // standard url for the category $arrParams = array("base" => "collections", "action" => "subject", "username" => $strUser, "subject" => $objCategoryData->normalized); $url = Xerxes_Framework_Parser::escapeXml($this->request->url_for($arrParams)); $objElement = $objXml->createElement("url", $url); $objXml->documentElement->appendChild($objElement); //edit url for the user-created category $arrParams = array("base" => "collections", "action" => "edit_form", "username" => $strUser, "subject" => $objCategoryData->normalized); $url = Xerxes_Framework_Parser::escapeXml($this->request->url_for($arrParams)); $objElement = $objXml->createElement("edit_url", $url); $objXml->documentElement->appendChild($objElement); // the attributes of the subcategories $db_list_index = 1; foreach ($objCategoryData->subcategories as $objSubData) { $objSubCategory = $objXml->createElement("subcategory"); $objSubCategory->setAttribute("name", $objSubData->name); $objSubCategory->setAttribute("position", $y); $objSubCategory->setAttribute("id", $objSubData->id); $y++; // the database information foreach ($objSubData->databases as $objDatabaseData) { $objDatabase = Xerxes_Helper::databaseToNodeset($objDatabaseData, $this->request, $this->registry, $db_list_index); $objDatabase = $objXml->importNode($objDatabase, true); $objSubCategory->appendChild($objDatabase); } $objXml->documentElement->appendChild($objSubCategory); } } $this->request->addDocument($objXml); return 1; }
public static function toSentenceCase($strInput) { if (strlen($strInput) > 1) { // drop everything $strInput = Xerxes_Framework_Parser::strtolower($strInput); // capitalize the first letter $strInput = Xerxes_Framework_Parser::strtoupper(substr($strInput, 0, 1)) . substr($strInput, 1); // and the start of a subtitle $strInput = self::capitalizeSubtitle($strInput); } return $strInput; }
private function formatting($data, $node) { $style = ""; // stylistic rendering // stylistic elements foreach ($node->attributes as $attribute) { if ($attribute->getName() == "font-family" || $attribute->getName() == "font-style" || $attribute->getName() == "font-variant" || $attribute->getName() == "font-weight" || $attribute->getName() == "text-decoration" || $attribute->getName() == "vertical-align" || $attribute->getName() == "display") { $style .= " " . $attribute->getName() . ": " . (string) $attribute; } } // capitalization if ($node["text-case"]) { switch ((string) $node["text-case"]) { case "lowercase": $data = Xerxes_Framework_Parser::strtolower($data); break; case "uppercase": $data = Xerxes_Framework_Parser::strtoupper($data); break; case "capitalize-first": case "sentence": $data = Xerxes_Framework_Parser::strtoupper(substr($data, 0, 1)) . substr($data, 1); break; case "capitalize-all": //TODO: add this to parser? break; case "title": //TODO: make reference to parser? break; } } // stylistic rendering if ($style != "") { $data = "<span style=\"{$style}\">{$data}</span>"; } // add quotes if ($node["quotes"]) { $data = "\"" . $data . "\""; } return $node["prefix"] . $data . $node["suffix"]; }
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; }
/** * Add global array as xml to request xml document * * @param DOMDocument $objXml [by reference] request xml document * @param DOMNode $objAppend [by reference] node to append values to * @param array $arrValues global array */ private function addElement(&$objXml, &$objAppend, $arrValues) { foreach ($arrValues as $key => $value) { // need to make sure the xml element has a valid name // and not something crazy with spaces or commas, etc. $strSafeKey = Xerxes_Framework_Parser::strtolower(preg_replace('/\\W/', '_', $key)); if (is_array($value)) { foreach ($value as $strKey => $strValue) { $objElement = $objXml->createElement($strSafeKey); $objElement->setAttribute("key", $strKey); $objAppend->appendChild($objElement); if (is_array($strValue)) { // multi-dimensional arrays will be recursively added $this->addElement($objXml, $objElement, $strValue); } else { $objElement->nodeValue = Xerxes_Framework_Parser::escapeXml($strValue); } } } else { $objElement = $objXml->createElement($strSafeKey, Xerxes_Framework_Parser::escapeXml($value)); $objAppend->appendChild($objElement); } } }
/** * Fetches and normalize the API data * * @param string $url url of patron dump or pint test * @return array patron data */ private function getContent($url) { $arrRawData = array(); $arrData = array(); // get the data and strip out html tags $strResponse = Xerxes_Framework_Parser::request($url); $strResponse = trim(strip_tags($strResponse)); if ($strResponse == "") { throw new Exception("Could not connect to Innovative Patron API"); } else { // cycle thru each line in the response, splitting each // on the equal sign into an associative array $arrRawData = explode("\n", $strResponse); foreach ($arrRawData as $strLine) { $arrLine = explode("=", $strLine); // strip out the code, leaving just the attribute name $arrLine[0] = preg_replace("/\\[[^\\]]{1,}\\]/", "", $arrLine[0]); $arrData[trim($arrLine[0])] = trim($arrLine[1]); } } return $arrData; }
public function doExecute() { $configMemory = $this->registry->getConfig("HARVEST_MEMORY_LIMIT", false, "500M"); ini_set("memory_limit", $configMemory); echo "\n\nSFX INSTITUTIONAL HOLDINGS POPULATION \n\n"; // You can define the export file on sfx as having an instance extension, so // give the client the opportunity to define that here $strInstance = $this->request->getProperty("instance"); if ($strInstance != "") { $strInstance = "-" . $strInstance; } // construct the address to Google Scholar institutional // holdings file on SFX. Either SFX specific config, or // general link resolver config. $configSfx = $this->registry->getConfig("ALTERNATE_FULLTEXT_HARVEST_ADDRESS", false, $this->registry->getConfig("LINK_RESOLVER_ADDRESS", false)); if (!$configSfx) { throw new Exception("Can not run populate action, no link resolver address configured. " . "Need config ALTERNATE_FULLTEXT_HARVEST_ADDRESS or LINK_RESOLVER_ADDRESS."); } // fire-up a transaction with the database $objData = new Xerxes_DataMap(); $objData->beginTransaction(); // clear old data echo " Flushing SFX fulltext table . . . "; $objData->clearFullText(); echo "done.\n"; // try to get the data from sfx $done = false; $x = 0; while ($done == false) { $x++; $strUrl = $configSfx . "/cgi/public/get_file.cgi?file=institutional_holding" . $strInstance . '-.prt' . str_pad($x, 2, '0', STR_PAD_LEFT) . ".xml"; echo " Pulling down SFX inst holding file ({$x}) . . . "; try { $strResponse = Xerxes_Framework_Parser::request($strUrl); $objXml = new SimpleXMLElement($strResponse); } catch (Exception $e) { if ($x == 1) { throw new Exception("cannot get institutional holding file from sfx: '{$strUrl}'. " . "If this is the correct SFX server address, make sure your SFX allows access to " . "institutional holding file from this IP address in config/get_file_restriction.config " . "on SFX server."); } $done = true; } echo "done.\n"; if (!$done) { echo " Processing file . . . "; $objItems = $objXml->xpath("//item[@type != 'other']"); if ($objItems == false) { throw new Exception("could not find items in inst holding file."); } echo "done.\n"; echo " Adding to database . . . "; foreach ($objItems as $objItem) { foreach ($objItem->coverage as $objCoverage) { $objFullText = new Xerxes_Data_Fulltext(); $objFullText->issn = (string) $objItem->issn; $objFullText->issn = str_replace("-", "", $objFullText->issn); $objFullText->title = (string) $objItem->title; $objFullText->title = urlencode($objFullText->title); $objFullText->title = substr(Xerxes_Framework_Parser::strtolower($objFullText->title), 0, 100); $objFullText->startdate = (int) $objCoverage->from->year; $objFullText->enddate = (int) $objCoverage->to->year; if ($objFullText->enddate == 0) { $objFullText->enddate = 9999; } $objFullText->embargo = (int) $objCoverage->embargo->days_not_available; $objFullText->updated = date("YmdHis"); // add it to the database $objData->addFulltext($objFullText); } } echo "done.\n"; } } echo " Commiting changes . . . "; $objData->commit(); echo "done.\n"; return 1; }
public function execute(Xerxes_Framework_Request $objRequest, Xerxes_Framework_Registry $objRegistry) { // if the authentication_source is set in the request, then it takes precedence $override = $objRequest->getProperty("authentication_source"); if ($override == null) { // otherwise, see if one has been set in session from a previous login $session_auth = $objRequest->getSession("auth"); if ($session_auth != "") { $override = $session_auth; } } // make sure it's in our list, or if blank still, we get the default $configAuth = $objRegistry->getAuthenticationSource($override); // now make it! switch ($configAuth) { case "ldap": $this->authentication = new Xerxes_LDAP($objRequest, $objRegistry); break; case "innovative": $iii_file = "config/authentication/innovative.php"; if (file_exists($iii_file)) { require_once $iii_file; $this->authentication = new Xerxes_InnovativePatron_Local($objRequest, $objRegistry); } else { $this->authentication = new Xerxes_InnovativePatron($objRequest, $objRegistry); } break; case "cas": $this->authentication = new Xerxes_CAS($objRequest, $objRegistry); break; case "guest": $this->authentication = new Xerxes_GuestAuthentication($objRequest, $objRegistry); break; case "demo": $this->authentication = new Xerxes_DemoAuthentication($objRequest, $objRegistry); break; case "pds": $this->authentication = new Xerxes_PDS($objRequest, $objRegistry); break; case "shibboleth": $shib_file = "config/authentication/shibboleth.php"; if (file_exists($shib_file)) { require_once $shib_file; $this->authentication = new Xerxes_Shibboleth_Local($objRequest, $objRegistry); } else { $this->authentication = new Xerxes_Shibboleth($objRequest, $objRegistry); } break; case "custom": require_once "config/authentication/custom.php"; $this->authentication = new Xerxes_CustomAuth($objRequest, $objRegistry); break; default: // check to see if a file exists with an authentication class that extends the framework, // if so, then use it; this supports multiple custom schemes $local_file = "config/authentication/{$configAuth}.php"; $class_name = "Xerxes_CustomAuth_" . Xerxes_Framework_Parser::strtoupper(substr($configAuth, 0, 1)) . substr($configAuth, 1); if (file_exists($local_file)) { require_once $local_file; if (!class_exists($class_name)) { throw new Exception("the custom authentication scheme '{$configAuth}' should have a class called '{$class_name}'"); } $this->authentication = new $class_name($objRequest, $objRegistry); if (!$this->authentication instanceof Xerxes_Framework_Authenticate) { throw new Exception("class '{$class_name}' for the '{$configAuth}' authentication scheme must extend Xerxes_Framework_Authenticate"); } } else { throw new Exception("unsupported authentication type"); } } // we set this so we can keep track of the authentication type // through various requests $this->authentication->id = $configAuth; parent::execute($objRequest, $objRegistry); }