Sindbad~EG File Manager

Current Path : /var/www/web3/modules/core/classes/
Upload File :
Current File : /var/www/web3/modules/core/classes/GalleryUrlGenerator.class

<?php
/*
 * Gallery - a web based photo album viewer and editor
 * Copyright (C) 2000-2007 Bharat Mediratta
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA  02110-1301, USA.
 */

/* Don't use GalleryCoreApi::requireOnce here; index.php uses this file without GalleryCoreApi */
require_once(dirname(__FILE__) . '/GalleryUtilities.class');

if (!defined('GALLERY_MAIN_PHP')) {
    define('GALLERY_MAIN_PHP', 'main.php');
}

/**
 * This class generates all URLs for Gallery based on the auto-detected protocol, hostname, URL
 * path and the given GALLERY_MAIN_PHP.  Handles normal standalone as well as embedded and
 * multisite operation when some URLs need to go to the Gallery codebase directly.  Also handles
 * the navigation (history) together with GallerySession.  All auto-detected URL parts can be
 * overrided with the init() parameters (originating either from the optional config.php parameter
 * 'baseUri' or from GalleryEmbed).
 *
 * @package GalleryCore
 * @subpackage Classes
 * @author Bharat Mediratta <bharat@menalto.com>
 * @author Alan Harder <alan.harder@sun.com>
 * @version $Revision: 15792 $
 */
class GalleryUrlGenerator {

    /**
     * URL base filename of Gallery, defaults to 'main.php'.  Can also include some parameters, eg.
     * main.php?foo=bar.
     *
     * Index of array = $forceDirect (true/false) only relevant for embedded Gallery
     * array (0 => string file, 1 => string forceDirect file)
     * @var array
     * @access private
     */
    var $_file;

    /**
     * URL path to Gallery, eg. '/gallery2/' of http://example.com/gallery2/main.php.
     *
     * Index of array = $forceDirect (true/false) only relevant for embedded Gallery
     * array (0 => string path, 1 => string forceDirect path)
     * @var array
     * @access private
     */
    var $_path;

    /**
     * The host string of generated URLs (including optional port) eg. 'www.example.com'.
     *
     * Index of array = $forceDirect (true/false) only relevant for embedded Gallery
     * array (0 => string host, 1 => string forceDirect host)
     * @var array
     * @access private
     */
    var $_host;

    /**
     * The protocol of generated URLs, 'http' or 'https'.
     *
     * Index of array = $forceDirect (true/false) only relevant for embedded Gallery
     * array (0 => string protocol, 1 => string forceDirect protocol)
     * @var array
     * @access private
     */
    var $_protocol;

    /**
     * The session key=value for the CMS application in which Gallery is embedded.  Should only be
     * non-empty when cookieless browsing is supported by CMS, eg. 'session=3838562834573' which is
     * then added to all URLs generated by Gallery.
     * @var string
     * @access private
     */
    var $_embedSessionString;

    /**
     * The base host (protocol + host name) of all URLs generated with function makeUrl.
     *
     * Index of array = $forceDirect (true/false), eg. 'http://example.com/'
     * array (0 => string base host, 1 => string forceDirect base host)
     * @var array
     * @access private
     */
    var $_currentBaseHost;

    /**
     * The complete URL (protocol + host name + path + file + query string) of the current request
     * eg. 'http://example.com/gallery2/main.php?g2_view=core.ShowItem&g2_itemId=15'.
     *
     * Index of array = $forceDirect (true/false) only relevant for embedded Gallery
     * array (0 => string base URL, 1 => string forceDirect base URL)
     * @var array
     * @access private
     */
    var $_currentUrl;

    /**
     * The complete URL dir (protocol + host name + path) of all URLs to be generated eg.
     * 'http://example.com/gallery2/.
     *
     * Index of array = $forceDirect (true/false) only relevant for embedded Gallery
     * array (0 => string base URL dir, 1 => string forceDirect base URL dir)
     * @var array
     * @access private
     */
    var $_currentUrlBaseDir;

    /**
     * The navigation id of the current URL.
     * @var string
     * @access private
     */
    var $_navId = '';

    /**
     * Whether the cookie path was configured by the admin.
     * @var boolean
     * @access private
     */
    var $_isCookiePathConfigured;

    /*
     * ****************************************
     *              Static Methods
     */

    /**
     * Return the current request URI.
     * Example: for http://domain.com/gallery2/main.php?g2_view=core.ShowItem
     *          it returns /gallery2/main.php?g2_view=core.ShowItem
     *
     * @return string the current URL path component plus query parameters
     * @static
     */
    function getCurrentRequestUri() {
	if ($path = GalleryUtilities::getServerVar('REQUEST_URI')) {
	    /* Sometimes, REQUEST_URI has a host part. Remove it. */
	    if ($path{0} != '/') {
		$components = parse_url($path);
		$path = $components['path'];
		$path .= empty($components['query']) ? '' : '?' . $components['query'];
		$path .= empty($components['fragment']) ? '' : '#' . $components['fragment'];
	    }
	} else if ($path = GalleryUtilities::getServerVar('SCRIPT_NAME')) {
	    if (($tmp = GalleryUtilities::getServerVar('PATH_INFO')) && $tmp != $path) {
		$path .= $tmp;
	    }
	    if ($tmp = GalleryUtilities::getServerVar('QUERY_STRING')) {
		$path .= '?' . $tmp;
	    }
	}

	GalleryUtilities::unsanitizeInputValues($path, false);
	return $path;
    }

    /**
     * Append parameters to a URL using the Gallery prefix and URL encoding keys and values.
     * @param string $url the original URL
     * @param array $params key/value pairs to be appended; may contain nested arrays
     * @param boolean $addPrefix (optional) false to not add prefix to parameter names
     * @param boolean $htmlEntities (optional) false to not convert ampersands to HTML entities
     * @param boolean $urlEncode (optional) false to not URL encode parameter names and values
     * @return string the new URL (&amp; separates added params)
     * @static
     */
    function appendParamsToUrl($url, $params, $addPrefix=true, $htmlEntities=true,
			       $urlEncode=true) {
	if (empty($params)) {
	    return $url;
	}

	$args = $flatParams = array();
	GalleryUrlGenerator::_flattenParamsArray($params, $flatParams);

	foreach ($flatParams as $key => $value) {
	    if ($addPrefix) {
		$key = GalleryUtilities::prefixFormVariable($key);
	    }
	    if ($urlEncode) {
		$key = urlencode($key);
		$value = urlencode($value);
	    }
	    $args[] = $key . '=' . $value;
	}

	/* Prefix appended params with ? if the URL doesn't already have a query string */
	$amp = $htmlEntities ? '&amp;' : '&';
	return $url . ((strpos($url, '?') === false) ? '?' : $amp) . implode($amp, $args);
    }

    /**
     * Convert a structure of nested URL parameters into a flat array of parameters.
     *
     * Preserves the order of the parameters and does not encode them yet.
     * Example: Input  array('a' => '1', 'b' => array('c' => 2), 'd' = 3)
     *          Result array('a' => '1', 'b[c]' => 2, 'd' = 3)
     *
     * @param array $nestedParams array of URL parameters, can have nested arrays
     * @param array $flatParams flat array of URL parameters
     * @param string $keyBase (optional) base of the key for nested array parameters
     * @static
     * @access private
     */
    function _flattenParamsArray($nestedParams, &$flatParams, $keyBase=null) {
	foreach ($nestedParams as $key => $value) {
	    $key = empty($keyBase) ? $key : $keyBase . '[' . $key . ']';
	    if (is_array($value)) {
		GalleryUrlGenerator::_flattenParamsArray($value, $flatParams, $key);
	    } else {
		$flatParams[$key] = $value;
	    }
	}
    }

    /**
     * Old multisite system used a galleryId based on the current URL.  Return a value here so sites
     * won't break before they can upgrade.
     * @todo Remove on next major bump of core api
     *
     * @static
     * @deprecated
     */
    function getGalleryId() {
	return '';
    }

    /**
     * Split a URI string into file, path, host and protocol substrings and normalize them.
     *
     * Used to allow overriding auto-detected protocol, host, path and default base file.  Also used
     * to accept various embedUri formats
     *
     * @param string $uri URI
     * @return array $protocol, $host, $path, $file (incl. query string)
     * @access private
     * @static
     */
    function _parseUri($uri) {
	/*
	 * baseUri / g2Uri can have the following patterns:
	 *    - Everything before the two last '/' is interpreted as path
	 *      (minus the host part, if specified).
	 *    - Thus URI with leading '/' are interpreted as path (+ optional file).
	 *    - If there is a '/' and no http://, everything before the first '/' is
	 *      interpreted as host string and the protocol defaults to http.
	 *    - If it starts with http://, everything after it up to the first '/'
	 *      is interpreted as the host string.
	 *    - Everything after the last '/' is interpreted as file + query string.
	 * Examples of allowed URI strings:
	 *    http://www.example.com
	 *    http://example.com/gallery2/
	 *    https://127.0.0.1/gallery2/main.php
	 *    www.example.com/main.php
	 *    /gallery2/
	 *    /gallery2/main.php
	 *    /main.php
	 *    main.php
	 * Notes (= what you shouldn't do):
	 *    www.example.com (no '/' -> interpreted as file and not as host)
	 *    main.php/ (everything before the last '/' is interpreted as path)
	 */
	$file = $uri;
	$path = $host = $protocol = '';
	if (strpos($file, '/') !== false) {
	    /* Check if it's a URL including host and optional protocol part */
	    if (preg_match('{^(?:(https?)://)?([^/]+)(.*)$}', $file, $matches)) {
		$protocol = $matches[1];
		$host = $matches[2];
		$file = $matches[3];
	    }
	    /* $file = '/...', '/.../', '/.../...' or '...' '*/
	    if (preg_match('{^(/(?:.*/)?)?([^/]*)$}', $file, $matches)) {
		$path = $matches[1];
		$file = $matches[2];
	    }
	}

	return array($protocol, $host, $path, $file);
    }

    /*
     * ****************************************
     *              Object Methods
     */

    /**
     * Configure the GalleryUrlGenerator with all the data it needs.
     *
     * @param string $baseUri the base URL (optional), eg. index.php?mod=gallery will override
     *        main.php, /index.php or /gallery/index.php will override the path and file,
     *        /gallery/ overrides the path only, example.com/, overrides the host and the path and
     *        http://example.com/gallery/index.php?page=gallery overrides all parts
     *        All non-specified parts fall back to auto-detected values
     * @param string $g2Uri (optional) when embedded, base URL to Gallery standalone.  Same format
     *        as baseUri
     * @param string $embedSessionString (optional) when embedded in CMS app that supports
     *        cookieless browsing, key=value string for CMS session key and id
     */
    function init($baseUri=null, $g2Uri=null, $embedSessionString=null) {
	$this->_embedSessionString = $embedSessionString;

	if (isset($baseUri)) {
	    list ($this->_protocol[0], $this->_host[0], $this->_path[0], $this->_file[0]) =
		$this->_parseUri($baseUri);
	} else {
	    $this->_file[0] = GALLERY_MAIN_PHP;
	    /*
	     * Set the default value for the path part, if necessary (path = empty string is
	     * interpreted as not set / forced in URL generators ('/' would be interpreted as set)
	     */
	    $this->_path[0] = '';
	    $this->_protocol[0] = $this->_host[0] = null;
	}

	/* Set the forceDirect configuration parameters (only different if Gallery is embedded) */
	if (!empty($g2Uri)) {
	    list ($this->_protocol[1], $this->_host[1], $this->_path[1], $this->_file[1]) =
		$this->_parseUri($g2Uri);
	    /* If file[1] is empty, we default to GALLERY_MAIN_PHP, unless it's intended */
	    if ($this->_file[1] == '|') {
		/* User actually intends to set the file to an empty string */
		$this->_file[1] = '';
	    } else if (empty($this->_file[1])) {
		$this->_file[1] = GALLERY_MAIN_PHP;
	    }
	} else {
	    $this->_file[1] = $this->_file[0];
	    $this->_path[1] = $this->_path[0];
	    $this->_host[1] = $this->_host[0];
	    $this->_protocol[1] = $this->_protocol[0];
	}

	/* Set the default value for the host part, if necessary */
	foreach (array(false, true) as $forceDirect) {
	    if (empty($this->_host[$forceDirect])) {
		if (!isset($defaultHost) &&
		    !($defaultHost = GalleryUtilities::getServerVar('HTTP_X_FORWARDED_HOST'))) {
		    $defaultHost = GalleryUtilities::getServerVar('HTTP_HOST');
		}

		$this->_host[$forceDirect] = $defaultHost;
	    }
	}

	/* Set the default value for the protocol part, if necessary */
	foreach (array(false, true) as $forceDirect) {
	    if (empty($this->_protocol[$forceDirect])) {
		$this->_protocol[$forceDirect] =
		    (GalleryUtilities::getServerVar('HTTPS') == 'on') ? 'https' : 'http';
	    }
	}

	/* Set the base host (protocol + host name)  for makeUrl() (caching/performance) */
	foreach (array(false, true) as $forceDirect) {
	    $this->_currentBaseHost[$forceDirect] = sprintf('%s://%s',
							    $this->_protocol[$forceDirect],
							    $this->_host[$forceDirect]);
	}

	/* Check if the cookie path is configured */
	if (GalleryUtilities::isEmbedded()) {
	    list ($ret, $path) =
		GalleryCoreApi::getPluginParameter('module', 'core', 'cookie.path');
	    if ($ret) {
		return $ret;
	    }
	    if (!empty($path)) {
		$this->_isCookiePathConfigured = true;
	    } else {
		$this->_isCookiePathConfigured = false;
	    }
	}

	return null;
    }

    /**
     * Return the host name for the current request.
     *
     * @param boolean $forceDirect (optional) if true, ensure Gallery base protocol/host is used
     * @return string the host name
     */
    function getHostName($forceDirect=false) {
	return $this->_host[$forceDirect];
    }

    /**
     * Add given path to current protocol/server/port to create full URL.
     *
     * @param string $path the URL path; leading slash will be added if missing
     * @param boolean $forceDirect (optional) if true, ensure Gallery base protocol/host is used
     * @return string the URL
     */
    function makeUrl($path, $forceDirect=false) {
	if (empty($path)) {
	    $path = '/';
	} else if ($path{0} != '/') {
	    $path = '/' . $path;
	}

	return $this->_currentBaseHost[$forceDirect] . $path;
    }

    /**
     * Make a given URL an absolute Gallery URL. The specified URL can be relative (e.g. main.php),
     * server-relative (e.g. /gallery2/main.php) or already absolute.
     *
     * @param string a relative, server-relative or absolute URL
     * @param boolean $forceDirect (optional) if true, Gallery base protocol/host is used in case
     *                             the URL isn't absolute already
     * @return string the absolute URL
     */
    function makeAbsoluteUrl($url, $forceDirect=false) {
	$url = trim($url);
	if (!preg_match('#^[A-Za-z0-9+.\-]+://#', $url)) {
	    if (substr($url, 0, 1) == '/') {
		$url = $this->makeUrl($url, $forceDirect);
	    } else {
		$url = $this->getCurrentUrlDir($forceDirect) . $url;
	    }
	}
	return $url;
    }

    /**
     * Return the complete URL of the current request.
     *
     * The returned URL may differ from the actual request URL since we allow for overriding the
     * discovered protocol/host/host/path/file
     *
     * @param boolean $forceDirect (optional) if true, ensure Gallery base protocol/host is used
     * @return string the current URL
     */
    function getCurrentUrl($forceDirect=false) {
	if (!isset($this->_currentUrl[$forceDirect])) {
	    /* Allow overriding protocol / host part, but keep request string unchanged */
	    $this->_currentUrl[$forceDirect] =
		$this->makeUrl(GalleryUrlGenerator::getCurrentRequestUri(), $forceDirect);
	}

	return $this->_currentUrl[$forceDirect];
    }

    /**
     * Return a URL that is stripped of all parameters that don't directly affect the output of the
     * page, like navigation parameters.  This URL can be used as the cache key for this page.
     *
     * @return string
     */
    function getCacheableUrl() {
	$url = $this->getCurrentUrl();
	$parsed = parse_url($url);
	$url = !empty($parsed['scheme']) ? $parsed['scheme'] . ':' . '//' : '';
	$url .= !empty($parsed['user']) ? $parsed['user'] .
	    ($parsed['pass'] ? ':'.$parsed['pass'] : '') . '@' : '';
	$url .= !empty($parsed['host']) ? $parsed['host'] : '';
	$url .= !empty($parsed['port']) ? ':' . $parsed['port'] : '';
	$url .= !empty($parsed['path']) ? $parsed['path'] : '';
	if (!empty($parsed['query'])) {
	    parse_str($parsed['query'], $components);
	    foreach (array('statusId', 'return', 'returnName', 'navId', 'fromNavId') as $special) {
		unset($components[GALLERY_FORM_VARIABLE_PREFIX . $special]);
	    }
	    $first = true;
	    foreach ($components as $key => $value) {
		$url .= $first ? '?' : '&';
		$url .= "$key=$value";
		$first = false;
	    }
	}
	$url .= !empty($parsed['fragment']) ? '#' . $parsed['fragment'] : '';
	return $url;
    }

    /**
     * Return the base directory of all generated URLs.  Eg, if the URL is:
     *   http://example.com/gallery2/main.php
     * Then we return:
     *   http://example.com/gallery2/
     *
     * Usually, it's the same as the URL directory of the current request URL, unless we're using
     * short URLs. Also, the base URL can be overridden
     *
     * @param boolean $forceDirect (optional) if true, ensure Gallery base URL is returned
     *        (different when embedded)
     * @return string the base URL directory
     */
    function getCurrentUrlDir($forceDirect=false) {
	if (!isset($this->_currentUrlBaseDir[$forceDirect])) {

	    if (!empty($this->_path[$forceDirect])) {
		/* An override for the path was defined (most likely an embedded Gallery request) */
		$url = $this->makeUrl($this->_path[$forceDirect], $forceDirect);
	    } else {
		/*
		 * Non-embedded request (else path must be set)
		 * Auto-detect the path in the current URL
		 */
		$url = $this->getCurrentUrl($forceDirect);

		/*
		 * Remove the base file and any query string after it
		 *    http://example.com/gallery2/main.php?g2_foo=foo/bar
		 * Extract everything up to but not including main.php:
		 *    http://example.com/gallery2/
		 * Note: PathInfo is handled by the PathInfoUrlGenerator
		 */
		if (empty($this->_file[0])) {
		    $url = substr($url, 0, strrpos($url, '/') + 1);
		} else if (($i = strpos($url, $this->_file[0])) !== false) {
		    $url = substr($url, 0, $i);
		} else if (($i = strpos($url, '?')) !== false) {
		    /* We couldn't find the file name, at least remove the query string */
		    $url = substr($url, 0, $i);
		}
	    }
	    $url .= substr($url, -1) != '/' ? '/' : '';

	    $this->_currentUrlBaseDir[$forceDirect] = $url;
	}

	return $this->_currentUrlBaseDir[$forceDirect];
    }

    /**
     * Generate a Gallery URL.
     * @param array $params (optional) key=value pairs to be included in the URL
     *     special 'href' key specifies path to append to Gallery base URL instead of a query param
     *     %CURRENT_URL% token in a parameter value will be replaced with current URL
     * @param array $options (optional) additional URL generation options:
     *     'baseUrl' => string; to override the default baseUrl
     *     'forceDirect' => true; to generate from Gallery site URL even if embedded or multisite
     *     'forceFullUrl' => true; to generate absolute URL instead of relative path URL
     *     'forceSessionId' => boolean; to force session id to be included or excluded; by default
     *         it is included when cookies are not in use (by default it is excluded from href URLs)
     *     'htmlEntities' => false; to use '&' parameter separator instead of '&amp;'
     *     'urlEncode' => false; to not URL encode parameter names and values
     *     'forceServerRelativeUrl' => true; to generate server-relative URLs if possible but no
     *         relative URLs (e.g. /gallery2/main.php instead of
     *         http://example.com/gallery2/main.php but never just main.php (without path))
     *     'useAuthToken' => boolean; to force auth token to be included or excluded; by default it
     *         is included in controller URLs
     *     'protocol' => string; to override the URL scheme
     * @return string URL
     */
    function generateUrl($params=array(), $options=array()) {
	global $gallery;
	$currentView = $gallery->getCurrentView();

	/*
	 * For 'core.DownloadItem' URLs or if 'forceDirect' option given, use Gallery site URL
	 * (direct to main.php in directory for active config.php, even if embedded/multisite).  For
	 * other non-absolute 'href' URLs use Gallery base URL (direct to Gallery codebase location,
	 * even if multisite or embedded).  Otherwise use application URL (embed URL; same as
	 * Gallery site URL if not embedded).
	 */
	if (isset($options['baseUrl'])) {
	    $url = $options['baseUrl'];
	    $appSession = true;
	} else if (isset($params['href'])) {
	     /* In case of multisites, get the codebase base URL */
	    $url = $gallery->getConfig('galleryBaseUrl');
	    if (empty($url) || !empty($options['forceDirect'])) {
		$url = $this->getCurrentUrlDir(true);
	    }

	    /* Default to not including session id in href URLs */
	    if (!isset($options['forceSessionId'])) {
		$options['forceSessionId'] = false;
	    }

	    $href = $params['href'];
	    unset($params['href']);
	    if (preg_match('/^[a-zA-Z0-9\+\.\-]+:\/\//', $href)) {
		/* Absolute URL */
		$url = $href;
	    } else if (($pos = strpos($href, '/')) === 0) {
		/* Absolute URL path (use $options['baseUrl'] if you need non forceDirect URLs) */
		$url = $this->makeUrl($href, true);
	    } else if ($pos > 0) {
		/* Check for local override */
		$override = sprintf('%s/local/%s', dirname($href), basename($href));
		$platform =& $gallery->getPlatform();
		if ($platform->file_exists(dirname(__FILE__) . '/../../../' . $override)) {
		    $href = $override;
		}
		$url .= $href;
	    } else {
		$url .= $href;
	    }
	} else if ((isset($params['view']) && $params['view'] == 'core.DownloadItem')
		|| !empty($options['forceDirect'])) {
	    /* DownloadItem requests go always directly to Gallery, even when embedded */
	    $url = $this->getCurrentUrlDir(true) . $this->_file[true];

	    /* Check if we are forced to append the session id in embedded Gallery */
	    if ($this->embedForceSessionId($params)) {
		$options['forceSessionId'] = true;
	    }
	} else {
	    $url = $this->getCurrentUrlDir() . $this->_file[0];
	    $appSession = true;
	}

	/* Swap in the actual URL for the 'return' placeholder */
	if (isset($params['return'])) {
	    list ($ret, $view) = GalleryView::loadView($currentView);
	    if (!$ret) {
		list ($ret, $viewDescription) = $view->getViewDescription();
		if (!$ret) {
		    $params['returnName'] = $viewDescription;
		}
	    }
	    $params['return'] = str_replace('&amp;', '&', $this->getNavigationReturnUrl());
	    if (!empty($this->_navId)) {
		$params['navId'] = $this->_navId;
	    }
	}

	/* Navigation */
	$targetView = isset($params['view']) ? $params['view'] : '';
	if (!empty($this->_navId) && empty($options['forceDirect'])
		&& (empty($currentView)
		    || $currentView == $targetView
		    || !empty($params['controller']))) {
	    /*
	     * We are moving around in the same view or we are redirecting to a controller,
	     * who knows where it will redirect to.  Let's keep the navigation.
	     */
	    $params['navId'] = $this->_navId;
	}

	/* Replace any known tokens */
	foreach (array_keys($params) as $key) {
	    if ($params[$key] === '%CURRENT_URL%') {
		$params[$key] = $this->getCurrentUrl();
	    }
	}

	/* Shorten URLs by removing default values */
	if (isset($params['view']) && $params['view'] == GALLERY_DEFAULT_VIEW) {
	    unset($params['view']);

	    if (empty($this->_rootItemId)) {
		list ($ret, $this->_rootItemId) = GalleryCoreApi::getDefaultAlbumId();
		if ($ret) {
		    $this->_rootItemId = -1;
		}
	    }
	    if (isset($params['itemId']) && $params['itemId'] == $this->_rootItemId) {
		unset($params['itemId']);
	    }
	}

	if ($session =& $gallery->getSession()) {
	    $sessionId = $session->getId();

	    /*
	     * Remove session related parameters if requested (we're already outputting or output
	     * without fetching the HTML (immediate view / progressbar)
	     */
	    if (empty($sessionId) || !$session->isPersistent()) {
		unset($params['navId']);
	    } else {
		/* Add authToken to all controller URLs */
		if (!empty($options['useAuthToken'])
			|| (!isset($options['useAuthToken']) && !empty($params['controller']))) {
		    $params['authToken'] = $session->getAuthToken();
		}
	    }

	    /* Add session parameters to URL */
	    if (!empty($options['forceSessionId'])
		|| (!isset($options['forceSessionId']) && !$session->isUsingCookies())) {
		if (!empty($this->_embedSessionString) && !empty($appSession)) {
		    list ($sessionKey, $sessionId) = explode(
			'=', $this->_embedSessionString, 2);
		    $embedSessionParams = array();
		    $embedSessionParams[$sessionKey] = $sessionId;
		} else if (!empty($sessionId)) {
		    $params[$session->getKey()] = $sessionId;
		}
	    }
	}

	/* Add parameters to URL */
	$url = GalleryUrlGenerator::appendParamsToUrl($url, $params, true,
	    !empty($options['htmlEntities']) || !isset($options['htmlEntities']),
	    !empty($options['urlEncode']) || !isset($options['urlEncode']));

	/* Add embed session parameters to URL */
	if (!empty($embedSessionParams)) {
	    $url = GalleryUrlGenerator::appendParamsToUrl($url, $embedSessionParams, false,
		!empty($options['htmlEntities']) || !isset($options['htmlEntities']), false);
	}

	/* Replace protocol with $options['protocol'].  See RFC1738 section 2.1. */
	if (isset($options['protocol'])) {
	    $url = preg_replace('/^[a-zA-Z0-9\+\.\-]+:/', $options['protocol'] . ':', $url);
	}

	/*
	 * Elide as much of the common URL as we can to save space.  This won't cover all cases,
	 * since other URL generators could be subclassing this, but it should be relatively safe
	 * because it's only removing substrings that match exactly.  If rewrite is on, then we have
	 * to use a server relative path since we may be at a URL like /v/foo/bar so if we try for a
	 * pure relative path then we'll wind up using /v/foo/bar as the base for relative URLs
	 */
	if (empty($options['forceFullUrl'])) {
	    $url = $this->makeRelativeUrl($url, !empty($options['forceServerRelativeUrl']));
	}

	return $url;
    }

    /**
     * Translate the given absolute URL to a relative URL.
     *
     * The result will be either a server relative URL /..., a URL relative to the current URL
     * directory or an unchanged absolute URL (some URLs in multisite go to the codebase, embedded
     * Gallery could be on a different subdomain, ..)
     *
     * Note: don't be fooled if $this->_file shows up in the query string!
     *
     * @param string $url absolute URL
     * @return string relative URL (or unchanged absolute URL)
     */
    function makeRelativeUrl($url, $forceServerRelativeUrl=false) {
	$requestUri = $this->getCurrentRequestUri();
	/* When embedded, file can be empty */
	if ($forceServerRelativeUrl || empty($this->_file[0])
		|| ($pos = strpos($requestUri, $this->_file[0])) === false
		|| (($qPos = strpos($requestUri, '?')) !== false && $pos >= $qPos)
		|| strpos($url, $this->getCurrentUrlDir()) !== 0) {
	    /* Don't use forceDirect, keep the URL absolute if necessary */
	    $url = str_replace($this->makeUrl('/'), '/', $url);
	} else {
	    $url = str_replace($this->getCurrentUrlDir(), '', $url);
	}

	return $url;
     }

    /**
     * Get the cookie path that will encompass Gallery (and CMS app if embedded).
     *
     * The forceDirect parameter forces the function to return the path to Gallery and not to the
     * current dir of the URL.  This is only relevant when Gallery is embedded.  forceDirect is only
     * used for applets because they talk to Gallery directly and not through the embedding
     * application.  If the cookie path wouldn't be set to the Gallery base in this case, the applet
     * wouldn't select the cookie for requests, because it wasn't allowed to (according to the
     * cookie specs)
     *
     * Examples:
     * Current URL                                 forceDirect        cookie path
     * http://example.com/gallery2/main.php        false              /gallery2/
     * http://example.com/gallery2/main.php        true               /gallery2/
     * http://example.com/applicationXy/index.php  false              /applicationXy/
     * http://example.com/applicationXy/index.php  true               /gallery2/
     *
     * In the last example we assumed that Gallery is installed at that location.
     *
     * @param boolean $forceDirect (optional) if true, ensure Gallery path of base URL is returned
     *                (different when embedded)
     * @return array (object Gallery status, string path)
     */
    function getCookiePath($forceDirect=false) {
	if (!isset($this->_cookiePath[$forceDirect])) {
	    /* Return the configured path is it is set */
	    list ($ret, $path) = GalleryCoreApi::getPluginParameter('module', 'core',
								    'cookie.path');
	    if ($ret) {
		return array($ret, null);
	    }
	    if (empty($path)) {
		if (!empty($this->_path[$forceDirect])) {
		    $path = $this->_path[$forceDirect];
		} else {
		    $urlComponents = parse_url($this->getCurrentUrlDir($forceDirect));
		    $path = $urlComponents['path'];
		}
	    }
	    $this->_cookiePath[$forceDirect] = $path;
	}

	return array(null, $this->_cookiePath[$forceDirect]);
    }

    /**
     * Initialize the navigation branch.
     *
     * If we came here with a 'return' set, we need to branch a new navigation.  If we are just
     * navigating through options in the same navigation level, simply pass the navId along.  If we
     * are coming back from a navigation, clean up our mess.  In other cases we simply have no
     * navigation support
     *
     * Note: This should be called as soon as we have access to our session and the
     * requestVariables, but before we start generating URLs with generateUrl().  Currently it's
     * called from GalleryInitSecondPass
     *
     * @return object GalleryStatus
     */
    function initNavigation() {
	global $gallery;

	$variables =
	    GalleryUtilities::getRequestVariables('return', 'returnName', 'navId', 'fromNavId');
	foreach ($variables as $key  => $value) {
	    $variables[$key] = is_string($value) ? $value : null;
	}
	list ($returnUrl, $returnName, $navId, $fromNavId) = $variables;

	if (!empty($returnUrl)) {
	    /* Detect header injection attempts */
	    if (!GalleryUtilities::isSafeHttpHeader($returnUrl)) {
		$message = sprintf('Invalid return URL! The requested URL %s contains malicious ' .
				   'characters.',
				   $this->makeUrl($this->getCurrentRequestUri()), $returnUrl);
		return GalleryCoreApi::error(ERROR_PERMISSION_DENIED, __FILE__, __LINE__, $message);
	    }

	    /*
	     * Check for phishing attacks, don't allow return URLs to other sites or to other paths.
	     * Therefore first get the validPath, e.g. '/gallery2/' Do not allow ../ to break out of
	     * the path Allow all URLs that don't start with a protocol and neither with '/', eg.
	     * v/albumname but also www.EVIL.com is fine, since it's interpreted as a relative URL
	     */
	    $validPath =  '/' . str_replace($this->makeUrl(''), '', $this->getCurrentUrlDir());
	    /*
	     * We check for ../ and /../ patterns and on windows \../ would also break out,
	     * normalize to URL / *nix style paths to check fewer cases
	     */
	    $normReturnUrl = str_replace("\\", '/', $returnUrl);
	    if (((empty($this->_file[0]) || strpos($returnUrl, $this->_file[0]) !== 0)
			&& strpos($normReturnUrl, $validPath) !== 0
			&& strpos($returnUrl, $this->getCurrentUrlDir()) !== 0
			&& !( !preg_match('{^\s*\w*://}i', $normReturnUrl)
			    && preg_match('{^\s*[^/\s]}i', $normReturnUrl)))
		    || preg_match('{^\s*\.\./}', $normReturnUrl)
		    || strpos($normReturnUrl, '/../') !== false) {
		$message = sprintf('Invalid return URL! The requested URL %s tried to insert a ' .
				   'redirection to %s which is not a part of this Gallery.',
				   $this->makeUrl($this->getCurrentRequestUri()), $returnUrl);
		return GalleryCoreApi::error(ERROR_PERMISSION_DENIED, __FILE__, __LINE__, $message);
	    }

	    /* Branch a new navigation */
	    $navData = array('returnUrl' => $returnUrl,
			     'returnName' => $returnName);
	    if (!empty($navId)) {
		$navData['returnNavId'] = $navId;
	    }
	    $session =& $gallery->getSession();
	    $this->_navId = $session->addToNavigation($navData);
	} else {
	    if (!empty($fromNavId)) {
		/* We came back from a navigational branch. Delete it */
		$session =& $gallery->getSession();
		$session->jumpNavigation($fromNavId, $navId);
	    }
	    if (!empty($navId)) {
		/* Just continue in our current navigation level */
		$this->_navId = $navId;
	    }
	}

	return null;
    }

    /**
     * Get the current navigation id.
     *
     * @return string the navigation id
     */
    function getNavigationId() {
	return $this->_navId;
    }

    /**
     * Get an URL to return to the currently loaded view, stripping all parameters that are of
     * navigational nature.
     *
     * @return string the URL
     */
    function getNavigationReturnUrl() {
	global $gallery;

	$formUrl = GalleryUtilities::getRequestVariables('formUrl');
	if (!empty($formUrl)) {
	    /*
	     * We don't really have an URL, because we are in a POST request.  This is the last
	     * known URL when the form was originally rendered
	     */
	    return $formUrl;
	}

	$params = GalleryUtilities::getUrlVariablesFiltered(
		array('return', 'returnName', 'navId', 'fromNavId', 'authorization'), true);

	return $this->generateUrl($params, array('forceServerRelativeUrl' => 1));
    }

    /**
     * Check if we currently have a back link to where we came from.
     *
     * @return boolean true if we can go back
     */
    function isNavigationBackPossible() {
	global $gallery;
	if (empty($this->_navId)) {
	    return false;
	}
	$session =& $gallery->getSession();
	$navData = $session->getNavigation($this->_navId);
	return (count($navData) > 0);
    }

    /**
     * Get a list of navigation links to go back to where we came from.
     *
     * @param int $depth set this to get links back to a certain depth
     * @return array ( object GalleryStatus a status code,
     *                 array of navigational links: array('url' => ...,
     *                                            'name' => 'Back to ...'))
     */
    function getNavigationLinks($depth=null) {
	global $gallery;
	if (empty($this->_navId)) {
	    return array(null, array());
	}

	list ($ret, $core) = GalleryCoreApi::loadPlugin('module', 'core');
	if ($ret) {
	    return array($ret, null);
	}

	$session =& $gallery->getSession();
	$navData = $session->getNavigation($this->_navId);
	$links = array();
	$i = 0;
	foreach ($navData as $navItem) {
	    $i++;
	    if (isset($depth) && $i > $depth) {
		break;
	    }
	    $url = $navItem['returnUrl'];
	    $params = array('fromNavId' => $this->_navId);
	    if (isset($navItem['returnNavId'])) {
		$params['navId'] = $navItem['returnNavId'];
	    }
	    if (!empty($navItem['returnName'])) {
		$name = $core->translate(array('text' => 'Back to %s',
					       'arg1' => $navItem['returnName']));
	    } else {
		$name = $core->translate('Back');
	    }
	    $url = GalleryUrlGenerator::appendParamsToUrl($url, $params);
	    $links[] = array('url' => $url, 'name' => $name);
	}
	return array(null, $links);
    }

    /**
     * Decide whether to include session id in the URL.
     *
     * Force the session id in the URL for embedded DownloadItem URLs if the cookie.path plugin
     * parameter is not set. See GallerySession::init for details
     *
     * @param array $params (string param)
     * @return boolean forceSessionId
     * @access protected
     */
    function embedForceSessionId($params) {
	if (isset($params['view']) && $params['view'] == 'core.DownloadItem' &&
		GalleryUtilities::isEmbedded() && empty($this->_isCookiePathConfigured)) {
	    /*
	     * It is assumed that the Gallery session is initiated before generateUrl() is called
	     * for the first time
	     */
	    return true;
	} else {
	    return false;
	}
    }
}
?>

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists