public function results()
 {
     // need to authenticate for non-local library
     $source = $this->request->getProperty("source");
     if ($source != "local") {
         $objRestrict = new Xerxes_Framework_Restrict($this->request);
         $objRestrict->checkIP();
     }
     // @todo factor this out to the framework
     $this->addAdvancedSearchLink();
     parent::results();
 }
 public function doExecute()
 {
     // if supplied in url, use that (for future API use)
     $username = $this->request->getProperty("username");
     if (!$username) {
         // default to logged in user
         $username = $this->request->getSession("username");
     }
     // default names for if we have to create a new category.
     // can be sent with HTTP request, otherwise we have hard coded defaults.
     $strNewSubject = $this->registry->getConfig("default_collection_name", false, "My Saved Databases");
     $strNormalizedSubject = Xerxes_Data_Category::normalize($strNewSubject);
     // we can only do this if we have a real user (not temp user)
     if ($username == null || !Xerxes_Framework_Restrict::isAuthenticatedUser($this->request)) {
         throw new Xerxes_Exception_AccessDenied("text_collections_error_not_logged_in");
     }
     $objData = new Xerxes_DataMap();
     //$arrResults = $objData->getUserCreatedCategories($username, "id");
     $arrResults = $objData->getUserCreatedCategories($username);
     // find the default one, if present.
     $redirectCategory = null;
     for ($i = 0; $i < count($arrResults); $i++) {
         $iCat = $arrResults[$i];
         if ($iCat->normalized == $strNormalizedSubject) {
             $redirectCategory = $iCat;
             break;
         }
     }
     // Couldn't find it? Have to make one.
     if (empty($redirectCategory)) {
         //Create one
         $redirectCategory = $this->addDefaultCollection($objData, $username);
     }
     /*  This doesn't work right yet, although it's a nice idea. 
         else {
           // Okay, let's make sure our default category has at least one
           // section, which it always ought to, but data corruption sometimes,
           // and we can fix it up. Got to refetch it to get it's subcategories.
           
           $redirectCategory = $objData->getSubject( $redirectCategory->normalized, null, Xerxes_DataMap::userCreatedMode, $redirectCategory->username);
           
           if ( count($redirectCategory->subcategories) == 0) {
             // add the default one 
             $this->addDefaultSubcategory($objData, $redirectCategory);
           }
         }*/
     // and redirect
     $url = $this->request->url_for(array('base' => 'collections', 'action' => 'subject', 'username' => $username, 'subject' => $redirectCategory->normalized));
     $this->request->setRedirect($url);
     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 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);
     }
 }
Beispiel #5
0
 /**
  * Determines if the database is searchable by user
  *
  * @param Xerxes_Data_Database $db
  * @param Xerxes_Framework_Request $objRequest	Xerxes request object
  * @param Xerxes_Framework_Registry $objRegistry Xerxes registry object
  * @return unknown
  */
 public static function dbSearchableForUser(Xerxes_Data_Database $db, $objRequest, $objRegistry)
 {
     $allowed = "";
     if ($db->searchable != 1) {
         //nobody can search it!
         $allowed = false;
     } elseif ($db->guest_access != "") {
         //anyone can search it!
         $allowed = true;
     } elseif (count($db->group_restrictions) > 0) {
         // they have to be authenticated, and in a group that is included
         // in the restrictions, or in an ip address associated with a
         // restricted group.
         $allowed = Xerxes_Framework_Restrict::isAuthenticatedUser($objRequest) && array_intersect($_SESSION["user_groups"], $db->group_restrictions);
         if (!$allowed) {
             // not by virtue of a login, but now check for ip address
             $ranges = array();
             foreach ($db->get("group_restrictions") as $group) {
                 $ranges[] = $objRegistry->getGroupLocalIpRanges($group);
             }
             $allowed = Xerxes_Framework_Restrict::isIpAddrInRanges($objRequest->getServer('REMOTE_ADDR'), implode(",", $ranges));
         }
     } else {
         // ordinary generally restricted resource.  they need to be
         // an authenticated user, or in the local ip range.
         if (Xerxes_Framework_Restrict::isAuthenticatedUser($objRequest) || Xerxes_Framework_Restrict::isIpAddrInRanges($objRequest->getServer('REMOTE_ADDR'), $objRegistry->getConfig("LOCAL_IP_RANGE"))) {
             $allowed = true;
         }
     }
     return $allowed;
 }
Beispiel #6
0
 /**
  * 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;
 }
Beispiel #7
0
 public function doExecute()
 {
     $objXml = new DOMDocument();
     $objXml->loadXML("<navbar />");
     ### saved records link
     $arrLink = array("base" => "folder");
     // make sure there is no return if coming from login to prevent a spider
     // from thinking this is a different page
     if ($this->request->getProperty("base") != "authenticate") {
         $arrLink["return"] = $this->request->getServer("REQUEST_URI");
     }
     $savedRecordsLink = $this->addNavbarElement($objXml, "saved_records", $arrLink);
     // add numSavedRecords  and sessionSavedRecords for proper icon display
     $objData = new Xerxes_DataMap();
     $num = $objData->totalRecords($this->request->getSession("username"));
     $savedRecordsLink->setAttribute("numSavedRecords", (string) $num);
     $savedRecordsLink->setAttribute("numSessionSavedRecords", Xerxes_Helper::numMarkedSaved());
     ### my collections (i.e., databases)
     $arrCollectionUrl = array("base" => "collections", "action" => "list");
     if (Xerxes_Framework_Restrict::isAuthenticatedUser($this->request)) {
         $arrCollectionUrl["username"] = $this->request->getSession("username");
     }
     $this->addNavbarElement($objXml, "saved_collections", $arrCollectionUrl);
     ### authentication
     // tell it to force an https url if so configured.
     $force_secure_login = false;
     if ($this->registry->getConfig("secure_login", false) == "true") {
         $force_secure_login = true;
     }
     // login
     $this->addNavbarElement($objXml, "login", array("base" => "authenticate", "action" => "login", "return" => $this->request->getServer("REQUEST_URI")), $force_secure_login);
     // logout
     $this->addNavbarElement($objXml, "logout", array("base" => "authenticate", "action" => "logout", "return" => $this->request->getServer("REQUEST_URI")));
     ### db alphabetical list
     $this->addNavbarElement($objXml, "database_list", array("base" => "databases", "action" => "alphabetical"));
     ### languages
     $languages = $this->registry->getConfig("LANGUAGES", false);
     if ($languages != null) {
         // map locales to language codes
         foreach ($languages as $language) {
             $order = NULL;
             $code = NULL;
             foreach ($language->attributes() as $name => $val) {
                 if ($name == "code") {
                     $code = (string) $val;
                 }
                 if ($name == "locale") {
                     $locale = (string) $val;
                     if ($locale == '') {
                         $locale = 'C';
                     }
                 }
             }
             $locales[$code] = $locale;
         }
         $languages_xml = $objXml->createElement("languages");
         $objXml->documentElement->appendChild($languages_xml);
         $language_names = Xerxes_Framework_Languages::getInstance();
         foreach ($languages->language as $language) {
             $code = (string) $language["code"];
             $readable_name = $language_names->getNameFromCode("iso_639_2B_code", $code, $locales[$code]);
             $native_name = $language_names->getNameFromCode("iso_639_2B_code", $code);
             $language_node = $objXml->createElement("language");
             $languages_xml->appendChild($language_node);
             $language_node->setAttribute("code", $code);
             $language_node->setAttribute("name", $readable_name);
             $language_node->setAttribute("native_name", $native_name);
             $language_node->setAttribute("locale", $locales[$code]);
             // link back to home page
             $current_params = $this->request->getURIProperties();
             // this page
             // this is necessary on the home page
             if (!array_key_exists("base", $current_params)) {
                 $current_params["base"] = "";
             }
             // subject pages can't support a swap, so send user back to home page
             if (($current_params["base"] == "databases" || $current_params["base"] == "embed") && array_key_exists("subject", $current_params)) {
                 $current_params = array();
                 $current_params["base"] = "";
             }
             // add the languages
             $current_params["lang"] = $code;
             // with language set
             $url = $this->request->url_for($current_params);
             $language_node->setAttribute("url", $url);
         }
     }
     $this->request->addDocument($objXml);
     return 1;
 }