/typo3conf/ext/realurl/class.tx_realurl.php
PHP | 2787 lines | 1614 code | 289 blank | 884 comment | 400 complexity | b9f1b668f5260e817bfc22b904be50ce MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- <?php
- /***************************************************************
- * Copyright notice
- *
- * (c) 2004 Kasper Skaarhoj (kasper@typo3.com)
- * (c) 2005-2010 Dmitry Dulepov (dmitry@typo3.org)
- * All rights reserved
- *
- * This script is part of the Typo3 project. The Typo3 project 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.
- *
- * The GNU General Public License can be found at
- * http://www.gnu.org/copyleft/gpl.html.
- * A copy is found in the textfile GPL.txt and important notices to the license
- * from the author is found in LICENSE.txt distributed with these scripts.
- *
- *
- * This script 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.
- *
- * This copyright notice MUST APPEAR in all copies of the script!
- ***************************************************************/
- /**
- * Class for creating and parsing Speaking Urls
- *
- * $Id: class.tx_realurl.php 63839 2012-06-25 11:38:02Z dmitry $
- *
- * @author Kasper Skaarhoj <kasper@typo3.com>
- * @author Dmitry Dulepov <dmitry@typo3.org>
- */
- /**
- * [CLASS/FUNCTION INDEX of SCRIPT]
- *
- *
- *
- * 107: class tx_realurl
- *
- * SECTION: Translate parameters to a Speaking URL (t3lib_tstemplate::linkData)
- * 152: function tx_realurl()
- * 170: function encodeSpURL(&$params, $ref)
- * 241: function encodeSpURL_doEncode($inputQuery, $cHashCache = FALSE, $origUrl = '')
- * 324: function encodeSpURL_pathFromId(&$paramKeyValues, &$pathParts)
- * 353: function encodeSpURL_gettingPostVarSets(&$paramKeyValues, &$pathParts, $postVarSetCfg)
- * 390: function encodeSpURL_fileName(&$paramKeyValues)
- * 412: function encodeSpURL_setSequence($varSetCfg, &$paramKeyValues, &$pathParts)
- * 516: function encodeSpURL_setSingle($keyWord, $keyValues, &$paramKeyValues, &$pathParts)
- * 550: function encodeSpURL_encodeCache($urlToEncode, $internalExtras, $setEncodedURL = '')
- * 617: function encodeSpURL_cHashCache($newUrl, &$paramKeyValues)
- *
- * SECTION: Translate a Speaking URL to parameters (tslib_fe)
- * 669: function decodeSpURL($params, $ref)
- * 759: function decodeSpURL_checkRedirects($speakingURIpath)
- * 801: function decodeSpURL_doDecode($speakingURIpath, $cHashCache = FALSE)
- * 877: function decodeSpURL_createQueryStringParam($paramArr, $prependString = '')
- * 900: function decodeSpURL_createQueryString(&$getVars)
- * 925: function decodeSpURL_idFromPath(&$pathParts)
- * 966: function decodeSpURL_settingPreVars(&$pathParts, $config)
- * 989: function decodeSpURL_settingPostVarSets(&$pathParts, $postVarSetCfg)
- * 1054: function decodeSpURL_fixBrackets(&$arr)
- * 1080: function decodeSpURL_fileName($fileName)
- * 1108: function decodeSpURL_getSequence(&$pathParts, $setupArr)
- * 1201: function decodeSpURL_getSingle($keyValues)
- * 1217: function decodeSpURL_throw404($msg)
- * 1251: function decodeSpURL_jumpAdmin()
- * 1275: function decodeSpURL_jumpAdmin_goBackend($pageId)
- * 1290: function decodeSpURL_decodeCache($speakingURIpath, $cachedInfo = '')
- * 1354: function decodeSpURL_cHashCache($speakingURIpath)
- *
- * SECTION: Alias-ID look up functions
- * 1385: function lookUpTranslation($cfg, $value, $aliasToUid = FALSE)
- * 1495: function lookUp_uniqAliasToId($cfg, $aliasValue, $onlyNonExpired = FALSE)
- * 1522: function lookUp_idToUniqAlias($cfg, $idValue, $lang, $aliasValue = '')
- * 1550: function lookUp_newAlias($cfg, $newAliasValue, $idValue, $lang)
- * 1620: function lookUp_cleanAlias($cfg, $newAliasValue)
- *
- * SECTION: General helper functions (both decode/encode)
- * 1665: function setConfig()
- * 1699: function getPostVarSetConfig($page_id, $mainCat = 'postVarSets')
- * 1721: function pageAliasToID($alias)
- * 1744: function rawurlencodeParam($str)
- * 1759: function checkCondition($setup, $prevVal, $value)
- * 1777: function isBEUserLoggedIn()
- *
- * SECTION: External Hooks
- * 1794: function clearPageCacheMgm($params, $ref)
- * 1809: function isString(&$str, $paramName)
- * 1834: function findRootPageId($host = '')
- *
- * TOTAL FUNCTIONS: 41
- * (This index is automatically created/updated by the extension "extdeveval")
- *
- */
- /**
- * Class for creating and parsing Speaking Urls
- * This class interfaces with hooks in TYPO3 inside tslib_fe (for parsing speaking URLs to GET parameters) and in t3lib_tstemplate (for parsing GET parameters into a speaking URL)
- *
- * @author Kasper Skaarhoj <kasper@typo3.com>
- * @author Dmitry Dulepov <dmitry@typo3.org>
- * @package TYPO3
- * @subpackage tx_realurl
- */
- class tx_realurl {
- // External, static:
- var $NA = '-'; // Substitute value for "blank" values
- var $maxLookUpLgd = 100; // Max. length of look-up strings. Just a "brake"
- var $prefixEnablingSpURL = 'index.php'; // Only work Speaking URL on URLs starting with "index.php"
- var $decodeCacheTTL = 1; // TTL for decode cache, default is 1 day.
- var $encodeCacheTTL = 1; // TTL for encode cache, default is 1 day.
- // Internal:
- /** @var tslib_fe */
- var $pObj; // tslib_fe / GLOBALS['TSFE'] (for ->decodeSpURL())
- var $extConf; // Configuration for extension, from $TYPO3_CONF_VARS['EXTCONF']['realurl']
- var $adminJumpSet = FALSE; // Is set true (->encodeSpURL) if AdminJump is active in some way. Is set false again when captured first time!
- var $fe_user_prefix_set = FALSE; // Is set true (->encodeSpURL) if there is a frontend user logged in
- var $filePart; // Contains the filename when a Speaking URL is decoded.
- var $dirParts; // All directory parts of the string
- var $orig_paramKeyValues = array(); // Contains the index of GETvars that the URL had when the encoding began.
- var $appendedSlash = false; // Set true if slash is appended
- var $encodePageId = 0; // Set with the page id during encoding. for internal use only.
- var $speakingURIpath_procValue = ''; // For decoding, the path we are processing.
- var $disableDecodeCache = FALSE; // If set internally, decode caching is disabled. Used when a 303 header is set in tx_realurl_advanced.
- var $decode_editInBackend = FALSE; // If set (in adminjump function) then we will redirect to edit the found page id in the backend.
- var $encodeError = FALSE; // If set true encoding failed , probably because the url was outside of root line - and the input url is returned directly.
- var $host = ''; // Current host name. Set in setConfig()
- /**
- * Additional values to use when creating chash cache. This works, for
- * example, when using _DOMAINS and cHash for links that do not really
- * need a cHash.
- *
- * @var array
- */
- protected $additionalParametersForChash;
- /**
- * Actual host name (configuration key) for the current request. This can
- * be different from the $this->host if there are host aliases.
- *
- * @var string
- */
- protected $hostConfigured = '';
- var $multidomain = false;
- var $urlPrepend = array();
- var $useMySQLExtendedSyntax = false;
- /**
- * Holds a uid of the detected language during decoding to limit search of
- * titles only to this language. Valid values are:
- * -1 - no language detected
- * 0 - default language (only if really detected!)
- * >0 - a language uid taken from preVars or _DOMAINS (corresponds to uid in sys_languages table)
- *
- * @var int
- */
- protected $detectedLanguage = -1;
- /**
- * Inidicates wwether devLog is enabled
- *
- * @var true
- */
- protected $enableDevLog = false;
- /**
- * Contains a request id. This is to simplify identification of a single
- * request when the site is accessed concurently
- *
- * @var string
- */
- protected $devLogId;
- /**
- * Mime type that can be set according to the file extension (decoding only).
- *
- * @var string
- */
- protected $mimeType = null;
- var $enableStrictMode = false;
- var $enableChashDebug = false;
- /**
- * If non-empty, corresponding URL query parameter will be ignored in preVars
- * (note: preVars only!). This is necessary for _DOMAINS feature. This value
- * is set to empty in adjustConfigurationByHostEncode().
- *
- * @see tx_realurl::adjustConfigurationByHostEncode()
- * @see tx_realurl::encodeSpURL_doEncode()
- * @var string
- */
- protected $ignoreGETvar;
- /**
- * Contains URL parameters that were merged into URL. This is necessary
- * if cHash has to be recalculated due to bypassed parameters. Used during
- * encoding only.
- *
- * @var array
- * @see http://bugs.typo3.org/view.php?id=11219
- */
- protected $cHashParameters;
- /**
- * Indicates wether cHash should be rebuilt for the URL. Used during
- * encoding only.
- *
- * @var boolean
- * @see http://bugs.typo3.org/view.php?id=11219
- */
- protected $rebuildCHash;
- /************************************
- *
- * Translate parameters to a Speaking URL (t3lib_tstemplate::linkData)
- *
- ************************************/
- /**
- * Creates an instance of this class
- *
- * @return void
- */
- public function __construct() {
- if (!t3lib_extMgm::isLoaded('dbal') && strpos(get_resource_type($GLOBALS['TYPO3_DB']->link), 'mysql link') !== false) {
- $res = $GLOBALS['TYPO3_DB']->sql_query('SELECT @@VERSION');
- $rec = $GLOBALS['TYPO3_DB']->sql_fetch_row($res);
- $GLOBALS['TYPO3_DB']->sql_free_result($res);
- $this->useMySQLExtendedSyntax = version_compare($rec[0], '4.1.0', '>');
- }
- $sysconf = (array)unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['realurl']);
- $this->enableStrictMode = (boolean)$sysconf['enableStrictMode'];
- $this->enableChashUrlDebug = (boolean)$sysconf['enableChashUrlDebug'];
- $this->initDevLog($sysconf);
- }
- /**
- * Initializes devLog support
- *
- * @param array $sysconf
- * @return void
- */
- protected function initDevLog(array $sysconf) {
- $this->enableDevLog = (boolean)$sysconf['enableDevLog'];
- if ($this->enableDevLog) {
- $this->devLogId = (isset($_SERVER['UNIQUE_ID']) ? $_SERVER['UNIQUE_ID'] : uniqid(''));
- }
- }
- /**
- * Translates a URL with query string (GET parameters) into Speaking URL.
- * Called from t3lib_tstemplate::linkData
- *
- * @param array Array of parameters from t3lib_tstemplate::linkData - the function creating all links inside TYPO3
- * @return void
- */
- public function encodeSpURL(&$params) {
- $this->devLog('Entering encodeSpURL for ' . $params['LD']['totalURL']);
- if ($this->isInWorkspace()) {
- $this->devLog('Workspace detected. Not doing anything!');
- return;
- }
- if (!$params['TCEmainHook']) {
- // Return directly, if simulateStaticDocuments is set:
- if ($GLOBALS['TSFE']->config['config']['simulateStaticDocuments']) {
- $GLOBALS['TT']->setTSlogMessage('SimulateStaticDocuments is enabled. RealURL disables itself.', 2);
- return;
- }
- // Return directly, if realurl is not enabled:
- if (!$GLOBALS['TSFE']->config['config']['tx_realurl_enable']) {
- $GLOBALS['TT']->setTSlogMessage('RealURL is not enabled in TS setup. Finished.');
- return;
- }
- }
- // Checking prefix:
- $prefix = $GLOBALS['TSFE']->absRefPrefix . $this->prefixEnablingSpURL;
- if (substr($params['LD']['totalURL'], 0, strlen($prefix)) != $prefix) {
- return;
- }
- $this->devLog('Starting URL encode');
- // Initializing config / request URL:
- $this->setConfig();
- $adjustedConfiguration = $this->adjustConfigurationByHost('encode', $params);
- $this->adjustRootPageId();
- $internalExtras = array();
- // Init "Admin Jump"; If frontend edit was enabled by the current URL of the page, set it again in the generated URL (and disable caching!)
- if (!$params['TCEmainHook']) {
- if ($GLOBALS['TSFE']->applicationData['tx_realurl']['adminJumpActive']) {
- $GLOBALS['TSFE']->set_no_cache();
- $this->adminJumpSet = TRUE;
- $internalExtras['adminJump'] = 1;
- }
- // If there is a frontend user logged in, set fe_user_prefix
- if (is_array($GLOBALS['TSFE']->fe_user->user)) {
- $this->fe_user_prefix_set = TRUE;
- $internalExtras['feLogin'] = 1;
- }
- }
- // Parse current URL into main parts:
- $uParts = parse_url($params['LD']['totalURL']);
- // Look in memory cache first
- $urlData = $this->hostConfigured . ' | ' . $uParts['query'];
- $newUrl = $this->encodeSpURL_encodeCache($urlData, $internalExtras);
- if (!$newUrl) {
- // Encode URL
- $newUrl = $this->encodeSpURL_doEncode($uParts['query'], $this->extConf['init']['enableCHashCache'], $params['LD']['totalURL']);
- // Set new URL in cache
- $this->encodeSpURL_encodeCache($urlData, $internalExtras, $newUrl);
- }
- unset($urlData);
- // Adding any anchor there might be:
- if ($uParts['fragment']) {
- $newUrl .= '#' . $uParts['fragment'];
- }
- // Reapply config.absRefPrefix if necessary
- if ((!isset($this->extConf['init']['reapplyAbsRefPrefix']) || $this->extConf['init']['reapplyAbsRefPrefix']) && $GLOBALS['TSFE']->absRefPrefix) {
- // Prevent // in case of absRefPrefix ending with / and emptyUrlReturnValue=/
- if (substr($GLOBALS['TSFE']->absRefPrefix, -1, 1) == '/' && substr($newUrl, 0, 1) == '/') {
- $newUrl = substr($newUrl, 1);
- }
- $newUrl = $GLOBALS['TSFE']->absRefPrefix . $newUrl;
- }
- // Set prepending of URL (e.g. hostname) which will be processed by typoLink_PostProc hook in tslib_content:
- if (isset($adjustedConfiguration['urlPrepend']) && !isset($this->urlPrepend[$newUrl])) {
- $urlPrepend = $adjustedConfiguration['urlPrepend'];
- if (substr($urlPrepend, -1) == '/') {
- $urlPrepend = substr($urlPrepend, 0, -1);
- }
- $this->urlPrepend[$newUrl] = $urlPrepend;
- }
- // Call hooks
- if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']['encodeSpURL_postProc'])) {
- foreach($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']['encodeSpURL_postProc'] as $userFunc) {
- $hookParams = array(
- 'pObj' => &$this,
- 'params' => $params,
- 'URL' => &$newUrl,
- );
- t3lib_div::callUserFunction($userFunc, $hookParams, $this);
- }
- }
- // Setting the encoded URL in the LD key of the params array - that value is passed by reference and thus returned to the linkData function!
- $params['LD']['totalURL'] = $newUrl;
- }
- /**
- * Prepends URL generated by RealURL by something (e.g. a host).
- * This method gets called by the typoLink_PostProc hook in tslib_content:
- *
- * @param array $parameters: Array of parameters from typoLink_PostProc hook in tslib_content
- * @param object $cObj: Reference to the calling tslib_content instance
- * @return void
- */
- public function encodeSpURL_urlPrepend(&$parameters, &$pObj) {
- if (isset($parameters['finalTagParts']['url'])) {
- // We must check for absolute URLs here because typolink can force
- // absolute URLs for pages with restricted access. It prepends
- // current host always. See http://bugs.typo3.org/view.php?id=18200
- $testUrl = $parameters['finalTagParts']['url'];
- if (preg_match('/^https?:\/\/[^\/]+\//', $testUrl)) {
- $testUrl = preg_replace('/https?:\/\/[^\/]+(.+)$/', '\1', $testUrl);
- }
- if (isset($this->urlPrepend[$testUrl])) {
- $urlKey = $url = $testUrl;
- // Remove absRefPrefix if necessary
- $absRefPrefixLength = strlen($GLOBALS['TSFE']->absRefPrefix);
- if ($absRefPrefixLength != 0 && substr($url, 0, $absRefPrefixLength) == $GLOBALS['TSFE']->absRefPrefix) {
- $url = substr($url, $absRefPrefixLength);
- }
- $url = $this->urlPrepend[$urlKey] . ($url{0} != '/' ? '/' : '') . $url;
- unset($this->urlPrepend[$testUrl]);
- // Adjust the URL:
- $parameters['finalTag'] = str_replace(
- '"' . htmlspecialchars($parameters['finalTagParts']['url']) . '"',
- '"' . htmlspecialchars($url) . '"',
- $parameters['finalTag']
- );
- $parameters['finalTagParts']['url'] = $url;
- $pObj->lastTypoLinkUrl = $url;
- }
- }
- }
- /**
- * Transforms a query string into a speaking URL according to the configuration in ->extConf
- *
- * @param string Input query string
- * @param boolean If set, the cHashCache table is used for "&cHash"
- * @param string Original URL
- * @return string Output Speaking URL (with as many GET parameters encoded into the URL as possible).
- * @see encodeSpURL()
- */
- protected function encodeSpURL_doEncode($inputQuery, $cHashCache = FALSE, $origUrl = '') {
- $this->cHashParameters = array();
- $this->rebuildCHash = false;
- // Extract all GET parameters into an ARRAY:
- $paramKeyValues = array();
- $GETparams = explode('&', $inputQuery);
- foreach ($GETparams as $paramAndValue) {
- list($p, $v) = explode('=', $paramAndValue, 2);
- $p = rawurldecode($p);
- if ($p != '') {
- $paramKeyValues[$p] = rawurldecode($v);
- }
- }
- $this->orig_paramKeyValues = $paramKeyValues;
- // Init array in which to collect the "directories" of the URL:
- $pathParts = array();
- // Pre-vars:
- $this->encodeSpURL_setSequence($this->extConf['preVars'], $paramKeyValues, $pathParts);
- // Create path from ID value:
- $page_id = $this->encodePageId = $paramKeyValues['id'];
- $this->encodeError = FALSE;
- $this->encodeSpURL_pathFromId($paramKeyValues, $pathParts);
- if ($this->encodeError) {
- return $origUrl;
- }
- // Fixed Post-vars:
- $fixedPostVarSetCfg = $this->getPostVarSetConfig($page_id, 'fixedPostVars');
- if (is_array($fixedPostVarSetCfg)) {
- $this->encodeSpURL_setSequence($fixedPostVarSetCfg, $paramKeyValues, $pathParts);
- }
- // Post var sets:
- $postVarSetCfg = $this->getPostVarSetConfig($page_id);
- $this->encodeSpURL_gettingPostVarSets($paramKeyValues, $pathParts, $postVarSetCfg);
- // Compile Speaking URL path
- $pathParts = $this->cleanUpPathParts($pathParts);
- // Add filename, if any:
- $newUrl = $this->createURLWithFileName($paramKeyValues, $pathParts);
- // Fix empty URLs
- $newUrl = $this->fixEmptyUrl($newUrl);
- // Clear ignored var
- if (isset($paramKeyValues[$this->ignoreGETvar])) {
- unset($paramKeyValues[$this->ignoreGETvar]);
- }
- // Store cHash cache:
- if ($cHashCache) {
- $this->encodeSpURL_cHashCache($newUrl, $paramKeyValues);
- }
- // Manage remaining GET parameters:
- if (count($paramKeyValues)) {
- $q = array();
- foreach ($paramKeyValues as $k => $v) {
- $q[] = $this->rawurlencodeParam($k) . '=' . rawurlencode($v);
- }
- $newUrl .= '?' . implode('&', $q);
- }
- // Memory clean up
- unset($this->cHashParameters);
- // Return new, Speaking URL encoded URL:
- return $newUrl;
- }
- /**
- * Creating the TYPO3 Page path into $pathParts from the "id" value in $paramKeyValues
- *
- * @param array Current URLs GETvar => value pairs in array, being translated into pathParts: Here we take out "id" GET var.
- * @param array Numerical array of path-parts, continously being filled. Here, the "page path" is being added by which-ever method is preferred. Passed by reference.
- * @return void Unsetting "id" from $paramKeyValues / Setting page path in $pathParts
- * @see encodeSpURL_doEncode()
- */
- protected function encodeSpURL_pathFromId(&$paramKeyValues, &$pathParts) {
- // Return immediately if no GET vars remain to be translated:
- if (!count($paramKeyValues)) {
- return;
- }
- // Creating page path:
- switch ((string)$this->extConf['pagePath']['type']) {
- case 'user':
- $params = array('paramKeyValues' => &$paramKeyValues, 'pathParts' => &$pathParts, 'pObj' => &$this, 'conf' => $this->extConf['pagePath'], 'mode' => 'encode');
- t3lib_div::callUserFunction($this->extConf['pagePath']['userFunc'], $params, $this);
- break;
- default: // Default: Just passing through the ID/alias of the page:
- $pathParts[] = rawurlencode($paramKeyValues['id']);
- unset($paramKeyValues['id']);
- break;
- }
- }
- /**
- * Traversing setup for variables AFTER the page path.
- *
- * @param array Current URLs GETvar => value pairs in array, being translated into pathParts, continously shortend. Passed by reference.
- * @param array Numerical array of path-parts, continously being filled. Passed by reference.
- * @param array $postVarSetCfg config
- * @return void Removing values from $paramKeyValues / Setting values in $pathParts
- * @see encodeSpURL_doEncode(), decodeSpURL_settingPostVarSets()
- */
- protected function encodeSpURL_gettingPostVarSets(&$paramKeyValues, &$pathParts, $postVarSetCfg) {
- // Traverse setup for postVarSets. If any of those matches
- if (is_array($postVarSetCfg)) {
- foreach ($postVarSetCfg as $keyWord => $cfg) {
- switch ((string)$cfg['type']) {
- case 'admin':
- if ($this->adminJumpSet) {
- $pathParts[] = rawurlencode($keyWord);
- $this->adminJumpSet = FALSE; // ... this makes sure that any subsequent "admin-jump" activation is set...
- }
- break;
- case 'single':
- $this->encodeSpURL_setSingle($keyWord, $cfg['keyValues'], $paramKeyValues, $pathParts);
- break;
- default:
- unset($cfg['type']); // Just to make sure it is NOT set.
- foreach ($cfg as $Gcfg) {
- if (isset($paramKeyValues[$Gcfg['GETvar']])) {
- $pathParts[] = rawurlencode($keyWord);
- $pathPartsSize = count($pathParts);
- $cHashParameters = $this->cHashParameters;
- $this->encodeSpURL_setSequence($cfg, $paramKeyValues, $pathParts);
- // If (1) nothing was added or (2) only empty segments added, remove this part completely
- if (count($pathParts) == $pathPartsSize) {
- array_pop($pathParts);
- }
- else {
- $dropSegment = true;
- for ($i = $pathPartsSize; $i < count($pathParts); $i++) {
- if ($pathParts[$i] != '') {
- $dropSegment = false;
- break;
- }
- }
- if ($dropSegment) {
- $pathParts = array_slice($pathParts, 0, $pathPartsSize - 1);
- // Nothing goes to cHash from this part.
- $this->cHashParameters = $cHashParameters;
- }
- }
- break;
- }
- }
- break;
- }
- }
- }
- }
- /**
- * Setting a filename if any filename is configured to match remaining variables.
- *
- * @param array Current URLs GETvar => value pairs in array, being translated into pathParts, continously shortend. Passed by reference.
- * @return string Returns the filename to prepend, if any
- * @see encodeSpURL_doEncode(), decodeSpURL_fileName()
- */
- protected function encodeSpURL_fileName(array &$paramKeyValues) {
- // Look if any filename matches the remaining variables:
- if (is_array($this->extConf['fileName']['index'])) {
- foreach ($this->extConf['fileName']['index'] as $keyWord => $cfg) {
- $pathParts = array();
- if ($this->encodeSpURL_setSingle($keyWord, $cfg['keyValues'], $paramKeyValues, $pathParts)) {
- return $keyWord != '_DEFAULT' ? $keyWord : '';
- }
- }
- }
- return '';
- }
- /**
- * Traverses a set of GETvars configured (array of segments)
- *
- * @param array Array of segment-configurations.
- * @param array Current URLs GETvar => value pairs in array, being translated into pathParts, continously shortend. Passed by reference.
- * @param array Numerical array of path-parts, continously being filled. Passed by reference.
- * @return void Removing values from $paramKeyValues / Setting values in $pathParts
- * @see encodeSpURL_doEncode(), encodeSpURL_gettingPostVarSets(), decodeSpURL_getSequence()
- */
- protected function encodeSpURL_setSequence($varSetCfg, &$paramKeyValues, &$pathParts) {
- // Traverse array of segments configuration
- $prevVal = '';
- if (is_array($varSetCfg)) {
- foreach ($varSetCfg as $setup) {
- switch ($setup['type']) {
- case 'action':
- $pathPartVal = '';
- // Look for admin jump:
- if ($this->adminJumpSet) {
- foreach ($setup['index'] as $pKey => $pCfg) {
- if ((string)$pCfg['type'] == 'admin') {
- $pathPartVal = $pKey;
- $this->adminJumpSet = FALSE;
- break;
- }
- }
- }
- // Look for frontend user login:
- if ($this->fe_user_prefix_set) {
- foreach ($setup['index'] as $pKey => $pCfg) {
- if ((string)$pCfg['type'] == 'feLogin') {
- $pathPartVal = $pKey;
- $this->fe_user_prefix_set = FALSE;
- break;
- }
- }
- }
- // If either pathPartVal has been set OR if _DEFAULT type is not bypass, set a value:
- if (strlen($pathPartVal) || $setup['index']['_DEFAULT']['type'] != 'bypass') {
- // If admin jump did not set $pathPartVal, look for first pass-through (no "type" set):
- if (!strlen($pathPartVal)) {
- foreach ($setup['index'] as $pKey => $pCfg) {
- if (!strlen($pCfg['type'])) {
- $pathPartVal = $pKey;
- break;
- }
- }
- }
- // Setting part of path:
- $pathParts[] = rawurlencode(strlen($pathPartVal) ? $pathPartVal : $this->NA);
- }
- break;
- default:
- if (!is_array($setup['cond']) || $this->checkCondition($setup['cond'], $prevVal)) {
- // Looking if the GET var is found in parameter index
- $GETvar = $setup['GETvar'];
- if ($GETvar == $this->ignoreGETvar) {
- // Do not do anything with this var!
- continue;
- }
- $parameterSet = isset($paramKeyValues[$GETvar]);
- $GETvarVal = $parameterSet ? $paramKeyValues[$GETvar] : '';
- // Set reverse map:
- $revMap = is_array($setup['valueMap']) ? array_flip($setup['valueMap']) : array();
- if (isset($revMap[$GETvarVal])) {
- $prevVal = $GETvarVal;
- $pathParts[] = rawurlencode($revMap[$GETvarVal]);
- $this->cHashParameters[$GETvar] = $GETvarVal;
- } elseif ($setup['noMatch'] == 'bypass') {
- // If no match in reverse value map and "bypass" is set, remove the parameter from the URL
- // Must rebuild cHash because we remove a parameter!
- $this->rebuildCHash |= $parameterSet;
- } elseif ($setup['noMatch'] == 'null') {
- // If no match and "null" is set, then set "dummy" value
- // Set "dummy" value (?)
- $prevVal = '';
- $pathParts[] = '';
- $this->rebuildCHash |= $parameterSet;
- } elseif ($setup['userFunc']) {
- $params = array(
- 'pObj' => &$this,
- 'value' => $GETvarVal,
- 'decodeAlias' => false,
- 'pathParts' => &$pathParts
- );
- $prevVal = $GETvarVal;
- $GETvarVal = t3lib_div::callUserFunction($setup['userFunc'], $params, $this);
- $pathParts[] = rawurlencode($GETvarVal);
- $this->cHashParameters[$GETvar] = $prevVal;
- } elseif (is_array($setup['lookUpTable'])) {
- $prevVal = $GETvarVal;
- $GETvarVal = $this->lookUpTranslation($setup['lookUpTable'], $GETvarVal);
- $pathParts[] = rawurlencode($GETvarVal);
- $this->cHashParameters[$GETvar] = $prevVal;
- } elseif (isset($setup['valueDefault'])) {
- $prevVal = $setup['valueDefault'];
- $pathParts[] = rawurlencode($setup['valueDefault']);
- $this->cHashParameters[$GETvar] = $setup['valueMap'][$setup['valueDefault']];
- $this->rebuildCHash |= !$parameterSet;
- } else {
- $prevVal = $GETvarVal;
- $pathParts[] = rawurlencode($GETvarVal);
- $this->cHashParameters[$GETvar] = $prevVal;
- $this->rebuildCHash |= !$parameterSet;
- }
- // Finally, unset GET var so it doesn't get processed once more:
- unset($paramKeyValues[$setup['GETvar']]);
- }
- break;
- }
- }
- }
- }
- /**
- * Traversing an array of GETvar => value pairs and checking if both variable names AND values are matching any found in $paramKeyValues; If so, the keyword representing those values is set and the GEtvars are unset from $paramkeyValues array
- *
- * @param string Keyword to set as a representation of the GETvars configured.
- * @param array Array of GETvar => values which content in $paramKeyvalues must match exactly in order to be substituted with the keyword, $keyWord
- * @param array Current URLs GETvar => value pairs in array, being translated into pathParts, continously shortend. Passed by reference.
- * @param array Numerical array of path-parts, continously being filled. Passed by reference.
- * @return boolean Return true, if any value from $paramKeyValues was removed.
- * @see encodeSpURL_fileName(), encodeSpURL_gettingPostVarSets(), decodeSpURL_getSingle()
- */
- protected function encodeSpURL_setSingle($keyWord, $keyValues, &$paramKeyValues, &$pathParts) {
- if (is_array($keyValues)) {
- $allSet = TRUE;
- // Check if all GETvars configured are found in $paramKeyValues:
- foreach ($keyValues as $getVar => $value) {
- if (!isset($paramKeyValues[$getVar]) || strcmp($paramKeyValues[$getVar], $value)) {
- $allSet = FALSE;
- break;
- }
- }
- // If all is set, unset the GETvars and set the value.
- if ($allSet) {
- $pathParts[] = rawurlencode($keyWord);
- foreach ($keyValues as $getVar => $value) {
- $this->cHashParameters[$getVar] = $value;
- unset($paramKeyValues[$getVar]);
- }
- return TRUE;
- }
- }
- return FALSE;
- }
- /**
- * Setting / Getting encoded URL to/from cache (memory cache, but could be extended to database cache)
- *
- * @param string Host + the original URL with GET parameters - identifying the cached version to find
- * @param array Array with extra data to include in encoding. This is flags if adminJump url or feLogin flags are set since these are NOT a part of the URL to encode and therefore are needed for the hash to be true.
- * @param string If set, this URL will be cached as the encoded version of $urlToEncode. Otherwise the function will look for and return the cached version of $urlToEncode
- * @return mixed If $setEncodedURL is true, this will be STORED as the cached version and the function returns false, otherwise the cached version is returned (string).
- * @see encodeSpURL()
- */
- protected function encodeSpURL_encodeCache($urlData, $internalExtras, $setEncodedURL = '') {
- // Create hash string:
- $hash = md5($urlData . '///' . serialize($internalExtras));
- if (!$setEncodedURL) { // Asking for cached encoded URL:
- // First, check memory, otherwise ask database:
- if (!isset($GLOBALS['TSFE']->applicationData['tx_realurl']['_CACHE'][$hash]) && $this->extConf['init']['enableUrlEncodeCache']) {
- $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('content', 'tx_realurl_urlencodecache',
- 'url_hash=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($hash, 'tx_realurl_urlencodecache') .
- ' AND tstamp>' . strtotime('midnight', time() - 24 * 3600 * $this->encodeCacheTTL));
- if (false != ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))) {
- $GLOBALS['TSFE']->applicationData['tx_realurl']['_CACHE'][$hash] = $row['content'];
- }
- $GLOBALS['TYPO3_DB']->sql_free_result($res);
- }
- return $GLOBALS['TSFE']->applicationData['tx_realurl']['_CACHE'][$hash];
- }
- else { // Setting encoded URL in cache:
- // No caching if FE editing is enabled!
- if (!$this->isBEUserLoggedIn()) {
- $GLOBALS['TSFE']->applicationData['tx_realurl']['_CACHE'][$hash] = $setEncodedURL;
- // If the page id is NOT an integer, it's an alias we have to look up:
- if (!self::testInt($this->encodePageId)) {
- $this->encodePageId = $this->pageAliasToID($this->encodePageId);
- }
- if ($this->extConf['init']['enableUrlEncodeCache'] && $this->canCachePageURL($this->encodePageId)) {
- $insertFields = array(
- 'url_hash' => $hash,
- 'origparams' => $urlData,
- 'internalExtras' => count($internalExtras) ? serialize($internalExtras) : '',
- 'content' => $setEncodedURL,
- 'page_id' => $this->encodePageId,
- 'tstamp' => time()
- );
- if ($this->useMySQLExtendedSyntax) {
- $query = $GLOBALS['TYPO3_DB']->INSERTquery('tx_realurl_urlencodecache', $insertFields);
- $query .= ' ON DUPLICATE KEY UPDATE tstamp=' . $insertFields['tstamp'];
- $GLOBALS['TYPO3_DB']->sql_query($query);
- } else {
- $GLOBALS['TYPO3_DB']->sql_query('START TRANSACTION');
- $GLOBALS['TYPO3_DB']->exec_DELETEquery('tx_realurl_urlencodecache', 'url_hash=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($hash, 'tx_realurl_urlencodecache'));
- $GLOBALS['TYPO3_DB']->exec_INSERTquery('tx_realurl_urlencodecache', $insertFields);
- $GLOBALS['TYPO3_DB']->sql_query('COMMIT');
- }
- }
- }
- }
- return '';
- }
- /**
- * Will store a record in a cachetable holding the value of the "cHash" parameter in a link, if any.
- * Background:
- * The "cHash" parameter is a hash over the values in the Query String of a URL and it "authenticates" the URL to the frontend so we can safely cache page content with that parameter combination.
- * Technically, there is no problem with the "cHash" parameter - it is like any other parameter something we could encode with Speaking URLs. The problem is: a cHash string is not "speaking" (and never will be!)
- * So; the only option we are left with if we want to remove the "?cHash=...:" remains in URLs and at the same time do not want to include it in the virtual path is; store it in the database!
- * This is what this function does: Stores a record in the database which relates the cHash value to a hash id of the URL. This is done ONLY if the "cHash" parameter is the only one left which would make the URL non-speaking. Otherwise it is left behind.
- * Obviously, this whole thing only works if there is a function in the decode part which will look up the cHash again and include it in the GET parameters resolved from the Speaking URL - but there is of course...
- *
- * @param string Speaking URL path (being hashed to an integer and cHash value related to this.)
- * @param array Params array, passed by reference. If "cHash" is the only value left it will be put in the cache table and the value is unset in the array.
- * @return void
- * @see decodeSpURL_cHashCache()
- */
- protected function encodeSpURL_cHashCache($newUrl, &$paramKeyValues) {
- // If "cHash" is the ONLY parameter left...
- // (if there are others our problem is that the cHash probably covers those
- // as well and if we include the cHash anyways we might get duplicates for
- // the same speaking URL in the cache table!)
- if (isset($paramKeyValues['cHash'])) {
- if ($this->rebuildCHash) {
- $cHashParameters = array_merge($this->cHashParameters, $paramKeyValues);
- unset($cHashParameters['cHash']);
- $cHashParameters = t3lib_div::cHashParams(t3lib_div::implodeArrayForUrl('', $cHashParameters));
- unset($cHashParameters['']);
- if (count($cHashParameters) == 1) {
- // No cHash needed.
- unset($paramKeyValues['cHash']);
- }
- elseif (count($cHashParameters) > 1) {
- if (method_exists('t3lib_div', 'calculateCHash')) {
- $paramKeyValues['cHash'] = t3lib_div::calculateCHash($cHashParameters);
- }
- else {
- $paramKeyValues['cHash'] = t3lib_div::shortMD5(serialize($cHashParameters));
- }
- }
- unset($cHashParameters);
- }
- if (count($paramKeyValues) == 1) {
- $stringForHash = $newUrl;
- if (count($this->additionalParametersForChash)) {
- $stringForHash .= '|' . serialize($this->additionalParametersForChash);
- }
- $spUrlHash = md5($stringForHash);
- $spUrlHashQuoted = $GLOBALS['TYPO3_DB']->fullQuoteStr($spUrlHash, 'tx_realurl_chashcache');
- // first, look if a cHash is already there for this SpURL
- list($row) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('chash_string',
- 'tx_realurl_chashcache', 'spurl_hash=' . $spUrlHashQuoted);
- if (!is_array($row)) {
- // Nothing found, insert to the cache
- $data = array(
- 'spurl_hash' => $spUrlHash,
- 'spurl_string' => $this->enableChashUrlDebug ? $stringForHash : null,
- 'chash_string' => $paramKeyValues['cHash']
- );
- $GLOBALS['TYPO3_DB']->exec_INSERTquery('tx_realurl_chashcache', $data);
- }
- else {
- // If one found, check if it is different, and if so update:
- if ($row['chash_string'] != $paramKeyValues['cHash']) {
- // If that chash_string is different from the one we want to
- // insert, that might be a bug or mean that encryptionKey was
- // changed so cHash values will be different now
- // In any case we will just silently update the value:
- $data = array(
- 'chash_string' => $paramKeyValues['cHash']
- );
- $GLOBALS['TYPO3_DB']->exec_UPDATEquery('tx_realurl_chashcache',
- 'spurl_hash=' . $spUrlHashQuoted, $data);
- }
- }
- // Unset "cHash" (and array should now be empty!)
- unset($paramKeyValues['cHash']);
- }
- }
- }
- /************************************
- *
- * Translate a Speaking URL to parameters (tslib_fe)
- *
- ************************************/
- /**
- * Parse speaking URL and translate it to parameters understood by TYPO3
- * Function is called from tslib_fe
- * The overall format of a speaking URL is these five parts [TYPO3_SITE_URL] / [pre-var] / [page-identification] / [post-vars] / [file.ext]
- * - "TYPO3_SITE_URL" is fixed value from the environment,
- * - "pre-var" is any number of segments separated by "/" mapping to GETvars AND with a known lenght,
- * - "page-identification" identifies the page id in TYPO3 possibly with multiple segments separated by "/" BUT with an UNKNOWN length,
- * - "post-vars" is sets of segments offering the same features as "pre-var"
- * - "file.ext" is any filename that might apply
- *
- * @param array Params for hook
- * @return void Setting internal variables.
- */
- public function decodeSpURL($params) {
- $this->devLog('Entering decodeSpURL');
- // Setting parent object reference (which is $GLOBALS['TSFE'])
- $this->pObj = &$params['pObj'];
- // Initializing config / request URL:
- $this->setConfig();
- $this->adjustConfigurationByHost('decode');
- $this->adjustRootPageId();
- // If there has been a redirect (basically; we arrived here otherwise than via "index.php" in the URL) this can happend either due to a CGI-script or because of reWrite rule. Earlier we used $GLOBALS['HTTP_SERVER_VARS']['REDIRECT_URL'] to check but...
- if ($this->pObj->siteScript && substr($this->pObj->siteScript, 0, 9) != 'index.php' && substr($this->pObj->siteScript, 0, 1) != '?') {
- // Getting the path which is above the current site url:
- // For instance "first/second/third/index.html?¶m1=value1¶m2=value2"
- // should be the result of the URL
- // "http://localhost/typo3/dev/dummy_1/first/second/third/index.html?¶m1=value1¶m2=value2"
- // Note: sometimes in fcgi installations it is absolute, so we have to make it
- // relative to work properly.
- $speakingURIpath = $this->pObj->siteScript{0} == '/' ? substr($this->pObj->siteScript, 1) : $this->pObj->siteScript;
- // Call hooks
- if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']['decodeSpURL_preProc'])) {
- foreach($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']['decodeSpURL_preProc'] as $userFunc) {
- $hookParams = array(
- 'pObj' => &$this,
- 'params' => $params,
- 'URL' => &$speakingURIpath,
- );
- t3lib_div::callUserFunction($userFunc, $hookParams, $this);
- }
- }
- // Append missing slash if configured for:
- if ($this->extConf['init']['appendMissingSlash']) {
- $regexp = '~^([^\?]*[^/])(\?.*)?$~';
- if (substr($speakingURIpath, -1, 1) == '?') {
- $speakingURIpath = substr($speakingURIpath, 0, -1);
- }
- if (preg_match($regexp, $speakingURIpath)) { // Only process if a slash is missing:
- $options = t3lib_div::trimExplode(',', $this->extConf['init']['appendMissingSlash'], true);
- if (in_array('ifNotFile', $options)) {
- if (!preg_match('/\/[^\/\?]+\.[^\/]+(\?.*)?$/', '/' . $speakingURIpath)) {
- $speakingURIpath = preg_replace($regexp, '\1/\2', $speakingURIpath);
- $this->appendedSlash = true;
- }
- }
- else {
- $speakingURIpath = preg_replace($regexp, '\1/\2', $speakingURIpath);
- $this->appendedSlash = true;
- }
- if ($this->appendedSlash && count($options) > 0) {
- foreach ($options as $option) {
- $matches = array();
- if (preg_match('/^redirect(\[(30[1237])\])?$/', $option, $matches)) {
- $code = count($matches) > 1 ? $matches[2] : 301;
- $status = 'HTTP/1.0 ' . $code . ' TYPO3 RealURL redirect';
- // Check path segment to be relative for the current site.
- // parse_url() does not work with relative URLs, so we use it to test
- if (!@parse_url($speakingURIpath, PHP_URL_HOST)) {
- @ob_end_clean();
- header($status);
- header('Location: ' . t3lib_div::locationHeaderUrl($speakingURIpath));
- exit;
- }
- }
- }
- }
- }
- }
- // If the URL is a single script like "123.1.html" it might be an "old" simulateStaticDocument request. If this is the case and support for this is configured, do NOT try and resolve it as a Speaking URL
- $fI = t3lib_div::split_fileref($speakingURIpath);
- if (!self::testInt($this->pObj->id) && $fI['path'] == '' && $this->extConf['fileName']['defaultToHTMLsuffixOnPrev'] && $this->extConf['init']['respectSimulateStaticURLs']) {
- // If page ID does not exist yet and page is on the root level and both
- // respectSimulateStaticURLs and defaultToHTMLsuffixOnPrev are set, than
- // ignore respectSimulateStaticURLs and attempt to resolve page id.
- // See http://bugs.typo3.org/view.php?id=1530
- $GLOBALS['TT']->setTSlogMessage('decodeSpURL: ignoring respectSimulateStaticURLs due defaultToHTMLsuffixOnPrev for the root level page!)', 2);
- $this->extConf['init']['respectSimulateStaticURLs'] = false;
- }
- if (!$this->extConf['init']['respectSimulateStaticURLs'] || $fI['path']) {
- $this->devLog('RealURL powered decoding (TM) starting!');
- // Parse path:
- $uParts = @parse_url($speakingURIpath);
- if (!is_array($uParts)) {
- $this->decodeSpURL_throw404('Current URL is invalid');
- }
- $speakingURIpath = $this->speakingURIpath_procValue = $uParts['path'];
- // Redirecting if needed (exits if so).
- $this->decodeSpURL_checkRedirects($speakingURIpath);
- // Looking for cached information:
- $cachedInfo = $this->decodeSpURL_decodeCache($speakingURIpath);
- // If no cached info was found, create it:
- if (!is_array($cachedInfo)) {
- // Decode URL:
- $cachedInfo = $this->decodeSpURL_doDecode($speakingURIpath, $this->extConf['init']['enableCHashCache']);
- // Storing cached information:
- $this->decodeSpURL_decodeCache($speakingURIpath, $cachedInfo);
- }
- // Re-create QUERY_STRING from Get vars for use with typoLink()
- $_SERVER['QUERY_STRING'] = $this->decodeSpURL_createQueryString($cachedInfo['GET_VARS']);
- // Jump-admin if configured:
- $this->decodeSpURL_jumpAdmin_goBackend($cachedInfo['id']);
- // Setting info in TSFE:
- $this->pObj->mergingWithGetVars($cachedInfo['GET_VARS']);
- $this->pObj->id = $cachedInfo['id'];
- if ($this->mimeType) {
- header('Content-type: ' . $this->mimeType);
- $this->mimeType = null;
- }
- }
- }
- }
- /**
- * Look for redirect configuration.
- * If the input path is found as key in $this->extConf['redirects'] this method redirects to the URL found as value
- *
- * @param string Path from SpeakingURL.
- * @return void
- * @see decodeSpURL_doDecode()
- */
- protected function decodeSpURL_checkRedirects($speakingURIpath) {
- $speakingURIpath = strtolower(trim($speakingURIpath));
- if (isset($this->extConf['redirects'][$speakingURIpath])) {
- $url = $this->extConf['redirects'][$speakingURIpath];
- if (preg_match('/^30[1237];/', $url)) {
- $redirectCode = intval(substr($url, 0, 3));
- $url = substr($url, 4);
- header('HTTP/1.0 ' . $redirectCode . ' Redirect');
- }
- header('Location: ' . t3lib_div::locationHeaderUrl($url));
- exit();
- }
- // Regex redirects:
- if (is_array($this->extConf['redirects_regex'])) {
- foreach ($this->extConf['redirects_regex'] as $regex => $substString) {
- if (preg_match('/' . $regex . '/', $speakingURIpath)) {
- $url = @preg_replace('/' . $regex . '/', $substString, $speakingURIpath);
- if ($url) {
- if (preg_match('/^30[1237];/', $url)) {
- $redirectCode = intval(substr($url, 0, 3));
- header('HTTP/1.0 ' . $redirectCode . ' Redirect');
- $url = substr($url, 4);
- }
- header('Location: ' . t3lib_div::locationHeaderUrl($url));
- exit();
- }
- }
- }
- }
- // DB defined redirects:
- $hash = t3lib_div::md5int($speakingURIpath);
- $url = $GLOBALS['TYPO3_DB']->fullQuoteStr($speakingURIpath, 'tx_realurl_redirects');
- $domainId = $this->getCurrentDomainId();
- list($redirectRow) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
- 'destination,has_moved,domain_limit', 'tx_realurl_redirects',
- 'url_hash=' . $hash . ' AND url=' . $url . ' AND domain_limit IN (0,' . $domainId . ')',
- '', 'domain_limit DESC');
- if (is_array($redirectRow)) {
- // Update statistics
- $fields_values = array(
- 'counter' => 'counter+1',
- 'tstamp' => time(),
- 'last_referer' => t3lib_div::getIndpEnv('HTTP_REFERER')
- );
- $GLOBALS['TYPO3_DB']->exec_UPDATEquery('tx_realurl_redirects',
- 'url_hash=' . $hash . ' AND url=' . $url . ' AND domain_limit=' . $redirectRow['domain_limit'],
- $fields_values, array('counter'));
- // Redirect
- if ($redirectRow['has_moved']) {
- header('HTTP/1.1 301 Moved Permanently');
- }
- header('Location: ' . t3lib_div::locationHeaderUrl($redirectRow['destination']));
- exit();
- }
- }
- /**
- * Obtains current domain id from sys_domain.
- *
- * @return int
- */
- protected function getCurrentDomainId() {
- list($row) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid',
- 'sys_domain',
- 'domainName=' . $GLOBALS['TYPO3_DB']->fullQuoteStr(t3lib_div::getIndpEnv('HTTP_HOST'), 'sys_domain') .
- ' AND redirectTo=\'\''
- );
- $result = (is_array($row) ? intval($row['uid']) : 0);
- return $result;
- }
- /**
- * Decodes a speaking URL path into an array of GET parameters and a page id.
- *
- * @param string Speaking URL path (after the "root" path of the website!) but without query parameters
- * @param boolean If cHash caching is enabled or not.
- * @return array Array with id and GET parameters.
- * @see decodeSpURL()
- */
- protected function decodeSpURL_doDecode($speakingURIpath, $cHashCache = FALSE) {
- // Cached info:
- $cachedInfo = array();
- // Convert URL to segments
- $pathParts = explode('/', $speakingURIpath);
- array_walk($pathParts, create_function('&$value', '$value = rawurldecode($value);'));
- // Strip/process file name or extension first
- $file_GET_VARS = $this->decodeSpURL_decodeFileName($pathParts);
- // Setting original dir-parts:
- $this->dirParts = $pathParts;
- // Setting "preVars":
- $pre_GET_VARS = $this->decodeSpURL_settingPreVars($pathParts, $this->extConf['preVars']);
- if (isset($this->extConf['pagePath']['languageGetVar'])) {
- $languageGetVar = $this->extConf['pagePath']['languageGetVar'];
- if (isset($pre_GET_VARS[$languageGetVar]) && self::testInt($pre_GET_VARS[$languageGetVar])) {
- // Language from URL
- $this->detectedLanguage = $pre_GET_VARS[$languageGetVar];
- }
- elseif (isset($_GET[$languageGetVar]) && self::testInt($_GET[$languageGetVar])) {
- // This is for _DOMAINS feature
- $this->detectedLanguage = $_GET[$languageGetVar];
- }
- }
- // Setting page id:
- list($cachedInfo['id'], $id_GET_VARS, $cachedInfo['rootpage_id']) = $this->decodeSpURL_idFromPath($pathParts);
- // Fixed Post-vars:
- $fixedPostVarSetCfg = $this->getPostVarSetConfig($cachedInfo['id'], 'fixedPostVars');
- $fixedPost_GET_VARS = $this->decodeSpURL_settingPreVars($pathParts, $fixedPostVarSetCfg);
- // Setting "postVarSets":
- $postVarSetCfg = $this->getPostVarSetConfig($cachedInfo['id']);
- $post_GET_VARS = $this->decodeSpURL_settingPostVarSets($pathParts, $postVarSetCfg, $cachedInfo['id']);
- // Looking for remaining parts:
- if (count($pathParts)) {
- $this->decodeSpURL_throw404('"' . $speakingURIpath . '" could not be found, closest page matching is ' . substr(implode('/', $this->dirParts), 0, -strlen(implode('/', $pathParts))) . '');
- }
- // Merge Get vars together:
- $cachedInfo['GET_VARS'] = array();
- if (is_array($pre_GET_VARS))
- $cachedInfo['GET_VARS'] = t3lib_div::array_merge_recursive_overrule($cachedInfo['GET_VARS'], $pre_GET_VARS);
- if (is_array($id_GET_VARS))
- $cachedInfo['GET_VARS'] = t3lib_div::array_merge_recursive_overrule($cachedInfo['GET_VARS'], $id_GET_VARS);
- if (is_array($fixedPost_GET_VARS))
- $cachedInfo['GET_VARS'] = t3lib_div::array_merge_recursive_overrule($cachedInfo['GET_VARS'], $fixedPost_GET_VARS);
- if (is_array($post_GET_VARS))
- $cachedInfo['GET_VARS'] = t3lib_div::array_merge_recursive_overrule($cachedInfo['GET_VARS'], $post_GET_VARS);
- if (is_array($file_GET_VARS))
- $cachedInfo['GET_VARS'] = t3lib_div::array_merge_recursive_overrule($cachedInfo['GET_VARS'], $file_GET_VARS);
- // cHash handling:
- if ($cHashCache) {
- $cHash_value = $this->decodeSpURL_cHashCache($speakingURIpath);
- if ($cHash_value) {
- $cachedInfo['GET_VARS']['cHash'] = $cHash_value;
- }
- }
- // Return information found:
- return $cachedInfo;
- }
- /**
- * Generates a parameter string from an array recursively
- *
- * @param array Array to generate strings from
- * @param string path to prepend to every parameter
- * @return array Array with parameter strings
- */
- protected function decodeSpURL_createQueryStringParam($paramArr, $prependString = '') {
- if (!is_array($paramArr)) {
- return array($prependString . '=' . $paramArr);
- }
- if (count($paramArr) == 0) {
- return array();
- }
- $paramList = array();
- foreach ($paramArr as $var => $value) {
- $paramList = array_merge($paramList, $this->decodeSpURL_createQueryStringParam($value, $prependString . '[' . $var . ']'));
- }
- return $paramList;
- }
- /**
- * Re-creates QUERY_STRING for use with typoLink()
- *
- * @param array List of Get vars
- * @return string QUERY_STRING value
- */
- protected function decodeSpURL_createQueryString(&$getVars) {
- if (!is_array($getVars) …
Large files files are truncated, but you can click here to view the full file