|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2011 Kasper Skårhøj <kasperYYYY@typo3.com> 00006 * (c) 2008-2011 Benjamin Mack <benni . typo3 . o)rg> 00007 * All rights reserved 00008 * 00009 * This script is part of the TYPO3 project. The TYPO3 project is 00010 * free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * The GNU General Public License can be found at 00016 * http://www.gnu.org/copyleft/gpl.html. 00017 * A copy is found in the textfile GPL.txt and important notices to the license 00018 * from the author is found in LICENSE.txt distributed with these scripts. 00019 * 00020 * 00021 * This script is distributed in the hope that it will be useful, 00022 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00024 * GNU General Public License for more details. 00025 * 00026 * This copyright notice MUST APPEAR in all copies of the script! 00027 ***************************************************************/ 00028 /** 00029 * Class that does the simulatestatic feature (Speaking URLs) 00030 * Was extracted for TYPO3 4.3 from the core 00031 * 00032 * $Id: class.tx_simulatestatic.php 10120 2011-01-18 20:03:36Z ohader $ 00033 * 00034 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00035 * @author Benjamin Mack <benni . typo3 . o)rg> 00036 */ 00037 class tx_simulatestatic { 00038 public $enabled = false; 00039 public $replacementChar = ''; 00040 public $conf = array(); 00041 public $pEncodingAllowedParamNames = array(); 00042 00043 /** 00044 * Initializes the extension, sets some configuration options and does some basic checks 00045 * 00046 * @param array holds all the information about the link that is about to be created 00047 * @param tslib_fe is a reference to the parent object that calls the hook 00048 * @return void 00049 */ 00050 public function hookInitConfig(array &$parameters, tslib_fe &$parentObject) { 00051 $TSconf = &$parameters['config']; 00052 00053 // if .simulateStaticDocuments was not present, the installation-wide default value will be used 00054 if (!isset($TSconf['simulateStaticDocuments'])) { 00055 $TSconf['simulateStaticDocuments'] = trim($parentObject->TYPO3_CONF_VARS['FE']['simulateStaticDocuments']); 00056 } 00057 00058 // simulateStatic was not activated 00059 if (!$TSconf['simulateStaticDocuments']) { 00060 return; 00061 } 00062 00063 $this->enabled = true; 00064 00065 // setting configuration options 00066 $this->conf = array( 00067 'mode' => $TSconf['simulateStaticDocuments'], 00068 'dontRedirectPathInfoError' => ($TSconf['simulateStaticDocuments_dontRedirectPathInfoError'] ? $TSconf['simulateStaticDocuments_dontRedirectPathInfoError'] : $TSconf['simulateStaticDocuments.']['dontRedirectPathInfoError']), 00069 'pEncoding' => ($TSconf['simulateStaticDocuments_pEnc'] ? $TSconf['simulateStaticDocuments_pEnc'] : $TSconf['simulateStaticDocuments.']['pEncoding']), 00070 'pEncodingOnlyP' => ($TSconf['simulateStaticDocuments_pEnc_onlyP'] ? $TSconf['simulateStaticDocuments_pEnc_onlyP'] : $TSconf['simulateStaticDocuments.']['pEncoding_onlyP']), 00071 'addTitle' => ($TSconf['simulateStaticDocuments_addTitle'] ? $TSconf['simulateStaticDocuments_addTitle'] : $TSconf['simulateStaticDocuments.']['addTitle']), 00072 'noTypeIfNoTitle' => ($TSconf['simulateStaticDocuments_noTypeIfNoTitle'] ? $TSconf['simulateStaticDocuments_noTypeIfNoTitle'] : $TSconf['simulateStaticDocuments.']['noTypeIfNoTitle']), 00073 'replacementChar' => (t3lib_div::compat_version('4.0') ? '-' : '_') 00074 ); 00075 00076 if ($this->conf['pEncodingOnlyP']) { 00077 $tempParts = t3lib_div::trimExplode(',', $this->conf['pEncodingOnlyP'], 1); 00078 foreach ($tempParts as $tempPart) { 00079 $this->pEncodingAllowedParamNames[$tempPart] = 1; 00080 } 00081 } 00082 00083 00084 // Checks and sets replacement character for simulateStaticDocuments. 00085 $replacement = trim($TSconf['simulateStaticDocuments_replacementChar'] ? $TSconf['simulateStaticDocuments_replacementChar'] : $TSconf['simulateStaticDocuments.']['replacementChar']); 00086 if ($replacement && (urlencode($replacement) == $replacement)) { 00087 $this->conf['replacementChar'] = $replacement; 00088 } 00089 00090 // Force absRefPrefix to this value is PATH_INFO is used. 00091 $absRefPrefix = $TSconf['absRefPrefix']; 00092 $absRefPrefix = trim($absRefPrefix); 00093 if ((!strcmp($this->conf['mode'], 'PATH_INFO') || $parentObject->absRefPrefix_force) && !$absRefPrefix) { 00094 $absRefPrefix = t3lib_div::dirname(t3lib_div::getIndpEnv('SCRIPT_NAME')) . '/'; 00095 } 00096 $parentObject->absRefPrefix = $absRefPrefix; 00097 $parentObject->config['config']['absRefPrefix'] = $absRefPrefix; 00098 00099 00100 // Check PATH_INFO url 00101 if ($parentObject->absRefPrefix_force && strcmp($this->conf['mode'], 'PATH_INFO')) { 00102 $redirectUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_DIR') . 'index.php?id=' . $parentObject->id . '&type='.$parentObject->type; 00103 if ($this->conf['dontRedirectPathInfoError']) { 00104 if ($parentObject->checkPageUnavailableHandler()) { 00105 $parentObject->pageUnavailableAndExit('PATH_INFO was not configured for this website, and the URL tries to find the page by PATH_INFO!'); 00106 } else { 00107 $message = 'PATH_INFO was not configured for this website, and the URL tries to find the page by PATH_INFO!'; 00108 header(t3lib_utility_Http::HTTP_STATUS_503); 00109 t3lib_div::sysLog($message, 'cms', t3lib_div::SYSLOG_SEVERITY_ERROR); 00110 $message = 'Error: PATH_INFO not configured: ' . $message . '<br /><br /><a href="' . htmlspecialchars($redirectUrl) . '">Click here to get to the right page.</a>'; 00111 throw new RuntimeException($message); 00112 } 00113 } else { 00114 t3lib_utility_Http::redirect($redirectUrl); 00115 } 00116 exit; 00117 // Set no_cache if PATH_INFO is NOT used as simulateStaticDoc. 00118 // and if absRefPrefix_force shows that such an URL has been passed along. 00119 // $this->set_no_cache(); 00120 } 00121 } 00122 00123 00124 /** 00125 * Hook for creating a speaking URL when using the generic linkData function 00126 * 00127 * @param array holds all the information about the link that is about to be created 00128 * @param t3lib_TStemplate is a reference to the parent object that calls the hook 00129 * @return void 00130 */ 00131 public function hookLinkDataPostProc(array &$parameters, t3lib_TStemplate &$parentObject) { 00132 if (!$this->enabled) { 00133 return; 00134 } 00135 00136 $LD = &$parameters['LD']; 00137 $page = &$parameters['args']['page']; 00138 $LD['type'] = ''; 00139 00140 // MD5/base64 method limitation 00141 $remainLinkVars = ''; 00142 $flag_pEncoding = (t3lib_div::inList('md5,base64', $this->conf['pEncoding']) && !$LD['no_cache']); 00143 if ($flag_pEncoding) { 00144 list($LD['linkVars'], $remainLinkVars) = $this->processEncodedQueryString($LD['linkVars']); 00145 } 00146 00147 $url = $this->makeSimulatedFileName( 00148 $page['title'], 00149 ($page['alias'] ? $page['alias'] : $page['uid']), 00150 intval($parameters['typeNum']), 00151 $LD['linkVars'], 00152 ($LD['no_cache'] ? true : false) 00153 ); 00154 if ($this->conf['mode'] == 'PATH_INFO') { 00155 $url = 'index.php/' . str_replace('.', '/', $url) . '/'; 00156 } else { 00157 $url .= '.html'; 00158 } 00159 $LD['url'] = $GLOBALS['TSFE']->absRefPrefix . $url . '?'; 00160 00161 if ($flag_pEncoding) { 00162 $LD['linkVars'] = $remainLinkVars; 00163 } 00164 00165 // If the special key 'sectionIndex_uid' (added 'manually' in tslib/menu.php to the page-record) is set, 00166 // then the link jumps directly to a section on the page. 00167 $LD['sectionIndex'] = ($page['sectionIndex_uid'] ? '#c'.$page['sectionIndex_uid'] : ''); 00168 00169 // Compile the normal total url 00170 $LD['totalURL'] = $parentObject->removeQueryString($LD['url'] . $LD['type'] . $LD['no_cache'] . $LD['linkVars'] . $GLOBALS['TSFE']->getMethodUrlIdToken) . $LD['sectionIndex']; 00171 } 00172 00173 00174 /** 00175 * Hook for checking to see if the URL is a speaking URL 00176 * 00177 * Here a .htaccess file maps all .html-files to index.php and 00178 * then we extract the id and type from the name of that HTML-file. (AKA "simulateStaticDocuments") 00179 * Support for RewriteRule to generate (simulateStaticDocuments) 00180 * With the mod_rewrite compiled into apache, put these lines into a .htaccess in this directory: 00181 * RewriteEngine On 00182 * RewriteRule ^[^/]*\.html$ index.php 00183 * The url must end with '.html' and the format must comply with either of these: 00184 * 1: '[title].[id].[type].html' - title is just for easy recognition in the 00185 * logfile!; no practical use of the title for TYPO3. 00186 * 2: '[id].[type].html' - above, but title is omitted; no practical use of 00187 * the title for TYPO3. 00188 * 3: '[id].html' - only id, type is set to the default, zero! 00189 * NOTE: In all case 'id' may be the uid-number OR the page alias (if any) 00190 * 00191 * @param array includes a reference to the parent Object (which is the global TSFE) 00192 * @param tslib_fe is a reference to the global TSFE 00193 * @return void 00194 */ 00195 public function hookCheckAlternativeIDMethods(array &$parameters, tslib_fe &$parentObject) { 00196 // If there has been a redirect (basically; we arrived here otherwise 00197 // than via "index.php" in the URL) 00198 // this can happend either due to a CGI-script or because of reWrite rule. 00199 // Earlier we used $_SERVER['REDIRECT_URL'] to check 00200 if ($parentObject->siteScript && substr($parentObject->siteScript, 0, 9) != 'index.php') { 00201 $uParts = parse_url($parentObject->siteScript); 00202 $fI = t3lib_div::split_fileref($uParts['path']); 00203 00204 if (!$fI['path'] && $fI['file'] && substr($fI['file'], -5) == '.html') { 00205 $parts = explode('.', $fI['file']); 00206 $pCount = count($parts); 00207 if ($pCount > 2) { 00208 $parentObject->type = intval($parts[$pCount-2]); 00209 $parentObject->id = $parts[$pCount-3]; 00210 } else { 00211 $parentObject->type = 0; 00212 $parentObject->id = $parts[0]; 00213 } 00214 } 00215 } 00216 00217 // If PATH_INFO is defined as simulateStaticDocuments mode and has information: 00218 if (t3lib_div::getIndpEnv('PATH_INFO') && strpos(t3lib_div::getIndpEnv('TYPO3_SITE_SCRIPT'), 'index.php/') === 0) { 00219 $parts = t3lib_div::trimExplode('/', t3lib_div::getIndpEnv('PATH_INFO'), true); 00220 $pCount = count($parts); 00221 if ($pCount > 1) { 00222 $parentObject->type = intval($parts[$pCount-1]); 00223 $parentObject->id = $parts[$pCount-2]; 00224 } else { 00225 $parentObject->type = 0; 00226 $parentObject->id = $parts[0]; 00227 } 00228 $parentObject->absRefPrefix_force = 1; 00229 } 00230 } 00231 00232 00233 /** 00234 * Analyzes the second part of a id-string (after the "+"), looking for B6 or M5 encoding 00235 * and if found it will resolve it and restore the variables in global $_GET. 00236 * If values for ->cHash, ->no_cache, ->jumpurl and ->MP is found, 00237 * they are also loaded into the internal vars of this class. 00238 * => Not yet used, could be ported from tslib_fe as well 00239 * 00240 * @param string String to analyze 00241 * @return void 00242 */ 00243 protected function idPartsAnalyze($string) { 00244 $getVars = ''; 00245 switch (substr($string, 0, 2)) { 00246 case 'B6': 00247 $addParams = base64_decode(str_replace('_', '=', str_replace('-', '/', substr($string, 2)))); 00248 parse_str($addParams, $getVars); 00249 break; 00250 case 'M5': 00251 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('params', 'cache_md5params', 'md5hash=' . $GLOBALS['TYPO3_DB']->fullQuoteStr(substr($string, 2), 'cache_md5params')); 00252 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 00253 00254 $GLOBALS['TSFE']->updateMD5paramsRecord(substr($string, 2)); 00255 parse_str($row['params'], $getVars); 00256 break; 00257 } 00258 $GLOBALS['TSFE']->mergingWithGetVars($getVars); 00259 } 00260 00261 00262 00263 00264 /******************************************** 00265 * 00266 * Various internal API functions 00267 * 00268 *******************************************/ 00269 00270 /** 00271 * This is just a wrapper function to use the params from the array split up. Can be deleted once the function in class.t3lib_fe.php is deleted 00272 * 00273 * @param array Parameter array delivered from tslib_fe::makeSimulFileName 00274 * @param tslib_fe Reference to the calling TSFE instance 00275 * @return string The body of the filename. 00276 * @see makeSimulatedFileName() 00277 * @deprecated since TYPO3 4.3, will be deleted in TYPO3 4.6 00278 */ 00279 public function makeSimulatedFileNameCompat(array &$parameters, tslib_fe &$parentObject) { 00280 t3lib_div::logDeprecatedFunction(); 00281 00282 return $this->makeSimulatedFileName( 00283 $parameters['inTitle'], 00284 $parameters['page'], 00285 $parameters['type'], 00286 $parameters['addParams'], 00287 $parameters['no_cache'] 00288 ); 00289 } 00290 00291 00292 /** 00293 * Make simulation filename (without the ".html" ending, only body of filename) 00294 * 00295 * @param string The page title to use 00296 * @param mixed The page id (integer) or alias (string) 00297 * @param integer The type number 00298 * @param string Query-parameters to encode (will be done only if caching is enabled and TypoScript configured for it. I don't know it this makes much sense in fact...) 00299 * @param boolean The "no_cache" status of the link. 00300 * @return string The body of the filename. 00301 * @see getSimulFileName(), t3lib_tstemplate::linkData(), tslib_frameset::frameParams() 00302 */ 00303 public function makeSimulatedFileName($inTitle, $page, $type, $addParams = '', $no_cache = false) { 00304 // Default value is 30 but values > 1 will be override this 00305 $titleChars = intval($this->conf['addTitle']); 00306 if ($titleChars == 1) { 00307 $titleChars = 30; 00308 } 00309 00310 $out = ($titleChars ? $this->fileNameASCIIPrefix($inTitle, $titleChars) : ''); 00311 $enc = ''; 00312 00313 if (strcmp($addParams, '') && !$no_cache) { 00314 switch ((string)$this->conf['pEncoding']) { 00315 case 'md5': 00316 $md5 = substr(md5($addParams), 0, 10); 00317 $enc = '+M5'.$md5; 00318 00319 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 00320 'md5hash', 00321 'cache_md5params', 00322 'md5hash=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($md5, 'cache_md5params') 00323 ); 00324 if (!$GLOBALS['TYPO3_DB']->sql_num_rows($res)) { 00325 $insertFields = array( 00326 'md5hash' => $md5, 00327 'tstamp' => $GLOBALS['EXEC_TIME'], 00328 'type' => 1, 00329 'params' => $addParams 00330 ); 00331 00332 $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_md5params', $insertFields); 00333 } 00334 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00335 break; 00336 case 'base64': 00337 $enc = '+B6' . str_replace('=', '_', str_replace('/', '-', base64_encode($addParams))); 00338 break; 00339 } 00340 } 00341 // Setting page and type number: 00342 return $out . $page . $enc . (($type || $out || !$this->conf['noTypeIfNoTitle']) ? '.' . $type : ''); 00343 } 00344 00345 00346 /** 00347 * Returns the simulated static file name (*.html) for the current page (using the page record in $this->page) 00348 * 00349 * @return string The filename (without path) 00350 * @see makeSimulatedFileName(), publish.php 00351 */ 00352 public function getSimulatedFileName() { 00353 return $this->makeSimulatedFileName( 00354 $GLOBALS['TSFE']->page['title'], 00355 ($GLOBALS['TSFE']->page['alias'] ? $GLOBALS['TSFE']->page['alias'] : $GLOBALS['TSFE']->id), 00356 $GLOBALS['TSFE']->type 00357 ) . '.html'; 00358 } 00359 00360 00361 /** 00362 * Processes a query-string with GET-parameters and returns two strings, one with the parameters that CAN be encoded and one array with those which can't be encoded (encoded by the M5 or B6 methods) 00363 * 00364 * @param string Query string to analyse 00365 * @return array Two num keys returned, first is the parameters that MAY be encoded, second is the non-encodable parameters. 00366 * @see makeSimulatedFileName(), t3lib_tstemplate::linkData() 00367 */ 00368 public function processEncodedQueryString($linkVars) { 00369 $remainingLinkVars = ''; 00370 if (strcmp($linkVars, '')) { 00371 $parts = t3lib_div::trimExplode('&', $linkVars); 00372 // This sorts the parameters - and may not be needed and further 00373 // it will generate new MD5 hashes in many cases. Maybe not so smart. Hmm? 00374 sort($parts); 00375 $remainingParts = array(); 00376 foreach ($parts as $index => $value) { 00377 if (strlen($value)) { 00378 list($parameterName) = explode('=', $value, 2); 00379 $parameterName = rawurldecode($parameterName); 00380 if (!$this->pEncodingAllowedParamNames[$parameterName]) { 00381 unset($parts[$index]); 00382 $remainingParts[] = $value; 00383 } 00384 } else { 00385 unset($parts[$index]); 00386 } 00387 } 00388 $linkVars = (count($parts) ? '&' . implode('&', $parts) : ''); 00389 $remainingLinkVars = (count($remainingParts) ? '&' . implode('&', $remainingParts) : ''); 00390 } 00391 return array($linkVars, $remainingLinkVars); 00392 } 00393 00394 00395 /** 00396 * Converts input string to an ASCII based file name prefix 00397 * 00398 * @param string String to base output on 00399 * @param integer Number of characters in the string 00400 * @param string Character to put in the end of string to merge it with the next value. 00401 * @return string Converted string 00402 */ 00403 public function fileNameASCIIPrefix($inTitle, $maxTitleChars, $mergeChar = '.') { 00404 $out = $GLOBALS['TSFE']->csConvObj->specCharsToASCII($GLOBALS['TSFE']->renderCharset, $inTitle); 00405 00406 // Get replacement character 00407 $replacementChar = $this->conf['replacementChar']; 00408 $replacementChars = '_\-' . ($replacementChar != '_' && $replacementChar != '-' ? $replacementChar : ''); 00409 $out = preg_replace('/[^A-Za-z0-9_-]/', $replacementChar, trim(substr($out, 0, $maxTitleChars))); 00410 $out = preg_replace('/([' . $replacementChars . ']){2,}/', '\1', $out); 00411 $out = preg_replace('/[' . $replacementChars . ']?$/', '', $out); 00412 $out = preg_replace('/^[' . $replacementChars . ']?/', '', $out); 00413 00414 return (strlen($out) ? $out . $mergeChar : ''); 00415 } 00416 } 00417 00418 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/simulatestatic/class.tx_simulatestatic.php'])) { 00419 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/simulatestatic/class.tx_simulatestatic.php']); 00420 } 00421 ?>
1.8.0