/** * 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 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); $this->apiWrapper->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 = $this->apiWrapper->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.1 ' . $code . ' TYPO3 RealURL redirect M' . __LINE__; // 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: ' . $this->apiWrapper->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 = $this->apiWrapper->split_fileref($speakingURIpath); if (!$this->apiWrapper->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 /** @noinspection PhpUndefinedMethodInspection */ $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; } } } }