示例#1
0
 public function getGroupDisplayName($id)
 {
     $id = Xerxes_Framework_Parser::strtoupper($id);
     //case insensitive
     if (array_key_exists($id, $this->usergroups)) {
         $group = $this->usergroups[$id];
         return (string) $group->display_name;
     } else {
         return $id;
     }
 }
示例#2
0
 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);
     }
 }
示例#3
0
 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"];
 }
示例#4
0
 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);
 }
示例#5
0
 /**
  * Extract a value from the master xml
  *
  * @param string $xpath				[optional] xpath expression to the element(s)
  * @param array $arrNamespaces		[optional] key / value pair of url / namespace reference for the xpath
  * @param string $strReturnType		[optional] return query results as 'DOMNODELIST' or 'ARRAY', otherwise as 'sting'
  * @return mixed					if no paramaters set, returns entire xml as DOMDocument
  * 									otherwise returns a string, unless value supplied in return type
  */
 public function getData($xpath = null, $arrNamespaces = null, $strReturnType = null)
 {
     if ($xpath == null && $arrNamespaces == null && $strReturnType == null) {
         return $this->xml;
     }
     $strReturnType = Xerxes_Framework_Parser::strtoupper($strReturnType);
     if ($strReturnType != null && $strReturnType != "DOMNODELIST" && $strReturnType != "ARRAY") {
         throw new Exception("unsupported return type");
     }
     $objXPath = new DOMXPath($this->xml);
     if ($arrNamespaces != null) {
         foreach ($arrNamespaces as $prefix => $identifier) {
             $objXPath->registerNamespace($prefix, $identifier);
         }
     }
     $objNodes = $objXPath->query($xpath);
     if ($objNodes == null) {
         // no value found
         return null;
     } elseif ($strReturnType == "DOMNODELIST") {
         // return nodelist
         return $objNodes;
     } elseif ($strReturnType == "ARRAY") {
         // return nodelist as array, for convenience
         $arrReturn = array();
         foreach ($objNodes as $objNode) {
             array_push($arrReturn, $objNode->nodeValue);
         }
         return $arrReturn;
     } else {
         // just grab the value, if you know it is the
         // only one or first one in the query
         if ($objNodes->item(0) != null) {
             return $objNodes->item(0)->nodeValue;
         } else {
             return null;
         }
     }
 }
示例#6
0
 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;
 }
示例#7
0
 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;
 }
示例#8
0
 /**
  * Converts the query to AND all terms, while preserving boolean operators
  * and quoted phrases; return as array
  *
  * @param string $strQuery		original query
  * @return array				query normalized
  */
 public function normalizeArray($strQuery, $toLower = true)
 {
     $bolQuote = false;
     // flags the start and end of a quoted phrase
     $arrWords = array();
     // the query broken into a word array
     $arrFinal = array();
     // final array of words
     $strQuote = "";
     // quoted phrase
     $arrSmall = array();
     // normalize it
     if ($toLower == true) {
         $strQuery = Xerxes_Framework_Parser::strtolower($strQuery);
     }
     while (strstr($strQuery, "  ")) {
         $strQuery = str_replace("  ", " ", $strQuery);
     }
     // split words into an array
     $arrWords = explode(" ", $strQuery);
     // cycle thru each word in the query
     for ($x = 0; $x < count($arrWords); $x++) {
         if ($bolQuote == true) {
             // we are inside of a quoted phrase
             $strQuote .= " " . $arrWords[$x];
             if (strpos($arrWords[$x], "\"") !== false) {
                 // the end of a quoted phrase
                 $bolQuote = false;
                 if ($x + 1 < count($arrWords)) {
                     if ($arrWords[$x + 1] != "and" && $arrWords[$x + 1] != "or" && $arrWords[$x + 1] != "not") {
                         // the next word is not a boolean operator,
                         // so AND the current one
                         array_push($arrFinal, $strQuote);
                         array_push($arrFinal, "AND");
                     } else {
                         array_push($arrFinal, $strQuote);
                     }
                 } else {
                     array_push($arrFinal, $strQuote);
                 }
                 $strQuote = "";
             }
         } elseif ($bolQuote == false && strpos($arrWords[$x], "\"") !== false) {
             // this is the start of a quoted phrase
             $strQuote .= " " . $arrWords[$x];
             $bolQuote = true;
         } elseif ($arrWords[$x] == "and" || $arrWords[$x] == "or" || $arrWords[$x] == "not") {
             // the current word is a boolean operator
             array_push($arrFinal, Xerxes_Framework_Parser::strtoupper($arrWords[$x]));
         } else {
             $arrSmallWords = array('of', 'a', 'the', 'and', 'an', 'or', 'nor', 'but', 'is', 'if', 'then', 'else', 'when', 'at', 'from', 'by', 'on', 'off', 'for', 'in', 'out', 'over', 'to', 'into', 'with', 'as');
             if (in_array($arrWords[$x], $arrSmallWords)) {
                 array_push($arrSmall, $arrWords[$x]);
             }
             if ($x + 1 < count($arrWords)) {
                 if ($arrWords[$x + 1] != "and" && $arrWords[$x + 1] != "or" && $arrWords[$x + 1] != "not") {
                     // the next word is not a boolean operator,
                     // so AND the current one
                     array_push($arrFinal, $arrWords[$x]);
                     array_push($arrFinal, "AND");
                 } else {
                     array_push($arrFinal, $arrWords[$x]);
                 }
             } else {
                 array_push($arrFinal, $arrWords[$x]);
             }
         }
     }
     // single quoted phrase
     if (count($arrFinal) == 0 && $strQuote != "") {
         array_push($arrFinal, $strQuote);
     }
     // small terms
     if (count($arrSmall) > 0) {
         array_push($this->arrTips, array(self::SMALL_WORDS => "'" . implode("', '", $arrSmall) . "'"));
     }
     return $arrFinal;
 }