Posted: Tue Jun 27, 2006 8:38 pm
ok I will have a look on the Gallery2 site.
Anyway thanks a lot Garvin
Regards Lars
Anyway thanks a lot Garvin
Regards Lars
Code: Select all
<?php
/*
* $RCSfile: GalleryUrlGenerator.class,v $
*
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2006 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.
*/
/**
* @version $Revision: 1.102 $ $Date: 2006/03/19 06:08:15 $
* @package GalleryCore
* @author Bharat Mediratta <bharat@menalto.com>
* @author Alan Harder <alan.harder@sun.com>
*/
/* 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');
}
/**
* Url Generator
*
* 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
*/
class GalleryUrlGenerator {
/*
* ****************************************
* Members
* ****************************************
*/
/**
* URL base filename of G2, defaults to 'main.php'
* Can also include some parameters, e.g. main.php?foo=bar
* Index of array = $forceDirect (true/false) only relevant for embedded G2
*
* @var array (0 => string file, 1 => string forceDirect file)
* @access private
*/
var $_file;
/**
* URL path to G2, e.g. '/gallery2/' of http://example.com/gallery2/main.php
* Index of array = $forceDirect (true/false) only relevant for embedded G2
*
* @var array (0 => string path, 1 => string forceDirect path)
* @access private
*/
var $_path;
/**
* The host string of generated URLs (including optional port)
* e.g. 'www.example.com'
* Index of array = $forceDirect (true/false) only relevant for embedded G2
*
* @var array (0 => string host, 1 => string forceDirect host)
* @access private
*/
var $_host;
/**
* The protocol of generated URLs, 'http' or 'https'
* Index of array = $forceDirect (true/false) only relevant for embedded G2
*
* @var array (0 => string protocol, 1 => string forceDirect protocol)
* @access private
*/
var $_protocol;
/**
* The session key=value for the CMS application in which G2 is embedded.
* Should only be nonempty when cookieless browsing is supported by CMS.
* e.g. 'session=3838562834573' which is then added to all URLs generated by G2
*
* @var string $_embedSessionString
* @access private
*/
var $_embedSessionString;
/**
* The base host (protocol + host name) of all URLs generated with function makeUrl
* Index of array = $forceDirect (true/false), e.g. 'http://example.com/'
*
* @var array (0 => string base host, 1 => string forceDirect base host)
* @access private
*/
var $_currentBaseHost;
/**
* The complete URL (protocol + host name + path + file + query string) of the current request
* e.g. 'http://example.com/gallery2/main.php?g2_view=core.ShowItem&g2_itemId=15'
* Index of array = $forceDirect (true/false) only relevant for embedded G2
*
* @var array (0 => string base URL, 1 => string forceDirect base URL)
* @access private
*/
var $_currentUrl;
/**
* The complete URL dir (protocol + host name + path) of all URLs to be generated
* e.g. 'http://example.com/gallery2/
* Index of array = $forceDirect (true/false) only relevant for embedded G2
*
* @var array (0 => string base URL dir, 1 => string forceDirect base URL dir)
* @access private
*/
var $_currentUrlBaseDir;
/**
* The navigation id of the current URL.
*
* @var string $_navId
* @access private
*/
var $_navId = '';
/**
* Whether the cookie path was configured by the admin
*
* @var bool $_isCookiePathConfigured
* @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')) &&
($path = GalleryUtilities::getServerVar('SCRIPT_NAME'))) {
if (($tmp = GalleryUtilities::getServerVar('PATH_INFO')) && $tmp != $path) {
$path .= $tmp;
}
if ($tmp = GalleryUtilities::getServerVar('QUERY_STRING')) {
$path .= '?' . $tmp;
}
}
return GalleryUtilities::htmlEntityDecode($path);
}
/**
* Append parameters to a url using the G2 prefix and urlencoding the keys and values.
*
* @param string the original url
* @param array key/value pairs to be appended; may contain nested arrays
* @param boolean (optional) false to not add prefix on parameter names
* @return string the new url (& separates added params)
* @static
*/
function appendParamsToUrl($url, $params, $addPrefix=true) {
if (empty($params)) {
return $url;
}
$args = array();
foreach ($params as $key => $value) {
$key = $addPrefix ? GalleryUtilities::prefixFormVariable(urlencode($key))
: urlencode($key);
if (is_array($value)) {
GalleryUrlGenerator::_appendNestedParams($args, $value, $key . '[');
} else {
$args[] = $key . '=' . urlencode($value);
}
}
/* Prefix appended params with ? if the URL doesn't already have a query string */
return $url . ((strpos($url, '?') === false) ? '?' : '&') . implode('&', $args);
}
/**
* Append array of (possibly nested) query parameters to flat array of keys/values.
*
* @param array output array
* @param array input key/value pairs; may contain nested arrays
* @param string prefix; used in recursive calls
* @static
* @access private
*/
function _appendNestedParams(&$args, $params, $prefix) {
foreach ($params as $key => $value) {
if (is_array($value)) {
GalleryUrlGenerator::_appendNestedParams($args, $value,
$prefix . urlencode($key) . '][');
} else {
$args[] = $prefix . urlencode($key) . ']=' . urlencode($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.
* @static
* @deprecated
*/
function getGalleryId() {
return '';
}
/*
* ****************************************
* Object Methods
* ****************************************
*/
/**
* Initializer. Configure the url generator with all the data it needs.
*
* @param string the base URL (optional), e.g. index.php?mod=gallery will override main.php,
* /index.php or /gallery/index.php will override the path the 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 (optional) when embedded, the base URL to G2 standalone. Same format as baseUri
* @param string (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 G2 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_SERVER'))) {
$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->wrap(__FILE__, __LINE__);
}
if (!empty($path)) {
$this->_isCookiePathConfigured = true;
} else {
$this->_isCookiePathConfigured = false;
}
}
return null;
}
/**
* 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
* @return array $protocol, $host, $path, $file (incl. query string)
* @access privat
*/
function _parseUri($uri) {
/*
* baseUri / g2Uri can have the following patterns:
* - everything between the two last '/' is interpreted as path
* - thus URI with leading '/' are inerpreted as path (+ optional file)
* - if there is a '/' and no http://, everything before the first '/' is
* interpreted as host string
* - if there it starts with http://, everything after it up to the first '/'
* is interpreted as 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
* Note:
* 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);
}
/**
* Return the host name for the current request
*
* @param boolean (optional) if true, ensure G2 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 the url path; leading slash will be added if missing
* @param boolean (optional) if true, ensure G2 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;
}
/**
* 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 (optional) if true, ensure G2 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 (optional) if true, ensure G2 base url is returned (different when embedded)
* @return string thebase 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 G2 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];
}
/**
* Return a valid Gallery URL.
*
* @param array (optional) key/value pairs to be included in the URL
* special 'href' key specifies path to append to G2 base url instead of a query param
* %CURRENT_URL% token in a parameter value will be replaced with current url
* @param array (optional) additional url generation options:
* 'baseUrl' => string; to override the default baseUrl
* 'forceDirect' => true; to generate from G2 site url even if embedded
* 'forceFullUrl' => true; to generate absolute url instead of relative path url
* 'forceSessionId' => boolean; to force session id to be in/not in the url; by default
* it is included when cookies are not in use (for href urls, default=not included)
* 'htmlEntities' => false; to use & parameter separator instead of &
* '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))
*/
function generateUrl($params=array(), $options=array()) {
global $gallery;
$currentView = $gallery->getCurrentView();
/*
* For non-absolute 'href' urls always use G2 base url
* (direct to G2 codebase location, even if multisite or embedded),
* For 'core.DownloadItem' urls or if 'forceDirect' option given, use G2 site url
* (direct to main.php in directory for active config.php, even if embedded)
* Otherwise use application url
* (embed url; same as G2 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)) {
$url = $this->getCurrentUrlDir(true);
}
if (!isset($options['forceSessionId'])) {
/* Default to not including session id in href urls */
$options['forceSessionId'] = false;
}
$href = $params['href'];
unset($params['href']);
if (preg_match('{^[a-z]+://}', $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) {
/* Rewrite URL if theme is in plugins directory */
$pluginData = explode('/', $href, 3);
$pluginType = substr($pluginData[0], 0, -1);
$pluginId = $pluginData[1];
if (($pluginType == 'module' || $pluginType == 'theme')
&& !GalleryCoreApi::isPluginInDefaultLocation($pluginType, $pluginId)) {
$href = $gallery->getConfig('plugins.dirname') . '/' . $href;
}
/* 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;
}
/*
* FIXME: $url could be $gallery->getConfig('galleryBaseUrl') (multisite codebase)
* which is wrong if it's a URL that points to plugins.dirname
* instead, use $url = $this->getCurrentUrlDir(true) . $href
*/
$url .= $href;
} else {
$url .= $href;
}
} else if ((isset($params['view']) && $params['view'] == 'core.DownloadItem') ||
!empty($options['forceDirect'])) {
/* DownloadItem requests go always directly to G2, even when embedded */
$url = $this->getCurrentUrlDir(true) . $this->_file[true];
/* Check if we are forced to append the session id in embedded G2 */
if ($this->embedForceSessionId($params)) {
$options['forceSessionId'] = true;
}
} else {
$url = $this->getCurrentUrlDir() . $this->_file[0];
$appSession = true;
}
/* Decide whether to include session id in the url */
if ( (isset($options['forceSessionId']) &&
$options['forceSessionId'] === true && $session =& $gallery->getSession()) ||
(!isset($options['forceSessionId']) &&
$session =& $gallery->getSession() && !$session->isUsingCookies()) ) {
if (!empty($this->_embedSessionString) && isset($appSession)) {
$embedSessionString = $this->_embedSessionString;
} else {
$params[$session->getKey()] = $session->getId();
}
}
/* 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('&', '&', $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::getPluginParameter('module',
'core', 'id.rootAlbum');
if ($ret) {
$this->_rootItemId = -1;
}
}
if (isset($params['itemId']) && $params['itemId'] == $this->_rootItemId) {
unset($params['itemId']);
}
}
/*
* Remove session related params if requested (we're already outputting or output without
* fetching the html (immediate view / progressbar)
*/
if ($session =& $gallery->getSession()) {
$sessionId = $session->getId();
if (empty($sessionId)) {
unset($params[$session->getKey()]);
unset($params['navId']);
} else if (!$session->isPersistent()) {
unset($params['navId']);
}
}
/* Add parameters to url */
$url = GalleryUrlGenerator::appendParamsToUrl($url, $params);
/* Add embed session id if needed */
if (isset($embedSessionString)) {
$url .= ((strpos($url, '?') === false) ? '?' : '&') . $embedSessionString;
}
/*
* Elide as much of the common url as we can to save space. This will not cover all the
* 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']));
}
if (isset($options['htmlEntities']) && !$options['htmlEntities']) {
$url = str_replace('&', '&', $url);
}
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 G2 could be on a different subdomain, ..)
*
* Note: don't be fooled if $this->_file shows up in the query string!
*
* @param string 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 G2 (and CMS app if embedded)
*
* The forceDirect parameter forces the function to return the path to G2 and not to the
* current dir of the URL. This is only relevant when G2 is embedded.
* forceDirect is only used for applets because they talk to G2 directly and not through the
* embedding application. If the cookie path wouldn't be set to the G2 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 G2 is installed at that location.
*
* @param boolean (optional) if true, ensure G2 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->wrap(__FILE__, __LINE__), 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 _GalleryMain().
*
* @return object Gallery status
*/
function initNavigation() {
global $gallery;
list ($returnUrl, $returnName, $navId, $fromNavId) =
GalleryUtilities::getRequestVariables('return', 'returnName', 'navId', 'fromNavId');
if (!empty($returnUrl)) {
/*
* 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 '/', e.g.
* 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) {
list ($ret, $module) = GalleryCoreApi::loadPlugin('module', 'core');
if ($ret) {
return $ret->wrap(__FILE__, __LINE__);
}
$message = sprintf(
$module->translate('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 = array();
$urlVariables = GalleryUtilities::getUrlVariablesFiltered(
array('return', 'returnName', 'navId', 'fromNavId'));
foreach ($urlVariables as $key => $value) {
$params[substr($key, strlen(GALLERY_FORM_VARIABLE_PREFIX))] = $value;
}
return $this->generateUrl($params);
}
/**
* 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 integer 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->wrap(__FILE__, __LINE__), 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 G2 session is initiated before generateUrl() is called
* for the first time.
*/
return true;
} else {
return false;
}
}
}
?>