public function __construct($connection = null, $username = null, $password = null) { $objRegistry = Xerxes_Framework_Registry::getInstance(); // make it a member variable so other functions can get it easier $this->registry = $objRegistry; // set primary language $languages = $this->registry->getConfig("languages"); if ($languages != "") { $this->primary_language = (string) $languages->language["code"]; } // searchable fields $this->searchable_fields = explode(",", $this->registry->getConfig("DATABASE_SEARCHABLE_FIELDS", false, "title_display,title_full,description,keyword,title_alternate")); // pdo can't tell us which rdbms we're using exactly, especially for // ms sql server, since we'll be using odbc driver, so we make this // explicit in the config $this->rdbms = $this->registry->getConfig("RDBMS", false, "mysql"); // take conn and credentials from config, unless overriden in constructor if ($connection == null) { $connection = $objRegistry->getConfig("DATABASE_CONNECTION", true); } if ($username == null) { $username = $objRegistry->getConfig("DATABASE_USERNAME", true); } if ($password == null) { $password = $objRegistry->getConfig("DATABASE_PASSWORD", true); } $this->init($connection, $username, $password); }
/** * Constructor * * @param $objRequest request object */ public function __construct(Xerxes_Framework_Request $objRequest) { $objRegistry = Xerxes_Framework_Registry::getInstance(); $this->request = $objRequest; $configAuthPage = $this->request->url_for(array("base" => "authenticate", "action" => "login")); $this->ip_range = $objRegistry->getConfig("LOCAL_IP_RANGE", false, null); // if the return url has a querystring mark in it, then append // return url to other params, otherwise it is sole param if (strstr($configAuthPage, "?")) { $this->strReturn = "{$configAuthPage}&return="; } else { $this->strReturn = "{$configAuthPage}?return="; } }
/** * Initialize the object by picking up and processing the ISO 639 xml file * * @exception will throw exception if no file can be found */ public function init() { // first, see if Getttext functions are installed if (function_exists('bindtextdomain')) { $this->gettext = true; } // set full path to local copy $this->languages_file_xerxes = realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR . $this->languages_file_xerxes); $this->gettext_domain_xerxes = realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR . $this->gettext_domain_xerxes); // if the iso-codes is not installed, use our copy $file = ""; if (file_exists($this->languages_file_system)) { $file = $this->languages_file_system; } elseif (file_exists($this->languages_file_xerxes)) { $file = $this->languages_file_xerxes; } else { throw new Exception("could not find file with the ISO 639 language list"); } // load the languages file $xml = new DOMDocument(); $xml->load($file); $this->xpath = new DOMXPath($xml); unset($xml); // which language shall we display? $objRegistry = Xerxes_Framework_Registry::getInstance(); $objRequest = Xerxes_Framework_Request::getInstance(); $lang = $objRequest->getProperty("lang"); if ($lang == null) { $lang = $objRegistry->defaultLanguage(); } $this->locale = $objRegistry->getLocale($lang); // bindings if ($this->gettext == true) { $gettext_domain_path = ""; if (file_exists($this->gettext_domain_xerxes)) { $gettext_domain_path = $this->gettext_domain_xerxes; } elseif (file_exists($this->gettext_domain_system)) { $gettext_domain_path = $this->gettext_domain_system; } bindtextdomain($this->domain, $gettext_domain_path); // this works on windows too? bind_textdomain_codeset($this->domain, 'UTF-8'); // assume UTF-8, all the .po files in iso_639 use it textdomain($this->domain); } }
public function map() { $leader = $this->leader(); ## source database $sid = $this->datafield("SID"); $this->metalib_id = $sid->subfield("d")->__toString(); $this->record_number = $sid->subfield("j")->__toString(); $this->result_set = $sid->subfield("s")->__toString(); $this->database_name = $sid->subfield("t")->__toString(); $this->source = $sid->subfield("b")->__toString(); ## metalib weirdness // puts leader in control field $strLeaderMetalib = $this->controlfield("LDR")->__toString(); if ($strLeaderMetalib != "") { $leader->value = $strLeaderMetalib; } $demunge = array("1XX", "6XX"); // character entity references de-munging code -- thanks a lot metalib! foreach ($demunge as $field) { $got_one = true; do { $authors = $this->datafield($field); $got_one = false; // whether we found any in the list for ($x = 0; $x < $authors->length(); $x++) { $this_datafield = $authors->item($x); $this_value = $this_datafield->subfield()->__toString(); // we found an un-terminated char entity ref $matches = array(); if (preg_match('/\\&\\#\\d{3}$/', $this_value, $matches)) { $got_one = true; $new_value = ""; // grab the value out of the next field $x++; // hopefully we aren't at the end? if ($x < $authors->length()) { // nope, so grab the next field's value $next_datafield = $authors->item($x); $next_value = $next_datafield->subfield()->__toString(); // add back in the terminating semi-colon $new_value = "{$this_value};{$next_value}"; // blank it so we don't re-process it $next_datafield->tag = "XXX"; } else { // yup, just add a terminating char to the value $new_value = $this_value . ";"; } // now create a new datafield composed of both old and new values $fixed_datafield = new Xerxes_Marc_DataField(); $fixed_datafield->tag = $this_datafield->tag; // we'll just assume this is |a $fixed_subfield = new Xerxes_Marc_Subfield(); $fixed_subfield->code = "a"; $fixed_subfield->value = $new_value; $fixed_datafield->addSubField($fixed_subfield); // add it to the main record $this->addDataField($fixed_datafield); // now blank the old ones $this_datafield->tag = "XXX"; } else { // we need to shift this to the end to keep field order in tact // (critical for authors) so the above code works right $new_field = clone $this_datafield; $this->addDataField($new_field); $this_datafield->tag = "XXX"; } } // if we found one, cycle back again to see if our now-combined // field(s) *also* have un-terminated references since there may have // been more than one broken char reference for a single author, e.g. } while ($got_one == true); } // z3950/sutrs and some screen-scrapers have multiple authors in repeating 100 fields; // invalid marc, so switch all but first to 700 $authors = $this->datafield("100"); if ($authors->length() > 1) { for ($x = 1; $x < $authors->length(); $x++) { $author = $authors->item($x); $author->tag = "700"; } } // there are often multiple 773's, just combine them into one so we don't // have to iterate over all of them in other code $obj773 = new Xerxes_Marc_DataField(); $obj773->tag = "773"; foreach ($this->datafield("773") as $linked_entry) { // add all of its subfields to the new one foreach ($linked_entry->subfield() as $linked_entry_subfield) { $obj773->addSubField($linked_entry_subfield); } // now blank this one to take it out of the mix $linked_entry->tag = "XXX"; } // add our new one to the document $this->addDataField($obj773); ## ebsco format if (strstr($this->source, "EBSCO")) { // leader appears to be hard-wired; useless $leader->value = ""; // format array_push($this->format_array, $this->datafield("656")->subfield("a")->__toString()); array_push($this->format_array, $this->datafield("514")->subfield("a")->__toString()); $strEbscoType = $this->datafield("072")->subfield("a")->__toString(); if (strstr($this->source, "EBSCO_PSY") || strstr($this->source, "EBSCO_PDH")) { $strEbscoType = ""; } array_push($this->format_array, $strEbscoType); // ebsco book chapter $strEbscoBookTitle = $this->datafield("771")->subfield("a")->__toString(); if ($strEbscoBookTitle != "") { array_push($this->format_array, "Book Chapter"); } } // gale puts issn in 773b if (strstr($this->source, 'GALE')) { $strGaleIssn = $this->datafield("773")->subfield("b")->__toString(); if ($strGaleIssn != null) { array_push($this->issns, $strGaleIssn); } } // eric doc number $this->eric_number = $this->datafield("ERI")->subfield("a")->__toString(); ## full-text // some databases have full-text but no 856 // will capture these here and add to links array // pychcritiques -- no indicator of full-text either, assume all to be (9/5/07) // no unique metalib config either, using psycinfo, so make determination based on name. yikes! if (stristr($this->database_name, "psycCRITIQUES")) { array_push($this->links, array("Full-Text in HTML", array("001" => $this->controlfield("001")->__toString()), "html")); } // factiva -- no indicator of full-text either, assume all to be (9/5/07) if (stristr($this->source, "FACTIVA")) { array_push($this->links, array("Full-Text Available", array("035_a" => $this->datafield("035")->subfield("a")->__toString()), "online")); } // eric -- document is recent enough to likely contain full-text; // 340000 being a rough approximation of the document number after which they // started digitizing // EBSCO provides an indication of Full text available in 037 (jdwyn 01/12/2012) if (strstr($this->source, "ERIC") && strlen($this->eric_number) > 3) { $strEricType = substr($this->eric_number, 0, 2); $strEricNumber = (int) substr($this->eric_number, 2); $strEricAvailabilityNote = $this->datafield("037")->subfield("a")->__toString(); if ($strEricType == "ED") { if ($strEricNumber >= 340000 || stristr($this->source, "EBSCO_ERIC") && $strEricAvailabilityNote != "Not available from ERIC" && $strEricAvailabilityNote != "Available on microfiche only") { $strFullTextPdf = "http://www.eric.ed.gov/ERICWebPortal/contentdelivery/servlet/ERICServlet?accno=" . $this->eric_number; array_push($this->links, array("Full-text at ERIC.gov", $strFullTextPdf, "pdf")); } } } // 7 Apr 09, jrochkind. Gale Biography Resource Center // No 856 is included at all, but a full text link can be // constructed from the 001 record id. if (stristr($this->source, "GALE_ZBRC")) { $url = "http://ic.galegroup.com/ic/bic1/ReferenceDetailsPage/ReferenceDetailsWindow?displayGroupName=K12-Reference&action=e&windowstate=normal&mode=view&documentId=GALE|" . $this->controlfield("001")->__toString(); array_push($this->links, array("Full-Text in HTML", $url, "html")); } // special handling of 856 $notes = $this->fieldArray("500", "a"); // needed for gale foreach ($this->datafield("856") as $link) { $strDisplay = $link->subfield("z")->__toString(); $strUrl = $link->subfield("u")->__toString(); // bad links // records that have 856s, but are not always for full-text; in that case, specify them // here as original records, and remove 856 so parent code doesn't process them as full-text links // // springer (metapress): does not distinguish between things in your subscription or not (9/16/08) // cinahl (bzh): not only is 856 bad, but link missing http:// bah! thanks greg at upacific! (9/10/08) // wilson: 901|t shows an indication of full-text (9/16/10) // cabi: just point back to site (10/30/07) // google scholar: just point back to site (3/26/07) // amazon: just point back to site (3/20/08) // abc-clio: just point back to site (7/30/07) // engineering village (evii): has unreliable full-text links in a consortium environment (4/1/08) // wiley interscience: wiley does not limit full-text links only to your subscription (4/29/08) // oxford: only include the links that are free, otherwise just a link to abstract (5/7/08) // gale: only has full-text if 'text available' note in 500 field (9/7/07) BUT: Not true of Gale virtual reference library (GALE_GVRL). 10/14/08 jrochkind. // ieee xplore: does not distinguish between things in your subscription or not (2/13/09) // elsevier links are not based on subscription (6/2/10) // harvard business: these links in business source premiere are not part of your subscription (5/26/10) // proquest (umi): these links are not full-text (thanks jerry @ uni) (5/26/10) // proquest (gateway): there doesn't appear to be a general rule to this, so only doing it for fiaf (5/26/10) // primo central: no actual links here if (stristr($this->source, "METAPRESS_XML") || stristr($this->source, "EBSCO_RZH") || stristr($this->source, "WILSON_") && $this->datafield("901")->subfield("t")->__toString() == "" || stristr($this->source, "CABI") || stristr($this->source, "SCOPUS4") || stristr($this->source, "GOOGLE_SCH") || stristr($this->source, "AMAZON") || stristr($this->source, "ABCCLIO") || stristr($this->source, "EVII") || stristr($this->source, "WILEY_IS") || stristr($this->source, "OXFORD_JOU") && !strstr($strUrl, "content/full/") || strstr($this->source, "GALE") && !strstr($this->source, "GALE_GVRL") && !in_array("Text available", $notes) || stristr($this->source, "IEEE_XPLORE") || stristr($this->source, "ELSEVIER_SCOPUS") || stristr($this->source, "ELSEVIER_SCIRUS") || stristr($this->source, "EBSCO") && $strUrl != "" && !strstr($strUrl, "epnet") || strstr($strUrl, "proquest.umi.com") && strstr($strUrl, "Fmt=2") || strstr($strUrl, "gateway.proquest.com") && strstr($strUrl, "xri:fiaf:article") || stristr($this->source, "NEWPC")) { // take it out so the parent class doesn't treat it as full-text $link->tag = "XXX"; array_push($this->links, array($strDisplay, $strUrl, "original_record")); } elseif (stristr($this->source, "EBSCO")) { $strEbscoFullText = $link->subfield("i")->__toString(); $ebsco_fulltext_type = ""; // html // there is (a) an indicator from ebsco that the record has full-text, or // (b) an abberant 856 link that doesn't work, but the construct link will work, // so we take that as something of a full-text indicator if (strstr($strEbscoFullText, "T") || strstr($strDisplay, "View Full Text")) { $ebsco_fulltext_type = "html"; } elseif (strstr($link->subfield("az")->__toString(), "PDF")) { $ebsco_fulltext_type = "pdf"; } if ($ebsco_fulltext_type != "") { $str001 = $this->controlfield("001")->__toString(); $str016 = $this->datafield("016")->subfield("a")->__toString(); // see if the id number is 'dirty' $bolAlpha001 = preg_match('/^\\W/', $str001); // if so, and there is a 016, use that instead, if not go ahead and use // the 001; if neither do nothing if ($bolAlpha001 == true && $str016 != "") { array_push($this->links, array($strDisplay, array("016" => $str016), $ebsco_fulltext_type)); } elseif ($bolAlpha001 == false) { array_push($this->links, array($strDisplay, array("001" => $str001), $ebsco_fulltext_type)); } $link->tag = "XXX"; array_push($this->links, array($strDisplay, $strUrl, "original_record")); } } } // Gale title clean-up, because for some reason unknown to man they put weird // notes and junk at the end of the title. so remove them here and add them to notes. if (strstr($this->source, 'GALE_')) { $arrMatches = array(); $strGaleRegExp = '/\\(([^)]*)\\)/'; $title = $this->datafield("245"); $title_main = $title->subfield("a"); $title_sub = $title->subfield("b"); $note_field = new Xerxes_Marc_DataField(); $note_field->tag = "500"; if ($title_main != null) { if (preg_match_all($strGaleRegExp, $title_main->value, $arrMatches) != 0) { $title_main->value = preg_replace($strGaleRegExp, "", $title_main->value); } foreach ($arrMatches[1] as $strMatch) { $subfield = new Xerxes_Marc_Subfield(); $subfield->code = "a"; $subfield->value = "From title: " . $strMatch; $note_field->addSubField($subfield); } } // sub title is only these wacky notes if ($title_sub != null) { $subfield = new Xerxes_Marc_Subfield(); $subfield->code = "a"; $subfield->value = "From title: " . $title_sub->value; $note_field->addSubField($subfield); $title_sub->value = ""; } if ($note_field->subfield("a")->length() > 0) { $this->addDataField($note_field); } } // psycinfo and related databases if (strstr($this->source, "EBSCO_PDH") || strstr($this->source, "EBSCO_PSYH") || strstr($this->source, "EBSCO_LOH")) { // includes a 502 that is not a thesis note -- bonkers! // need to make this a basic note, otherwise xerxes will assume this is a thesis foreach ($this->datafield("502") as $thesis) { $thesis->tag = "500"; } } ######## PARENT MAPPING ########### parent::map(); ################################### // metalib's own year, issue, volume fields $year = $this->datafield("YR ")->subfield("a")->__toString(); if ($year != "") { $this->year = $year; } if ($this->issue == null) { $this->issue = $this->datafield("ISS")->subfield("a")->__toString(); } if ($this->volume == null) { $this->volume = $this->datafield("VOL")->subfield("a")->__toString(); } // book chapters if ($this->journal_title != "" && count($this->isbns) > 0 && count($this->issns) == 0) { $this->book_title = $this->journal_title; $this->journal_title = ""; $this->format = "Book Chapter"; } ## ebsco 77X weirdness if (strstr($this->source, "EBSCO")) { // pages in $p (abbreviated title) $pages = $this->datafield("773")->subfield('p')->__toString(); if ($pages != "") { $this->short_title = ""; } // book chapter $btitle = $this->datafield("771")->subfield('a')->__toString(); if ($btitle != "") { $this->book_title = $btitle; $this->format = "Book Chapter"; } } ## oclc dissertation abstracts // (HACK) 10/1/2007 this assumes that the diss abs record includes the 904, which means // there needs to be a local search config that performs an 'add new' action rather than // the 'remove' action that the parser uses by default if (strstr($this->source, "OCLC_DABS")) { $this->degree = $this->datafield("904")->subfield("j")->__toString(); $this->institution = $this->datafield("904")->subfield("h")->__toString(); $this->journal_title = $this->datafield("904")->subfield("c")->__toString(); $this->journal = $this->journal_title . " " . $this->journal; if ($this->journal_title == "MAI") { $this->format = "Thesis"; } else { $this->format = "Dissertation"; } } // random format related changes if (strstr($this->source, 'ERIC') && strstr($this->eric_number, 'ED') && !stristr($this->title, "proceeding")) { $this->format = "Report"; } elseif (strstr($this->source, 'ERIC') && !strstr($this->eric_number, 'ED')) { $this->format = "Article"; } elseif (strstr($this->source, 'OCLC_PAPERS')) { $this->format = "Conference Paper"; } elseif (strstr($this->source, 'PCF1')) { $this->format = "Conference Proceeding"; } elseif (stristr($this->source, "GOOGLE_B")) { $this->format = "Book"; } elseif (strstr($this->source, "EBSCO_LOH")) { $this->format = "Tests & Measures"; } elseif (strstr($this->source, "OXFORD_MUSIC_ONLINE")) { $this->format = "Article"; } elseif (strstr($this->source, "ESPACENET")) { $this->format = "Patent"; } elseif (strstr($this->source, "WIPO_PCT")) { $this->format = "Patent"; } elseif (strstr($this->source, "USPA")) { $this->format = "Patent"; } elseif (strstr($this->source, "DEPATIS")) { $this->format = "Patent"; } elseif (strstr($this->source, "DART")) { $this->format = "Thesis"; } elseif (strstr($this->source, "DDI")) { $this->format = "Thesis"; } elseif (strstr($this->source, "ETHOS")) { $this->format = "Thesis"; } elseif (strstr($this->source, "DIVA_EXTR")) { $this->format = "Thesis"; } elseif (strstr($this->source, "UNION_NDLTD")) { $this->format = "Thesis"; } // JSTOR book review correction: title is meaningless, but subjects // contain the title of the books, so we'll swap them to the title here if (strstr($this->source, 'JSTOR') && $this->title == "Review") { $this->title = ""; $this->sub_title = ""; foreach ($this->subjects as $subject) { $this->title .= " " . $subject->value; } $this->title = trim($this->title); $this->subjects = null; $this->format = "Book Review"; } // jstor links are all pdfs if (strstr($this->source, 'JSTOR')) { for ($x = 0; $x < count($this->links); $x++) { $link = $this->links[$x]; $link[2] = "pdf"; $this->links[$x] = $link; } } // CSA subject term clean-up, // since they put an asterick in front of each term (2009-09-30) if (strstr($this->source, 'CSA_')) { for ($x = 0; $x < count($this->subjects); $x++) { $subject_object = $this->subjects[$x]; $subject_object->value = str_replace("*", "", $subject_object->value); $this->subjects[$x] = $subject_object; } } // demote links based on config $objConfig = Xerxes_Framework_Registry::getInstance(); $configIgnoreFullText = $objConfig->getConfig("FULLTEXT_IGNORE_SOURCES", false); $configIgnoreFullText = str_replace(" ", "", $configIgnoreFullText); $arrIgnore = explode(",", $configIgnoreFullText); for ($x = 0; $x < count($this->links); $x++) { $link = $this->links[$x]; if (in_array($this->source, $arrIgnore) || in_array($this->metalib_id, $arrIgnore)) { $link[2] = "original_record"; } $this->links[$x] = $link; } }
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 static function embedNoteField($note_field) { // description we handle special for escaping setting. Note that we // handle html escpaing here in controller for description, view // should use disable-output-escaping="yes" on value-of of description. $objRegistry = Xerxes_Framework_Registry::getInstance(); $escape_behavior = $objRegistry->getConfig("db_description_html", false, "escape"); // 'escape' ; 'allow' ; or 'strip' $note_field = str_replace('##', ' ', $note_field); if ($escape_behavior == "strip") { $allow_tag_list = $objRegistry->getConfig("db_description_allow_tags", false, ''); $arr_allow_tags = explode(',', $allow_tag_list); $param_allow_tags = ''; foreach ($arr_allow_tags as $tag) { $param_allow_tags .= "<{$tag}>"; } $note_field = strip_tags($note_field, $param_allow_tags); # escape ampersand literals too. $note_field = str_replace("&", "&", $note_field); } if ($escape_behavior == "escape") { $note_field = htmlspecialchars($note_field); } return $note_field; }
/** * Retrieve master XML and all request paramaters * * @param bool $bolHideServer [optional] true will exclude the server variables from the response, default false * * @return DOMDocument */ public function toXML($bolHideServer = false) { $objRegistry = Xerxes_Framework_Registry::getInstance(); // add the url parameters and session and server global arrays // to the master xml document $objXml = new DOMDocument(); $objXml->loadXML("<request />"); // session and server global arrays will have parent elements // but querystring and cookie params will be at the root of request $this->addElement($objXml, $objXml->documentElement, $this->arrParams); // add the session global array $objSession = $objXml->createElement("session"); $objXml->documentElement->appendChild($objSession); $this->addElement($objXml, $objSession, $_SESSION); // we might add some calculated thigns to xml that aren't actually // stored in session. // okay, yeah, we already have group memberships listed from the session, // but it doesn't have all the data we need, plus we need to stick // group memberships by virtue of IP address. $objAuth = $objXml->createElement("authorization_info"); $objXml->documentElement->appendChild($objAuth); // are they an affiliated user at all, meaning either logged in or // ip recognized? $authUser = Xerxes_Framework_Restrict::isAuthenticatedUser($this); $authIP = Xerxes_Framework_Restrict::isIpAddrInRanges($this->getServer('REMOTE_ADDR'), $objRegistry->getConfig("local_ip_range")); $objElement = $objXml->createElement("affiliated", $authUser || $authIP ? "true" : "false"); $objElement->setAttribute("user_account", $authUser ? "true" : "false"); $objElement->setAttribute("ip_addr", $authIP ? "true" : "false"); $objAuth->appendChild($objElement); // now each group $arrGroups = $objRegistry->userGroups(); if ($arrGroups != null) { foreach ($objRegistry->userGroups() as $group) { $authUser = array_key_exists("user_groups", $_SESSION) && is_array($_SESSION["user_groups"]) && in_array($group, $_SESSION["user_groups"]); $authIP = Xerxes_Framework_Restrict::isIpAddrInRanges($this->getServer('REMOTE_ADDR'), $objRegistry->getGroupLocalIpRanges($group)); $objElement = $objXml->createElement("group", $authUser || $authIP ? "true" : "false"); $objElement->setAttribute("id", $group); $objElement->setAttribute("display_name", $objRegistry->getGroupDisplayName($group)); $objElement->setAttribute("user_account", $authUser ? "true" : "false"); $objElement->setAttribute("ip_addr", $authIP ? "true" : "false"); $objAuth->appendChild($objElement); } } // add the server global array, but only if the request // asks for it, for security purposes if ($bolHideServer == true) { $objServer = $objXml->createElement("server"); $objXml->documentElement->appendChild($objServer); $this->addElement($objXml, $objServer, $_SERVER); } // add to the master xml document $this->addDocument($objXml); // once added, now return the master xml document return $this->xml; }
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; }
/** * Send a request as either GET or POST * * @param string $url url you want to send the request to * @param int $timeout [optional] seconds to wait before timing out * @param string $data [optional] data to POST to the above url * @param string $content_type [optional] content-type in the post, 'application/x-www-form-urlencoded' by default * @param bool $bolEncode [optional] whether to encode the posted data, true by default * @return string the response from the server */ public static function request($url, $timeout = null, $data = null, $content_type = null, $bolEncode = true) { $objRegistry = Xerxes_Framework_Registry::getInstance(); $proxy = $objRegistry->getConfig("HTTP_PROXY_SERVER", false); $curl = $objRegistry->getConfig("HTTP_USE_CURL", false, false); ### GET REQUEST (NON-PROXY) if ($data == null && $proxy == null && $curl == null) { $ctx = null; if ($timeout != null) { $ctx = stream_context_create(array('http' => array('timeout' => $timeout))); } return file_get_contents($url, 0, $ctx); } // these for POST requests $host = ""; // just the server host name $port = 80; // just the port number $path = ""; // just the uri path if ($data != null) { if ($content_type == null) { $content_type = "application/x-www-form-urlencoded"; } // split the host from the path $arrMatches = array(); if (preg_match('/http:\\/\\/([^\\/]*)(\\/.*)/', $url, $arrMatches) != false) { $host = $arrMatches[1]; $path = $arrMatches[2]; } // extract the port number, if present if (strstr($host, ":")) { $port = (int) self::removeLeft($host, ":"); $host = self::removeRight($host, ":"); } // regular POST requests will need to have the data urlencoded, but some special // POST requests, like 'text/xml' to Solr, should not, so client code should // set to false if ($bolEncode == true) { $data = urlencode($data); } } ### POST OR GET USING AN HTTP PROXY or need to use CURL if ($proxy != null || $curl != null) { $response = ""; // the response $ch = curl_init(); // curl object // basic curl settings curl_setopt($ch, CURLOPT_URL, $url); // the url we're sending the request to curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // this returns the response to a variable curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // this tells curl to follow 'location:' headers curl_setopt($ch, CURLOPT_MAXREDIRS, 10); // but don't follow more than 10 'location:' redirects if ($timeout != null) { curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); // wait and then timeout } // this is a post request if ($data != null) { // we do it this way, as opposed to a more typical curl post, // in case this is a custom HTTP POST request $header[] = "Host: {$host}\r\n"; $header[] = "Content-type: {$content_type}\r\n"; $header[] = "Content-length: " . strlen($data) . "\r\n"; $header[] = $data; curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); } // proxy settings if ($proxy != null) { curl_setopt($ch, CURLOPT_PROXY, $proxy); // proxy username and password, if necessary $username = $objRegistry->getConfig("HTTP_PROXY_USERNAME", false); $password = $objRegistry->getConfig("HTTP_PROXY_PASSWORD", false); if ($username != null && $password != null) { curl_setopt($ch, CURLOPT_PROXYUSERPWD, "{$username}:{$password}"); } } // return the response $response = curl_exec($ch); $responseInfo = curl_getinfo($ch); curl_close($ch); if ($response === false || $responseInfo["http_code"] != 200) { throw new Exception("Error in response, " . $responseInfo["http_code"] . " " . $response); } return $response; } else { $buf = ""; // the response $fp = fsockopen($host, $port); // file pointer object if (!$fp) { throw new Exception("could not connect to server"); } fputs($fp, "POST {$path} HTTP/1.1\r\n"); fputs($fp, "Host: {$host}\r\n"); fputs($fp, "Content-type: {$content_type}\r\n"); fputs($fp, "Content-length: " . strlen($data) . "\r\n"); fputs($fp, "Connection: close\r\n\r\n"); fputs($fp, $data); while (!feof($fp)) { $buf .= fgets($fp, 128); } fclose($fp); if (!strstr($buf, "200 OK")) { throw new Exception("Error in response, {$buf}"); } return $buf; } }