Documentation TYPO3 par Ameos |
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com) 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00213 class tslib_fe { 00214 00215 // CURRENT PAGE: 00216 var $id=''; // The page id (int) 00217 var $type=''; // RO The type (int) 00218 var $idParts=array(); // Loaded with the id, exploded by ',' 00219 var $cHash=''; // The submitted cHash 00220 var $no_cache=''; // Page will not be cached. Write only true. Never clear value (some other code might have reasons to set it true) 00221 var $rootLine=''; // The rootLine (all the way to tree root, not only the current site!) (array) 00222 var $page=''; // The pagerecord (array) 00223 var $contentPid=0; // This will normally point to the same value as id, but can be changed to point to another page from which content will then be displayed instead. 00224 var $sys_page=''; // The object with pagefunctions (object) 00225 var $jumpurl=''; 00226 var $pageNotFound=0; // Is set to 1 if a pageNotFound handler could have been called. 00227 var $domainStartPage=0; // Domain start page 00228 var $pageAccessFailureHistory=array(); // Array containing a history of why a requested page was not accessible. 00229 var $MP=''; 00230 var $RDCT=''; 00231 var $page_cache_reg1=0; // This can be set from applications as a way to tag cached versions of a page and later perform some external cache management, like clearing only a part of the cache of a page... 00232 var $siteScript=''; // Contains the value of the current script path that activated the frontend. Typically "index.php" but by rewrite rules it could be something else! Used for Speaking Urls / Simulate Static Documents. 00233 00234 // USER 00235 var $fe_user=''; // The user (object) 00236 var $loginUser=''; // Global flag indicating that a front-end user is logged in. This is set only if a user really IS logged in. The group-list may show other groups (like added by IP filter or so) even though there is no user. 00237 var $gr_list=''; // (RO=readonly) The group list, sorted numerically. Group '0,-1' is the default group, but other groups may be added by other means than a user being logged in though... 00238 var $beUserLogin=''; // Flag that indicates if a Backend user is logged in! 00239 var $workspacePreview=''; // Integer, that indicates which workspace is being previewed. 00240 var $loginAllowedInBranch = TRUE; // Shows whether logins are allowed in branch 00241 var $ADMCMD_preview_BEUSER_uid = 0; // Integer, set to backend user ID to initialize when keyword-based preview is used. 00242 00243 // PREVIEW 00244 var $fePreview=''; // Flag indication that preview is active. This is based on the login of a backend user and whether the backend user has read access to the current page. A value of 1 means ordinary preview, 2 means preview of a non-live workspace 00245 var $showHiddenPage=''; // Flag indicating that hidden pages should be shown, selected and so on. This goes for almost all selection of pages! 00246 var $showHiddenRecords=''; // Flag indicating that hidden records should be shown. This includes sys_template, pages_language_overlay and even fe_groups in addition to all other regular content. So in effect, this includes everything except pages. 00247 var $simUserGroup='0'; // Value that contains the simulated usergroup if any 00248 00249 // CONFIGURATION 00250 var $TYPO3_CONF_VARS=array(); // The configuration array as set up in t3lib/config_default.php. Should be an EXACT copy of the global array. 00251 var $config=''; // 'CONFIG' object from TypoScript. Array generated based on the TypoScript configuration of the current page. Saved with the cached pages. 00252 var $TCAcachedExtras=array(); // Array of cached information from TCA. This is NOT TCA itself! 00253 00254 // TEMPLATE / CACHE 00255 var $tmpl=''; // The TypoScript template object. Used to parse the TypoScript template 00256 var $cacheTimeOutDefault=''; // Is set to the time-to-live time of cached pages. If false, default is 60*60*24, which is 24 hours. 00257 var $cacheContentFlag=''; // Set internally if cached content is fetched from the database 00258 var $cacheExpires=0; // Set to the expire time of cached content 00259 var $isClientCachable=FALSE; // Set if cache headers allowing caching are sent. 00260 var $all=''; // $all used by template fetching system. This array is an identification of the template. If $this->all is empty it's because the template-data is not cached, which it must be. 00261 var $sPre=''; // toplevel - objArrayName, eg 'page' 00262 var $pSetup=''; // TypoScript configuration of the page-object pointed to by sPre. $this->tmpl->setup[$this->sPre.'.'] 00263 var $newHash=''; // This hash is unique to the template, the $this->id and $this->type vars and the gr_list (list of groups). Used to get and later store the cached data 00264 var $getMethodUrlIdToken=''; // If config.ftu (Frontend Track User) is set in TypoScript for the current page, the string value of this var is substituted in the rendered source-code with the string, '&ftu=[token...]' which enables GET-method usertracking as opposed to cookie based 00265 var $no_CacheBeforePageGen=''; // This flag is set before inclusion of pagegen.php IF no_cache is set. If this flag is set after the inclusion of pagegen.php, no_cache is forced to be set. This is done in order to make sure that php-code from pagegen does not falsely clear the no_cache flag. 00266 var $tempContent = FALSE; // This flag indicates if temporary content went into the cache during page-generation. 00267 var $forceTemplateParsing=''; // Boolean, passed to TypoScript template class and tells it to render the template forcibly 00268 var $cHash_array=array(); // The array which cHash_calc is based on, see ->makeCacheHash(). 00269 var $hash_base=''; // Loaded with the serialized array that is used for generating a hashstring for the cache 00270 var $pagesTSconfig=''; // May be set to the pagesTSconfig 00271 // PAGE-GENERATION / cOBJ 00272 /* 00273 Eg. insert JS-functions in this array ($additionalHeaderData) to include them once. Use associative keys. 00274 Keys in use: 00275 JSFormValidate : <script type="text/javascript" src="'.$GLOBALS["TSFE"]->absRefPrefix.'t3lib/jsfunc.validateform.js"></script> 00276 JSincludeFormupdate : <script type="text/javascript" src="t3lib/jsfunc.updateform.js"></script> 00277 JSMenuCode, JSMenuCode_menu : JavaScript for the JavaScript menu 00278 JSCode : reserved 00279 JSImgCode : reserved 00280 */ 00281 var $defaultBodyTag='<body>'; // Default bodytag, if nothing else is set. This can be overridden by applications like TemplaVoila. 00282 var $additionalHeaderData=array(); // used to accumulate additional HTML-code for the header-section, <head>...</head>. Insert either associative keys (like additionalHeaderData['myStyleSheet'], see reserved keys above) or num-keys (like additionalHeaderData[] = '...') 00283 var $additionalJavaScript=array(); // used to accumulate additional JavaScript-code. Works like additionalHeaderData. Reserved keys at 'openPic' and 'mouseOver' 00284 var $additionalCSS=array(); // used to accumulate additional Style code. Works like additionalHeaderData. 00285 var $JSeventFuncCalls = array( // you can add JavaScript functions to each entry in these arrays. Please see how this is done in the GMENU_LAYERS script. The point is that many applications on a page can set handlers for onload, onmouseover and onmouseup 00286 'onmousemove' => array(), 00287 'onmouseup' => array(), 00288 'onload' => array(), 00289 ); 00290 var $JSCode=''; // Deprecated, use additionalJavaScript instead. 00291 var $JSImgCode=''; // Used to accumulate JavaScript loaded images (by menus) 00292 var $divSection=''; // Used to accumulate DHTML-layers. 00293 00294 // RENDERING configuration, settings from TypoScript is loaded into these vars. See pagegen.php 00295 var $debug=''; // Debug flag, may output special debug html-code. 00296 var $intTarget=''; // Default internal target 00297 var $extTarget=''; // Default external target 00298 var $MP_defaults=array(); // Keys are page ids and values are default &MP (mount point) values to set when using the linking features...) 00299 var $spamProtectEmailAddresses=0; // If set, typolink() function encrypts email addresses. Is set in pagegen-class. 00300 var $absRefPrefix=''; // Absolute Reference prefix 00301 var $absRefPrefix_force=0; // Absolute Reference prefix force flag. This is set, if the type and id is retrieve from PATH_INFO and thus we NEED to prefix urls with at least '/' 00302 var $compensateFieldWidth=''; // Factor for form-field widths compensation 00303 var $lockFilePath=''; // Lock file path 00304 var $ATagParams=''; // <A>-tag parameters 00305 var $sWordRegEx=''; // Search word regex, calculated if there has been search-words send. This is used to mark up the found search words on a page when jumped to from a link in a search-result. 00306 var $sWordList=''; // Is set to the incoming array sword_list in case of a page-view jumped to from a search-result. 00307 var $linkVars=''; // A string prepared for insertion in all links on the page as url-parameters. Based on configuration in TypoScript where you defined which GET_VARS you would like to pass on. 00308 var $excludeCHashVars=''; // A string set with a comma list of additional GET vars which should NOT be included in the cHash calculation. These vars should otherwise be detected and involved in caching, eg. through a condition in TypoScript. 00309 var $displayEditIcons=''; // If set, edit icons are rendered aside content records. Must be set only if the ->beUserLogin flag is set and set_no_cache() must be called as well. 00310 var $displayFieldEditIcons=''; // If set, edit icons are rendered aside individual fields of content. Must be set only if the ->beUserLogin flag is set and set_no_cache() must be called as well. 00311 var $sys_language_uid=0; // Site language, 0 (zero) is default, int+ is uid pointing to a sys_language record. Should reflect which language menus, templates etc is displayed in (master language) - but not necessarily the content which could be falling back to default (see sys_language_content) 00312 var $sys_language_mode=''; // Site language mode for content fall back. 00313 var $sys_language_content=0; // Site content selection uid (can be different from sys_language_uid if content is to be selected from a fall-back language. Depends on sys_language_mode) 00314 var $sys_language_contentOL=0; // Site content overlay flag; If set - and sys_language_content is > 0 - , records selected will try to look for a translation pointing to their uid. (If configured in [ctrl][languageField] / [ctrl][transOrigP...] 00315 var $sys_language_isocode = ''; // Is set to the iso code of the sys_language_content if that is properly defined by the sys_language record representing the sys_language_uid. (Requires the extension "static_info_tables") 00316 00317 // RENDERING data 00318 var $applicationData=Array(); // 'Global' Storage for various applications. Keys should be 'tx_'.extKey for extensions. 00319 var $register=Array(); 00320 var $registerStack=Array(); // Stack used for storing array and retrieving register arrays (see LOAD_REGISTER and CLEAR_REGISTER) 00321 var $cObjectDepthCounter = 50; // Checking that the function is not called eternally. This is done by interrupting at a depth of 50 00322 var $recordRegister = Array(); // used by cObj->RECORDS and cObj->CONTENT to ensure the a records is NOT rendered twice through it! 00323 var $currentRecord = ''; // This is set to the [table]:[uid] of the latest record rendered. Note that class tslib_cObj has an equal value, but that is pointing to the record delivered in the $data-array of the tslib_cObj instance, if the cObjects CONTENT or RECORD created that instance 00324 var $accessKey =array(); // Used by class tslib_menu to keep track of access-keys. 00325 var $imagesOnPage=array(); // Numerical array where image filenames are added if they are referenced in the rendered document. This includes only TYPO3 generated/inserted images. 00326 var $lastImageInfo=array(); // Is set in tslib_cObj->cImage() function to the info-array of the most recent rendered image. The information is used in tslib_cObj->IMGTEXT 00327 var $uniqueCounter=0; // Used to generate page-unique keys. Point is that uniqid() functions is very slow, so a unikey key is made based on this, see function uniqueHash() 00328 var $uniqueString=''; 00329 var $indexedDocTitle=''; // This value will be used as the title for the page in the indexer (if indexing happens) 00330 var $altPageTitle=''; // Alternative page title (normally the title of the page record). Can be set from applications you make. 00331 var $pEncAllowedParamNames=array(); // An array that holds parameter names (keys) of GET parameters which MAY be MD5/base64 encoded with simulate_static_documents method. 00332 var $baseUrl=''; // The Base url set for the page header. 00333 var $anchorPrefix=''; // The proper anchor prefix needed when using speaking urls. (only set if baseUrl is set) 00334 00335 // Page content render object 00336 var $cObj =''; // is instantiated object of tslib_cObj 00337 00338 // CONTENT accumulation 00339 var $content=''; // All page content is accumulated in this variable. See pagegen.php 00340 00341 // GENERAL 00342 var $clientInfo=''; // Set to the browser: net / msie if 4+ browsers 00343 var $scriptParseTime=0; 00344 var $TCAloaded = 0; // Set ONLY if the full TCA is loaded 00345 00346 // Character set (charset) conversion object: 00347 var $csConvObj; // An instance of the "t3lib_cs" class. May be used by any application. 00348 var $defaultCharSet = 'iso-8859-1'; // The default charset used in the frontend if nothing else is set. 00349 var $renderCharset=''; // Internal charset of the frontend during rendering: Defaults to "forceCharset" and if that is not set, to ->defaultCharSet 00350 var $metaCharset=''; // Output charset of the websites content. This is the charset found in the header, meta tag etc. If different from $renderCharset a conversion happens before output to browser. Defaults to ->renderCharset if not set. 00351 var $localeCharset=''; // Assumed charset of locale strings. 00352 00353 // LANG: 00354 var $lang=''; // Set to the system language key (used on the site) 00355 var $langSplitIndex=0; // Set to the index number of the language key 00356 var $labelsCharset=''; // Charset of the labels from locallang (based on $this->lang) 00357 var $convCharsetToFrom=''; // Set to the charsets to convert from/to IF there are any difference. Otherwise this stays a string 00358 var $LL_labels_cache=array(); 00359 var $LL_files_cache=array(); 00360 00361 00362 00363 00364 00382 function tslib_fe($TYPO3_CONF_VARS, $id, $type, $no_cache='', $cHash='', $jumpurl='',$MP='',$RDCT='') { 00383 00384 // Setting some variables: 00385 $this->TYPO3_CONF_VARS = $TYPO3_CONF_VARS; 00386 $this->id = $id; 00387 $this->type = $type; 00388 $this->no_cache = $no_cache ? 1 : 0; 00389 $this->cHash = $cHash; 00390 $this->jumpurl = $jumpurl; 00391 $this->MP = $this->TYPO3_CONF_VARS['FE']['enable_mount_pids'] ? (string)$MP : ''; 00392 $this->RDCT = $RDCT; 00393 $this->clientInfo = t3lib_div::clientInfo(); 00394 $this->uniqueString=md5(microtime()); 00395 00396 $this->csConvObj = t3lib_div::makeInstance('t3lib_cs'); 00397 00398 // Call post processing function for constructor: 00399 if (is_array($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['tslib_fe-PostProc'])) { 00400 $_params = array('pObj' => &$this); 00401 foreach($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['tslib_fe-PostProc'] as $_funcRef) { 00402 t3lib_div::callUserFunction($_funcRef,$_params,$this); 00403 } 00404 } 00405 } 00406 00415 function connectToMySQL() { 00416 $this->connectToDB(); 00417 } 00418 00425 function connectToDB() { 00426 if ($GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) { 00427 if (!TYPO3_db) { 00428 $this->printError('No database selected','Database Error'); 00429 // Redirects to the Install Tool: 00430 echo '<script type="text/javascript"> 00431 /*<![CDATA[*/ 00432 window.location.href = "'.TYPO3_mainDir.'install/index.php?mode=123&step=1&password=joh316"; 00433 /*]]>*/ 00434 </script>'; 00435 exit; 00436 } elseif (!$GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) { 00437 $this->printError('Cannot connect to the current database, "'.TYPO3_db.'"','Database Error'); 00438 exit; 00439 } 00440 } else { 00441 if (!TYPO3_db) { 00442 // Redirects to the Install Tool: 00443 echo '<script type="text/javascript"> 00444 /*<![CDATA[*/ 00445 window.location.href = "'.TYPO3_mainDir.'install/index.php?mode=123&step=1&password=joh316"; 00446 /*]]>*/ 00447 </script>'; 00448 exit; 00449 } 00450 $this->printError('The current username, password or host was not accepted when the connection to the database was attempted to be established!','Database Error'); 00451 exit; 00452 } 00453 00454 00455 // Call post processing function for DB connection: 00456 if (is_array($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['connectToDB'])) { 00457 $_params = array('pObj' => &$this); 00458 foreach($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['connectToDB'] as $_funcRef) { 00459 t3lib_div::callUserFunction($_funcRef,$_params,$this); 00460 } 00461 } 00462 } 00463 00470 function sendRedirect() { 00471 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('params', 'cache_md5params', 'md5hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->RDCT, 'cache_md5params')); 00472 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00473 $this->updateMD5paramsRecord($this->RDCT); 00474 header('Location: '.$row['params']); 00475 exit; 00476 } 00477 } 00478 00479 00480 00481 00482 00483 00484 00485 00486 00487 00488 00489 00490 00491 00492 00493 00494 00495 00496 /******************************************** 00497 * 00498 * Initializing, resolving page id 00499 * 00500 ********************************************/ 00501 00502 00508 function initFEuser() { 00509 $this->fe_user = t3lib_div::makeInstance('tslib_feUserAuth'); 00510 00511 $this->fe_user->lockIP = $this->TYPO3_CONF_VARS['FE']['lockIP']; 00512 $this->fe_user->lockHashKeyWords = $this->TYPO3_CONF_VARS['FE']['lockHashKeyWords']; 00513 $this->fe_user->checkPid = $this->TYPO3_CONF_VARS['FE']['checkFeUserPid']; 00514 $this->fe_user->lifetime = intval($this->TYPO3_CONF_VARS['FE']['lifetime']); 00515 $this->fe_user->checkPid_value = $GLOBALS['TYPO3_DB']->cleanIntList(t3lib_div::_GP('pid')); // List of pid's acceptable 00516 00517 // Check if a session is transferred: 00518 if (t3lib_div::_GP('FE_SESSION_KEY')) { 00519 $fe_sParts = explode('-',t3lib_div::_GP('FE_SESSION_KEY')); 00520 if (!strcmp(md5($fe_sParts[0].'/'.$this->TYPO3_CONF_VARS['SYS']['encryptionKey']), $fe_sParts[1])) { // If the session key hash check is OK: 00521 $_COOKIE[$this->fe_user->name] = $fe_sParts[0]; 00522 $this->fe_user->forceSetCookie = 1; 00523 } 00524 } 00525 00526 if ($this->TYPO3_CONF_VARS['FE']['dontSetCookie']) { 00527 $this->fe_user->dontSetCookie=1; 00528 } 00529 00530 $this->fe_user->start(); 00531 $this->fe_user->unpack_uc(''); 00532 $this->fe_user->fetchSessionData(); // Gets session data 00533 $recs = t3lib_div::_GP('recs'); 00534 if (is_array($recs)) { // If any record registration is submitted, register the record. 00535 $this->fe_user->record_registration($recs, $this->TYPO3_CONF_VARS['FE']['maxSessionDataSize']); 00536 } 00537 00538 // Call hook for possible manipulation of frontend user object 00539 if (is_array($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['initFEuser'])) { 00540 $_params = array('pObj' => &$this); 00541 foreach($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['initFEuser'] as $_funcRef) { 00542 t3lib_div::callUserFunction($_funcRef,$_params,$this); 00543 } 00544 } 00545 00546 // For every 60 seconds the is_online timestamp is updated. 00547 if (is_array($this->fe_user->user) && $this->fe_user->user['uid'] && $this->fe_user->user['is_online']<($GLOBALS['EXEC_TIME']-60)) { 00548 $GLOBALS['TYPO3_DB']->exec_UPDATEquery('fe_users', 'uid='.intval($this->fe_user->user['uid']), array('is_online' => $GLOBALS['EXEC_TIME'])); 00549 } 00550 } 00551 00558 function initUserGroups() { 00559 00560 $this->fe_user->showHiddenRecords = $this->showHiddenRecords; // This affects the hidden-flag selecting the fe_groups for the user! 00561 $this->fe_user->fetchGroupData(); // no matter if we have an active user we try to fetch matching groups which can be set without an user (simulation for instance!) 00562 00563 if (is_array($this->fe_user->user) && count($this->fe_user->groupData['uid'])) { 00564 $this->loginUser=1; // global flag! 00565 $this->gr_list = '0,-2'; // group -2 is not an existing group, but denotes a 'default' group when a user IS logged in. This is used to let elements be shown for all logged in users! 00566 $gr_array = $this->fe_user->groupData['uid']; 00567 } else { 00568 $this->loginUser=0; 00569 $this->gr_list = '0,-1'; // group -1 is not an existing group, but denotes a 'default' group when not logged in. This is used to let elements be hidden, when a user is logged in! 00570 00571 if ($this->loginAllowedInBranch) { 00572 $gr_array = $this->fe_user->groupData['uid']; // For cases where logins are not banned from a branch usergroups can be set based on IP masks so we should add the usergroups uids. 00573 } else { 00574 $gr_array = array(); // Set to blank since we will NOT risk any groups being set when no logins are allowed! 00575 } 00576 } 00577 00578 // Clean up. 00579 $gr_array = array_unique($gr_array); // Make unique... 00580 sort($gr_array); // sort 00581 if (count($gr_array)) { 00582 $this->gr_list.=','.implode(',',$gr_array); 00583 } 00584 00585 if ($this->fe_user->writeDevLog) t3lib_div::devLog('Valid usergroups for TSFE: '.$this->gr_list, 'tslib_fe'); 00586 } 00587 00593 function isUserOrGroupSet() { 00594 return is_array($this->fe_user->user) || $this->gr_list!=='0,-1'; 00595 } 00596 00618 function checkAlternativeIdMethods() { 00619 00620 $this->siteScript = t3lib_div::getIndpEnv('TYPO3_SITE_SCRIPT'); 00621 00622 // Resolving of "simulateStaticDocuments" URLs: 00623 if ($this->siteScript && substr($this->siteScript,0,9)!='index.php') { // 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 $_SERVER['REDIRECT_URL'] to check but 00624 $uParts = parse_url($this->siteScript); // Parse the path: 00625 $fI = t3lib_div::split_fileref($uParts['path']); 00626 00627 if (!$fI['path'] && $fI['file'] && substr($fI['file'],-5)=='.html') { 00628 $parts = explode('.',$fI['file']); 00629 $pCount = count($parts); 00630 if ($pCount>2) { 00631 $this->type = intval($parts[$pCount-2]); 00632 $this->id = $parts[$pCount-3]; 00633 } else { 00634 $this->type = 0; 00635 $this->id = $parts[0]; 00636 } 00637 } 00638 } 00639 00640 // If PATH_INFO 00641 if (t3lib_div::getIndpEnv('PATH_INFO')) { // If pathinfo contains stuff... 00642 $parts=t3lib_div::trimExplode('/',t3lib_div::getIndpEnv('PATH_INFO'),1); 00643 $parts[]='html'; 00644 $pCount = count($parts); 00645 if ($pCount>2) { 00646 $this->type = intval($parts[$pCount-2]); 00647 $this->id = $parts[$pCount-3]; 00648 } else { 00649 $this->type = 0; 00650 $this->id = $parts[0]; 00651 } 00652 $this->absRefPrefix_force=1; 00653 } 00654 00655 // Call post processing function for custom URL methods. 00656 if (is_array($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['checkAlternativeIdMethods-PostProc'])) { 00657 $_params = array('pObj' => &$this); 00658 foreach($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['checkAlternativeIdMethods-PostProc'] as $_funcRef) { 00659 t3lib_div::callUserFunction($_funcRef,$_params,$this); 00660 } 00661 } 00662 } 00663 00670 function clear_preview() { 00671 $this->showHiddenPage = 0; 00672 $this->showHiddenRecords = 0; 00673 $GLOBALS['SIM_EXEC_TIME'] = $GLOBALS['EXEC_TIME']; 00674 $this->fePreview = 0; 00675 } 00676 00683 function determineId() { 00684 00685 // Getting ARG-v values if some 00686 $this->setIDfromArgV(); 00687 00688 // If there is a Backend login we are going to check for any preview settings: 00689 $GLOBALS['TT']->push('beUserLogin',''); 00690 if ($this->beUserLogin || $this->doWorkspacePreview()) { 00691 00692 // Backend user preview features: 00693 if ($this->beUserLogin) { 00694 $this->fePreview = $GLOBALS['BE_USER']->extGetFeAdminValue('preview') ? 1 : 0; 00695 00696 // If admin panel preview is enabled... 00697 if ($this->fePreview) { 00698 $fe_user_OLD_USERGROUP = $this->fe_user->user['usergroup']; 00699 00700 $this->showHiddenPage = $GLOBALS['BE_USER']->extGetFeAdminValue('preview','showHiddenPages'); 00701 $this->showHiddenRecords = $GLOBALS['BE_USER']->extGetFeAdminValue('preview','showHiddenRecords'); 00702 // simulate date 00703 $simTime = $GLOBALS['BE_USER']->extGetFeAdminValue('preview','simulateDate'); 00704 if ($simTime) $GLOBALS['SIM_EXEC_TIME']=$simTime; 00705 // simulate user 00706 $simUserGroup = $GLOBALS['BE_USER']->extGetFeAdminValue('preview','simulateUserGroup'); 00707 $this->simUserGroup = $simUserGroup; 00708 if ($simUserGroup) $this->fe_user->user['usergroup']=$simUserGroup; 00709 if (!$simUserGroup && !$simTime && !$this->showHiddenPage && !$this->showHiddenRecords) { 00710 $this->fePreview=0; 00711 } 00712 } 00713 } 00714 00715 if ($this->id) { 00716 00717 // Now it's investigated if the raw page-id points to a hidden page and if so, the flag is set. 00718 // This does not require the preview flag to be set in the admin panel 00719 $idQ = t3lib_div::testInt($this->id) ? 'uid='.intval($this->id) : 'alias='.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->id, 'pages').' AND pid>=0'; // pid>=0 added for the sake of versioning... 00720 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('hidden', 'pages', $idQ.' AND hidden!=0 AND deleted=0'); 00721 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res)) { 00722 $this->fePreview = 1; // The preview flag is set only if the current page turns out to actually be hidden! 00723 $this->showHiddenPage = 1; 00724 } 00725 00726 // For Live workspace: Check root line for proper connection to tree root (done because of possible preview of page / branch versions) 00727 if (!$this->fePreview && $this->whichWorkspace()===0) { 00728 00729 // Initialize the page-select functions to check rootline: 00730 $temp_sys_page = t3lib_div::makeInstance('t3lib_pageSelect'); 00731 $temp_sys_page->init($this->showHiddenPage); 00732 00733 // If root line contained NO records and ->error_getRootLine_failPid tells us that it was because of a pid=-1 (indicating a "version" record)...: 00734 if (!count($temp_sys_page->getRootLine($this->id,$this->MP)) && $temp_sys_page->error_getRootLine_failPid==-1) { 00735 00736 // Setting versioningPreview flag and try again: 00737 $temp_sys_page->versioningPreview = TRUE; 00738 if (count($temp_sys_page->getRootLine($this->id,$this->MP))) { 00739 // Finally, we got a root line (meaning that it WAS due to versioning preview of a page somewhere) and we set the fePreview flag which in itself will allow sys_page class to display previews of versionized records. 00740 $this->fePreview = 1; 00741 } 00742 } 00743 } 00744 } 00745 00746 // The preview flag will be set if a backend user is in an offline workspace 00747 if (($GLOBALS['BE_USER']->user['workspace_preview'] || t3lib_div::_GP('ADMCMD_view') || $this->doWorkspacePreview()) && ($this->whichWorkspace()===-1 || $this->whichWorkspace()>0)) { 00748 $this->fePreview = 2; // Will show special preview message. 00749 } 00750 00751 // If the front-end is showing a preview, caching MUST be disabled. 00752 if ($this->fePreview) { 00753 $this->set_no_cache(); 00754 } 00755 } 00756 $GLOBALS['TT']->pull(); 00757 00758 // Now, get the id, validate access etc: 00759 $this->fetch_the_id(); 00760 00761 // Check if backend user has read access to this page. If not, recalculate the id. 00762 if ($this->beUserLogin && $this->fePreview) { 00763 if (!$GLOBALS['BE_USER']->doesUserHaveAccess($this->page,1)) { 00764 00765 // Resetting 00766 $this->clear_preview(); 00767 $this->fe_user->user['usergroup'] = $fe_user_OLD_USERGROUP; 00768 00769 // Fetching the id again, now with the preview settings reset. 00770 $this->fetch_the_id(); 00771 } 00772 } 00773 00774 // Checks if user logins are blocked for a certain branch and if so, will unset user login and re-fetch ID. 00775 $this->loginAllowedInBranch = $this->checkIfLoginAllowedInBranch(); 00776 if (!$this->loginAllowedInBranch) { // Logins are not allowed: 00777 if ($this->isUserOrGroupSet()) { // Only if there is a login will we run this... 00778 00779 // Clear out user and group: 00780 unset($this->fe_user->user); 00781 $this->gr_list = '0,-1'; 00782 00783 // Fetching the id again, now with the preview settings reset. 00784 $this->fetch_the_id(); 00785 } 00786 } 00787 00788 // Final cleaning. 00789 $this->id = $this->contentPid = intval($this->id); // Make sure it's an integer 00790 $this->type = intval($this->type); // Make sure it's an integer 00791 00792 // Look for alternative content PID if page is under version preview: 00793 if ($this->fePreview) { 00794 if ($this->page['_ORIG_pid']==-1 && $this->page['t3ver_swapmode']==0) { // Current page must have been an offline version and have swapmode set to 0: 00795 // Setting contentPid here for preview might not be completely correct to do. Strictly the "_ORIG_uid" value should be used for tables where "versioning_followPages" is set and for others not. However this is a working quick-fix to display content elements at least! 00796 $this->contentPid = $this->page['_ORIG_uid']; 00797 } 00798 } 00799 00800 // Call post processing function for id determination: 00801 if (is_array($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['determineId-PostProc'])) { 00802 $_params = array('pObj' => &$this); 00803 foreach($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['determineId-PostProc'] as $_funcRef) { 00804 t3lib_div::callUserFunction($_funcRef,$_params,$this); 00805 } 00806 } 00807 } 00808 00817 function fetch_the_id() { 00818 $GLOBALS['TT']->push('fetch_the_id initialize/',''); 00819 00820 // Initialize the page-select functions. 00821 $this->sys_page = t3lib_div::makeInstance('t3lib_pageSelect'); 00822 $this->sys_page->versioningPreview = $this->fePreview ? TRUE : FALSE; 00823 $this->sys_page->versioningWorkspaceId = $this->whichWorkspace(); 00824 $this->sys_page->init($this->showHiddenPage); 00825 00826 // Set the valid usergroups for FE 00827 $this->initUserGroups(); 00828 00829 // Sets sys_page where-clause 00830 $this->setSysPageWhereClause(); 00831 00832 // Splitting $this->id by a period (.). First part is 'id' and second part - if exists - will overrule the &type param if given 00833 $pParts = explode('.',$this->id); 00834 $this->id = $pParts[0]; // Set it. 00835 if (isset($pParts[1])) {$this->type=$pParts[1];} 00836 00837 // Splitting $this->id by a comma (,). First part is 'id' and other parts are just stored for use in scripts. 00838 $this->idParts = explode(',',$this->id); 00839 00840 // Splitting by a '+' sign - used for base64/md5 methods of parameter encryption for simulate static documents. 00841 list($pgID,$SSD_p)=explode('+',$this->idParts[0],2); 00842 if ($SSD_p) { $this->idPartsAnalyze($SSD_p); } 00843 $this->id = $pgID; // Set id 00844 00845 // If $this->id is a string, it's an alias 00846 $this->checkAndSetAlias(); 00847 00848 // The id and type is set to the integer-value - just to be sure... 00849 $this->id = intval($this->id); 00850 $this->type = intval($this->type); 00851 $GLOBALS['TT']->pull(); 00852 00853 // We find the first page belonging to the current domain 00854 $GLOBALS['TT']->push('fetch_the_id domain/',''); 00855 $this->domainStartPage = $this->findDomainRecord($this->TYPO3_CONF_VARS['SYS']['recursiveDomainSearch']); // the page_id of the current domain 00856 if (!$this->id) { 00857 if ($this->domainStartPage) { 00858 $this->id = $this->domainStartPage; // If the id was not previously set, set it to the id of the domain. 00859 } else { 00860 $theFirstPage = $this->sys_page->getFirstWebPage($this->id); // Find the first 'visible' page in that domain 00861 if ($theFirstPage) { 00862 $this->id = $theFirstPage['uid']; 00863 } else { 00864 $this->printError('No pages are found on the rootlevel!'); 00865 exit; 00866 } 00867 } 00868 } 00869 $GLOBALS['TT']->pull(); 00870 00871 $GLOBALS['TT']->push('fetch_the_id rootLine/',''); 00872 $requestedId = $this->id; // We store the originally requested id 00873 $this->getPageAndRootlineWithDomain($this->domainStartPage); 00874 $GLOBALS['TT']->pull(); 00875 00876 if ($this->pageNotFound && $this->TYPO3_CONF_VARS['FE']['pageNotFound_handling']) { 00877 $pNotFoundMsg = array( 00878 1 => 'ID was not an accessible page', 00879 2 => 'Subsection was found and not accessible', 00880 3 => 'ID was outside the domain', 00881 4 => 'The requested page alias does not exist' 00882 ); 00883 $this->pageNotFoundAndExit($pNotFoundMsg[$this->pageNotFound]); 00884 } 00885 00886 // set no_cache if set 00887 if ($this->page['no_cache']) { 00888 $this->set_no_cache(); 00889 } 00890 00891 // Init SYS_LASTCHANGED 00892 $this->register['SYS_LASTCHANGED'] = intval($this->page['tstamp']); 00893 if ($this->register['SYS_LASTCHANGED'] < intval($this->page['SYS_LASTCHANGED'])) { 00894 $this->register['SYS_LASTCHANGED'] = intval($this->page['SYS_LASTCHANGED']); 00895 } 00896 } 00897 00911 function getPageAndRootline() { 00912 $this->page = $this->sys_page->getPage($this->id); 00913 if (!count($this->page)) { 00914 // If no page, we try to find the page before in the rootLine. 00915 $this->pageNotFound=1; // Page is 'not found' in case the id itself was not an accessible page. code 1 00916 $this->rootLine = $this->sys_page->getRootLine($this->id,$this->MP); 00917 if (count($this->rootLine)) { 00918 $c=count($this->rootLine)-1; 00919 while($c>0) { 00920 00921 // Add to page access failure history: 00922 $this->pageAccessFailureHistory['direct_access'][] = $this->rootLine[$c]; 00923 00924 // Decrease to next page in rootline and check the access to that, if OK, set as page record and ID value. 00925 $c--; 00926 $this->id = $this->rootLine[$c]['uid']; 00927 $this->page = $this->sys_page->getPage($this->id); 00928 if (count($this->page)){ break; } 00929 } 00930 } 00931 // If still no page... 00932 if (!count($this->page)) { 00933 if ($this->TYPO3_CONF_VARS['FE']['pageNotFound_handling']) { 00934 $this->pageNotFoundAndExit('The requested page does not exist!'); 00935 } else { 00936 $this->printError('The requested page does not exist!'); 00937 exit; 00938 } 00939 } 00940 } 00941 00942 // spacer is not accessible in frontend 00943 if ($this->page['doktype'] == 199) { 00944 if ($this->TYPO3_CONF_VARS['FE']['pageNotFound_handling']) { 00945 $this->pageNotFoundAndExit('The requested page does not exist!'); 00946 } else { 00947 $this->printError('The requested page does not exist!'); 00948 exit; 00949 } 00950 } 00951 00952 // Is the ID a link to another page?? 00953 if ($this->page['doktype']==4) { 00954 $this->MP = ''; // We need to clear MP if the page is a shortcut. Reason is if the short cut goes to another page, then we LEAVE the rootline which the MP expects. 00955 $this->page = $this->getPageShortcut($this->page['shortcut'],$this->page['shortcut_mode'],$this->page['uid']); 00956 $this->id = $this->page['uid']; 00957 } 00958 00959 // Gets the rootLine 00960 $this->rootLine = $this->sys_page->getRootLine($this->id,$this->MP); 00961 00962 // If not rootline we're off... 00963 if (!count($this->rootLine)) { 00964 $this->printError('The requested page didn\'t have a proper connection to the tree-root! <br /><br />('.$this->sys_page->error_getRootLine.')'); 00965 exit; 00966 } 00967 00968 // Checking for include section regarding the hidden/starttime/endtime/fe_user (that is access control of a whole subbranch!) 00969 if ($this->checkRootlineForIncludeSection()) { 00970 if (!count($this->rootLine)) { 00971 $this->printError('The requested page was not accessible!'); 00972 exit; 00973 } else { 00974 $el = reset($this->rootLine); 00975 $this->id = $el['uid']; 00976 $this->page = $this->sys_page->getPage($this->id); 00977 $this->rootLine = $this->sys_page->getRootLine($this->id,$this->MP); 00978 } 00979 } 00980 } 00981 00994 function getPageShortcut($SC,$mode,$thisUid,$itera=20,$pageLog=array()) { 00995 $idArray = t3lib_div::intExplode(',',$SC); 00996 00997 // Find $page record depending on shortcut mode: 00998 switch($mode) { 00999 case 1: 01000 case 2: 01001 $pageArray = $this->sys_page->getMenu($idArray[0]?$idArray[0]:$thisUid,'*','sorting','AND pages.doktype<199 AND pages.doktype!=6'); 01002 $pO = 0; 01003 if ($mode==2 && count($pageArray)) { // random 01004 $this->make_seed(); 01005 $randval = intval(rand(0,count($pageArray)-1)); 01006 $pO = $randval; 01007 } 01008 $c = 0; 01009 reset($pageArray); 01010 while(list(,$pV)=each($pageArray)) { 01011 if ($c==$pO) { 01012 $page = $pV; 01013 break; 01014 } 01015 $c++; 01016 } 01017 break; 01018 default: 01019 $page = $this->sys_page->getPage($idArray[0]); 01020 break; 01021 } 01022 01023 // Check if short cut page was a shortcut itself, if so look up recursively: 01024 if ($page['doktype']==4) { 01025 if (!in_array($page['uid'],$pageLog) && $itera>0) { 01026 $pageLog[] = $page['uid']; 01027 $page = $this->getPageShortcut($page['shortcut'],$page['shortcut_mode'],$page['uid'],$itera-1,$pageLog); 01028 } else { 01029 $pageLog[] = $page['uid']; 01030 $this->printError('Page shortcuts were looping in uids '.implode(',',$pageLog).'...!'); 01031 exit; 01032 } 01033 } 01034 // Return resulting page: 01035 return $page; 01036 } 01037 01044 function checkRootlineForIncludeSection() { 01045 $c=count($this->rootLine); 01046 $removeTheRestFlag=0; 01047 01048 for ($a=0;$a<$c;$a++) { 01049 if (!$this->checkPagerecordForIncludeSection($this->rootLine[$a])) { 01050 // Add to page access failure history: 01051 $this->pageAccessFailureHistory['sub_section'][] = $this->rootLine[$a]; 01052 $removeTheRestFlag=1; 01053 } 01054 if ($this->rootLine[$a]['doktype']==6) { 01055 if ($this->beUserLogin) { // If there is a backend user logged in, check if he has read access to the page: 01056 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'uid='.intval($this->id).' AND '.$GLOBALS['BE_USER']->getPagePermsClause(1)); // versionOL()? 01057 list($isPage) = $GLOBALS['TYPO3_DB']->sql_fetch_row($res); 01058 if (!$isPage) $removeTheRestFlag=1; // If there was no page selected, the user apparently did not have read access to the current PAGE (not position in rootline) and we set the remove-flag... 01059 } else { // Dont go here, if there is no backend user logged in. 01060 $removeTheRestFlag=1; 01061 } 01062 } 01063 if ($removeTheRestFlag) { 01064 $this->pageNotFound=2; // Page is 'not found' in case a subsection was found and not accessible, code 2 01065 unset($this->rootLine[$a]); 01066 } 01067 } 01068 return $removeTheRestFlag; 01069 } 01070 01081 function checkEnableFields($row,$bypassGroupCheck=FALSE) { 01082 if ((!$row['hidden'] || $this->showHiddenPage) 01083 && $row['starttime']<=$GLOBALS['SIM_EXEC_TIME'] 01084 && ($row['endtime']==0 || $row['endtime']>$GLOBALS['SIM_EXEC_TIME']) 01085 && ($bypassGroupCheck || $this->checkPageGroupAccess($row)) 01086 ) { return TRUE; } 01087 } 01088 01097 function checkPageGroupAccess($row, $groupList=NULL) { 01098 if(is_null($groupList)) { 01099 $groupList = $this->gr_list; 01100 } 01101 if(!is_array($groupList)) { 01102 $groupList = explode(',', $groupList); 01103 } 01104 $pageGroupList = explode(',', $row['fe_group'] ? $row['fe_group'] : 0); 01105 return count(array_intersect($groupList, $pageGroupList)) > 0; 01106 } 01107 01116 function checkPagerecordForIncludeSection($row) { 01117 return (!$row['extendToSubpages'] || $this->checkEnableFields($row)) ? 1 : 0; 01118 } 01119 01125 function checkIfLoginAllowedInBranch() { 01126 01127 // Initialize: 01128 $c = count($this->rootLine); 01129 $disable = FALSE; 01130 01131 // Traverse root line from root and outwards: 01132 for ($a=0; $a<$c; $a++) { 01133 01134 // If a value is set for login state: 01135 if ($this->rootLine[$a]['fe_login_mode'] > 0) { 01136 01137 // Determine state from value: 01138 $disable = (int)$this->rootLine[$a]['fe_login_mode'] === 1 ? TRUE : FALSE; 01139 } 01140 } 01141 01142 return !$disable; 01143 } 01144 01150 function getPageAccessFailureReasons() { 01151 $output = array(); 01152 01153 $combinedRecords = array_merge( 01154 is_array($this->pageAccessFailureHistory['direct_access']) ? $this->pageAccessFailureHistory['direct_access'] : array(array('fe_group'=>0)), // Adding fake first record for direct access if none, otherwise $k==0 below will be indicating a sub-section record to be first direct_access record which is of course false! 01155 is_array($this->pageAccessFailureHistory['sub_section']) ? $this->pageAccessFailureHistory['sub_section'] : array() 01156 ); 01157 01158 if (count($combinedRecords)) { 01159 foreach($combinedRecords as $k => $pagerec) { 01160 // If $k=0 then it is the very first page the original ID was pointing at and that will get a full check of course 01161 // If $k>0 it is parent pages being tested. They are only significant for the access to the first page IF they had the extendToSubpages flag set, hence checked only then! 01162 if (!$k || $pagerec['extendToSubpages']) { 01163 if ($pagerec['hidden']) $output['hidden'][$pagerec['uid']] = TRUE; 01164 if ($pagerec['starttime'] > $GLOBALS['SIM_EXEC_TIME']) $output['starttime'][$pagerec['uid']] = $pagerec['starttime']; 01165 if ($pagerec['endtime']!=0 && $pagerec['endtime'] <= $GLOBALS['SIM_EXEC_TIME']) $output['endtime'][$pagerec['uid']] = $pagerec['endtime']; 01166 if (!$this->checkPageGroupAccess($pagerec)) $output['fe_group'][$pagerec['uid']] = $pagerec['fe_group']; 01167 } 01168 } 01169 } 01170 01171 return $output; 01172 } 01173 01182 function setIDfromArgV() { 01183 if (!$this->id) { 01184 list($theAlias) = explode('&',t3lib_div::getIndpEnv('QUERY_STRING')); 01185 $theAlias = trim($theAlias); 01186 $this->id = $theAlias ? $theAlias : 0; 01187 } 01188 } 01189 01198 function getPageAndRootlineWithDomain($domainStartPage) { 01199 $this->getPageAndRootline(); 01200 01201 // Checks if the $domain-startpage is in the rootLine. This is necessary so that references to page-id's from other domains are not possible. 01202 if ($domainStartPage && is_array($this->rootLine)) { 01203 reset ($this->rootLine); 01204 $idFound = 0; 01205 while(list($key,$val)=each($this->rootLine)) { 01206 if ($val['uid']==$domainStartPage) { 01207 $idFound=1; 01208 break; 01209 } 01210 } 01211 if (!$idFound) { 01212 $this->pageNotFound=3; // Page is 'not found' in case the id was outside the domain, code 3 01213 $this->id = $domainStartPage; 01214 $this->getPageAndRootline(); //re-get the page and rootline if the id was not found. 01215 } 01216 } 01217 } 01218 01225 function setSysPageWhereClause() { 01226 $this->sys_page->where_hid_del.=' AND pages.doktype<200'; 01227 $this->sys_page->where_groupAccess = $this->sys_page->getMultipleGroupsWhereClause('pages.fe_group', 'pages'); 01228 } 01229 01237 function findDomainRecord($recursive=0) { 01238 if ($recursive) { 01239 $host = explode('.',t3lib_div::getIndpEnv('HTTP_HOST')); 01240 while(count($host)) { 01241 $pageUid = $this->sys_page->getDomainStartPage(implode('.',$host),t3lib_div::getIndpEnv('SCRIPT_NAME'),t3lib_div::getIndpEnv('REQUEST_URI')); 01242 if ($pageUid) return $pageUid; else array_shift($host); 01243 } 01244 return $pageUid; 01245 } else { 01246 return $this->sys_page->getDomainStartPage(t3lib_div::getIndpEnv('HTTP_HOST'),t3lib_div::getIndpEnv('SCRIPT_NAME'),t3lib_div::getIndpEnv('REQUEST_URI')); 01247 } 01248 } 01249 01257 function pageNotFoundAndExit($reason='', $header='') { 01258 $header = $header ? $header : $this->TYPO3_CONF_VARS['FE']['pageNotFound_handling_statheader']; 01259 $this->pageNotFoundHandler($this->TYPO3_CONF_VARS['FE']['pageNotFound_handling'], $header, $reason); 01260 exit; 01261 } 01262 01272 function pageNotFoundHandler($code, $header='', $reason='') { 01273 // Issue header in any case: 01274 if ($header) {header($header);} 01275 01276 // Create response: 01277 if (gettype($code)=='boolean' || !strcmp($code,1)) { // Simply boolean; Just shows TYPO3 error page with reason: 01278 $this->printError('The page did not exist or was inaccessible.'.($reason ? ' Reason: '.htmlspecialchars($reason) : '')); 01279 exit; 01280 } elseif (t3lib_div::isFirstPartOfStr($code,'USER_FUNCTION:')) { 01281 $funcRef = trim(substr($code,14)); 01282 $params = array( 01283 'currentUrl' => t3lib_div::getIndpEnv('REQUEST_URI'), 01284 'reasonText' => $reason, 01285 'pageAccessFailureReasons' => $this->getPageAccessFailureReasons() 01286 ); 01287 echo t3lib_div::callUserFunction($funcRef,$params,$this); 01288 exit; 01289 } elseif (t3lib_div::isFirstPartOfStr($code,'READFILE:')) { 01290 $readFile = t3lib_div::getFileAbsFileName(trim(substr($code,9))); 01291 if (@is_file($readFile)) { 01292 $fileContent = t3lib_div::getUrl($readFile); 01293 $fileContent = str_replace('###CURRENT_URL###', t3lib_div::getIndpEnv('REQUEST_URI'), $fileContent); 01294 $fileContent = str_replace('###REASON###', htmlspecialchars($reason), $fileContent); 01295 echo $fileContent; 01296 } else { 01297 $this->printError('Configuration Error: 404 page "'.$readFile.'" could not be found.'); 01298 } 01299 exit; 01300 } elseif (strlen($code)) { 01301 header('Location: '.t3lib_div::locationHeaderUrl($code)); 01302 exit; 01303 } else { 01304 $this->printError('Error.'.($reason ? ' Reason: '.htmlspecialchars($reason) : '')); 01305 exit; 01306 } 01307 } 01308 01316 function checkAndSetAlias() { 01317 if ($this->id && !t3lib_div::testInt($this->id)) { 01318 $aid = $this->sys_page->getPageIdFromAlias($this->id); 01319 if ($aid) { 01320 $this->id = $aid; 01321 } else { 01322 $this->pageNotFound = 4; 01323 } 01324 } 01325 } 01326 01335 function idPartsAnalyze($str) { 01336 $GET_VARS = ''; 01337 switch(substr($str,0,2)) { 01338 case 'B6': 01339 $addParams = base64_decode(str_replace('_','=',str_replace('-','/',substr($str,2)))); 01340 parse_str($addParams,$GET_VARS); 01341 break; 01342 case 'M5': 01343 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('params', 'cache_md5params', 'md5hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr(substr($str,2), 'cache_md5params')); 01344 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); 01345 01346 $this->updateMD5paramsRecord(substr($str,2)); 01347 parse_str($row['params'],$GET_VARS); 01348 break; 01349 } 01350 01351 $this->mergingWithGetVars($GET_VARS); 01352 } 01353 01360 function mergingWithGetVars($GET_VARS) { 01361 if (is_array($GET_VARS)) { 01362 $realGet = t3lib_div::_GET(); // Getting $_GET var, unescaped. 01363 if (!is_array($realGet)) $realGet = array(); 01364 01365 // Merge new values on top: 01366 $realGet = t3lib_div::array_merge_recursive_overrule($realGet,$GET_VARS); 01367 01368 // Write values back to $_GET: 01369 t3lib_div::_GETset($realGet); 01370 01371 // Setting these specifically (like in the init-function): 01372 if (isset($GET_VARS['type'])) $this->type = intval($GET_VARS['type']); 01373 if (isset($GET_VARS['cHash'])) $this->cHash = $GET_VARS['cHash']; 01374 if (isset($GET_VARS['jumpurl'])) $this->jumpurl = $GET_VARS['jumpurl']; 01375 if (isset($GET_VARS['MP'])) $this->MP = $this->TYPO3_CONF_VARS['FE']['enable_mount_pids'] ? $GET_VARS['MP'] : ''; 01376 01377 if (isset($GET_VARS['no_cache']) && $GET_VARS['no_cache']) $this->set_no_cache(); 01378 } 01379 } 01380 01390 function ADMCMD_preview(){ 01391 $inputCode = t3lib_div::_GP('ADMCMD_prev'); 01392 01393 if ($inputCode) { 01394 01395 // Look for keyword configuration record: 01396 list($previewData) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 01397 '*', 01398 'sys_preview', 01399 'keyword='.$GLOBALS['TYPO3_DB']->fullQuoteStr($inputCode, 'sys_preview'). 01400 ' AND endtime>'.time() 01401 ); 01402 01403 // Get: Backend login status, Frontend login status 01404 // - Make sure to remove fe/be cookies (temporarily); BE already done in ADMCMD_preview_postInit() 01405 if (is_array($previewData)) { 01406 if (!count(t3lib_div::_POST())) { 01407 if (t3lib_div::getIndpEnv('TYPO3_SITE_URL').'?ADMCMD_prev='.$inputCode === t3lib_div::getIndpEnv('TYPO3_REQUEST_URL')) { 01408 01409 // Unserialize configuration: 01410 $previewConfig = unserialize($previewData['config']); 01411 01412 // Set GET variables: 01413 $GET_VARS = ''; 01414 parse_str($previewConfig['getVars'], $GET_VARS); 01415 t3lib_div::_GETset($GET_VARS); 01416 01417 // Return preview keyword configuration: 01418 return $previewConfig; 01419 } else die(htmlspecialchars('Request URL did not match "'.t3lib_div::getIndpEnv('TYPO3_SITE_URL').'?ADMCMD_prev='.$inputCode.'"')); // This check is to prevent people from setting additional GET vars via realurl or other URL path based ways of passing parameters. 01420 } else die('POST requests are incompatible with keyword preview.'); 01421 } else die('ADMCMD command could not be executed! (No keyword configuration found)'); 01422 } 01423 } 01424 01433 function ADMCMD_preview_postInit($previewConfig){ 01434 if (is_array($previewConfig)) { 01435 01436 // Clear cookies: 01437 unset($_COOKIE['be_typo_user']); 01438 $this->ADMCMD_preview_BEUSER_uid = $previewConfig['BEUSER_uid']; 01439 01440 } else die('Error in preview configuration.'); 01441 } 01442 01443 01444 01445 01446 01447 01448 01449 01450 01451 01452 01453 /******************************************** 01454 * 01455 * Template and caching related functions. 01456 * 01457 *******************************************/ 01458 01465 function makeCacheHash() { 01466 $GET = t3lib_div::_GET(); 01467 if ($this->cHash && is_array($GET)) { 01468 $this->cHash_array = t3lib_div::cHashParams(t3lib_div::implodeArrayForUrl('',$GET)); 01469 $cHash_calc = t3lib_div::shortMD5(serialize($this->cHash_array)); 01470 01471 if ($cHash_calc!=$this->cHash) { 01472 if ($this->TYPO3_CONF_VARS['FE']['pageNotFoundOnCHashError']) { 01473 $this->pageNotFoundAndExit('Request parameters could not be validated (&cHash comparison failed)'); 01474 } else { 01475 $this->set_no_cache(); 01476 $GLOBALS['TT']->setTSlogMessage('The incoming cHash "'.$this->cHash.'" and calculated cHash "'.$cHash_calc.'" did not match, so caching was disabled. The fieldlist used was "'.implode(',',array_keys($this->cHash_array)).'"',2); 01477 } 01478 } 01479 } 01480 } 01481 01489 function reqCHash() { 01490 if (!$this->cHash) { 01491 if ($this->TYPO3_CONF_VARS['FE']['pageNotFoundOnCHashError']) { 01492 if ($this->tempContent) { $this->clearPageCacheContent(); } 01493 $this->pageNotFoundAndExit('Request parameters could not be validated (&cHash empty)'); 01494 } else { 01495 $this->set_no_cache(); 01496 $GLOBALS['TT']->setTSlogMessage('TSFE->reqCHash(): No &cHash parameter was sent for GET vars though required so caching is disabled ',2); 01497 } 01498 } 01499 } 01500 01511 function cHashParams($addQueryParams) { 01512 return t3lib_div::cHashParams($addQueryParams); 01513 } 01514 01520 function initTemplate() { 01521 $this->tmpl = t3lib_div::makeInstance('t3lib_TStemplate'); 01522 $this->tmpl->init(); 01523 $this->tmpl->tt_track= $this->beUserLogin ? 1 : 0; 01524 } 01525 01532 function getFromCache() { 01533 $this->tmpl->getCurrentPageData(); 01534 $cc = Array(); 01535 if (is_array($this->tmpl->currentPageData)) { 01536 // BE CAREFULL to change the content of the cc-array. This array is serialized and an md5-hash based on this is used for caching the page. 01537 // If this hash is not the same in here in this section and after page-generation the page will not be properly cached! 01538 01539 $cc['all'] = $this->tmpl->currentPageData['all']; 01540 $cc['rowSum'] = $this->tmpl->currentPageData['rowSum']; 01541 $cc['rootLine'] = $this->tmpl->currentPageData['rootLine']; // This rootline is used with templates only (matching()-function) 01542 $this->all = $this->tmpl->matching($cc); // This array is an identification of the template. If $this->all is empty it's because the template-data is not cached, which it must be. 01543 ksort($this->all); 01544 } 01545 01546 $this->content=''; // clearing the content-variable, which will hold the pagecontent 01547 unset($this->config); // Unsetting the lowlevel config 01548 $this->cacheContentFlag = 0; 01549 01550 // Look for page in cache only if caching is not disabled and if a shift-reload is not sent to the server. 01551 if ($this->all && !$this->no_cache && !$this->headerNoCache()) { 01552 01553 $this->newHash = $this->getHash(); 01554 01555 $GLOBALS['TT']->push('Cache Row',''); 01556 if ($row = $this->getFromCache_queryRow()) { 01557 01558 $this->config = (array)unserialize($row['cache_data']); // Fetches the lowlevel config stored with the cached data 01559 $this->content = $row['HTML']; // Getting the content 01560 $this->tempContent = $row['temp_content']; // Flag for temp content 01561 $this->cacheContentFlag = 1; // Setting flag, so we know, that some cached content is gotten. 01562 $this->cacheExpires = $row['expires']; 01563 01564 if ($this->TYPO3_CONF_VARS['FE']['debug'] || $this->config['config']['debug']) { 01565 $this->content.=chr(10).'<!-- Cached page generated '.Date('d/m Y H:i', $row['tstamp']).'. Expires '.Date('d/m Y H:i', $row['expires']).' -->'; 01566 } 01567 01568 } 01569 $GLOBALS['TT']->pull(); 01570 } 01571 } 01572 01578 function getFromCache_queryRow() { 01579 01580 $GLOBALS['TT']->push('Cache Query',''); 01581 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 01582 'S.*', 01583 'cache_pages S,pages P', 01584 'S.hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->newHash, 'cache_pages').' 01585 AND S.page_id=P.uid 01586 AND S.expires > '.intval($GLOBALS['EXEC_TIME']).' 01587 AND P.deleted=0 01588 AND P.hidden=0 01589 AND P.starttime<='.intval($GLOBALS['EXEC_TIME']).' 01590 AND (P.endtime=0 OR P.endtime>'.intval($GLOBALS['EXEC_TIME']).')' 01591 ); 01592 $GLOBALS['TT']->pull(); 01593 01594 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 01595 $this->pageCachePostProcess($row,'get'); 01596 } 01597 $GLOBALS['TYPO3_DB']->sql_free_result($res); 01598 return $row; 01599 } 01600 01608 function headerNoCache() { 01609 $disableAcquireCacheData = FALSE; 01610 01611 if ($this->beUserLogin) { 01612 if (strtolower($_SERVER['HTTP_CACHE_CONTROL'])==='no-cache' || strtolower($_SERVER['HTTP_PRAGMA'])==='no-cache') { 01613 $disableAcquireCacheData = TRUE; 01614 } 01615 } 01616 01617 // Call hook for possible by-pass of requiring of page cache (for recaching purpose) 01618 if (is_array($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['headerNoCache'])) { 01619 $_params = array('pObj' => &$this, 'disableAcquireCacheData' => &$disableAcquireCacheData); 01620 foreach($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['headerNoCache'] as $_funcRef) { 01621 t3lib_div::callUserFunction($_funcRef,$_params,$this); 01622 } 01623 } 01624 01625 return $disableAcquireCacheData; 01626 } 01627 01637 function getHash() { 01638 $this->hash_base = serialize( 01639 array( 01640 'all' => $this->all, 01641 'id' => intval($this->id), 01642 'type' => intval($this->type), 01643 'gr_list' => (string)$this->gr_list, 01644 'MP' => (string)$this->MP, 01645 'cHash' => $this->cHash_array 01646 ) 01647 ); 01648 01649 return md5($this->hash_base); 01650 } 01651 01657 function getConfigArray() { 01658 $setStatPageName = false; 01659 01660 if (!is_array($this->config) || is_array($this->config['INTincScript']) || $this->forceTemplateParsing) { // If config is not set by the cache (which would be a major mistake somewhere) OR if INTincScripts-include-scripts have been registered, then we must parse the template in order to get it 01661 $GLOBALS['TT']->push('Parse template',''); 01662 01663 // Force parsing, if set?: 01664 $this->tmpl->forceTemplateParsing = $this->forceTemplateParsing; 01665 01666 // Start parsing the TS template. Might return cached version. 01667 $this->tmpl->start($this->rootLine); 01668 $GLOBALS['TT']->pull(); 01669 01670 if ($this->tmpl->loaded) { 01671 $GLOBALS['TT']->push('Setting the config-array',''); 01672 // t3lib_div::print_array($this->tmpl->setup); 01673 $this->sPre = $this->tmpl->setup['types.'][$this->type]; // toplevel - objArrayName 01674 $this->pSetup = $this->tmpl->setup[$this->sPre.'.']; 01675 01676 if (!is_array($this->pSetup)) { 01677 $this->printError('The page is not configured! [type= '.$this->type.']['.$this->sPre.']'); 01678 exit; 01679 } else { 01680 $this->config['config']=Array(); 01681 01682 // Filling the config-array. 01683 if (is_array($this->tmpl->setup['config.'])) { 01684 $this->config['config'] = $this->tmpl->setup['config.']; 01685 } 01686 if (is_array($this->pSetup['config.'])) { 01687 reset($this->pSetup['config.']); 01688 while(list($theK,$theV)=each($this->pSetup['config.'])) { 01689 $this->config['config'][$theK] = $theV; 01690 } 01691 } 01692 // if .simulateStaticDocuments was not present, the default value will rule. 01693 if (!isset($this->config['config']['simulateStaticDocuments'])) { 01694 $this->config['config']['simulateStaticDocuments'] = trim($this->TYPO3_CONF_VARS['FE']['simulateStaticDocuments']); 01695 } 01696 if ($this->config['config']['simulateStaticDocuments']) { 01697 // Set replacement char only if it is needed 01698 $this->setSimulReplacementChar(); 01699 } 01700 01701 // set default values for removeDefaultJS and inlineStyle2TempFile so CSS and JS are externalized if compatversion is higher than 4.0 01702 if(!isset($this->config['config']['removeDefaultJS']) && t3lib_div::compat_version('4.0.0')) { 01703 $this->config['config']['removeDefaultJS'] = 'external'; 01704 } 01705 if(!isset($this->config['config']['inlineStyle2TempFile']) && t3lib_div::compat_version('4.0.0')) { 01706 $this->config['config']['inlineStyle2TempFile'] = 1; 01707 } 01708 01709 // Processing for the config_array: 01710 $this->config['rootLine'] = $this->tmpl->rootLine; 01711 $this->config['mainScript'] = trim($this->config['config']['mainScript']) ? trim($this->config['config']['mainScript']) : 'index.php'; 01712 01713 // STAT: 01714 $theLogFile = $this->TYPO3_CONF_VARS['FE']['logfile_dir'].$this->config['config']['stat_apache_logfile']; 01715 // Add PATH_site left to $theLogFile if the path is not absolute yet 01716 if (!t3lib_div::isAbsPath($theLogFile)) $theLogFile = PATH_site.$theLogFile; 01717 01718 if ($this->config['config']['stat_apache'] && $this->config['config']['stat_apache_logfile'] && !strstr($this->config['config']['stat_apache_logfile'],'/')) { 01719 if (t3lib_div::isAllowedAbsPath($theLogFile)) { 01720 if (!@is_file($theLogFile)) { 01721 touch($theLogFile); // Try to create the logfile 01722 t3lib_div::fixPermissions($theLogFile); 01723 } 01724 01725 if (@is_file($theLogFile) && @is_writable($theLogFile)) { 01726 $this->config['stat_vars']['logFile'] = $theLogFile; 01727 $setStatPageName = true; // Set page name later on 01728 } else { 01729 $GLOBALS['TT']->setTSlogMessage('Could not set logfile path. Check filepath and permissions.',3); 01730 } 01731 } 01732 } 01733 01734 $this->config['FEData'] = $this->tmpl->setup['FEData']; 01735 $this->config['FEData.'] = $this->tmpl->setup['FEData.']; 01736 } 01737 $GLOBALS['TT']->pull(); 01738 } else { 01739 $this->printError('No template found!'); 01740 exit; 01741 } 01742 } 01743 01744 // Initialize charset settings etc. 01745 $this->initLLvars(); 01746 01747 // We want nice names, so we need to know the charset 01748 if ($setStatPageName) { 01749 if ($this->config['config']['stat_apache_niceTitle']) { 01750 $shortTitle = $this->csConvObj->specCharsToASCII($this->renderCharset,$this->page['title']); 01751 } else { 01752 $shortTitle = $this->page['title']; 01753 } 01754 $shortTitle = substr(preg_replace('/[^.[:alnum:]_-]/','_',$shortTitle),0,30); 01755 $pageName = $this->config['config']['stat_apache_pagenames'] ? $this->config['config']['stat_apache_pagenames'] : '[path][title]--[uid].html'; 01756 $pageName = str_replace('[title]', $shortTitle ,$pageName); 01757 $pageName = str_replace('[uid]',$this->page['uid'],$pageName); 01758 $pageName = str_replace('[alias]',$this->page['alias'],$pageName); 01759 $pageName = str_replace('[type]',$this->type,$pageName); 01760 $temp = $this->config['rootLine']; 01761 array_pop($temp); 01762 if ($this->config['config']['stat_apache_noRoot']) { 01763 array_shift($temp); 01764 } 01765 $len = t3lib_div::intInRange($this->config['config']['stat_titleLen'],1,100,20); 01766 if ($this->config['config']['stat_apache_niceTitle']) { 01767 $path = $this->csConvObj->specCharsToASCII($this->renderCharset,$this->sys_page->getPathFromRootline($temp,$len)); 01768 } else { 01769 $path = $this->sys_page->getPathFromRootline($temp,$len); 01770 } 01771 $this->config['stat_vars']['pageName'] = str_replace('[path]', preg_replace('/[^.[:alnum:]\/_-]/','_',$path.'/'), $pageName); 01772 } 01773 01774 // No cache 01775 if ($this->config['config']['no_cache']) { $this->set_no_cache(); } // Set $this->no_cache true if the config.no_cache value is set! 01776 01777 // Check PATH_INFO url 01778 if ($this->absRefPrefix_force && strcmp($this->config['config']['simulateStaticDocuments'],'PATH_INFO')) { 01779 $redirectUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_DIR').'index.php?id='.$this->id.'&type='.$this->type; 01780 if ($this->config['config']['simulateStaticDocuments_dontRedirectPathInfoError']) { 01781 $this->printError('PATH_INFO was not configured for this website, and the URL tries to find the page by PATH_INFO!<br /><br /><a href="'.htmlspecialchars($redirectUrl).'">Click here to get to the right page.</a>','Error: PATH_INFO not configured'); 01782 } else { 01783 header('Location: '.t3lib_div::locationHeaderUrl($redirectUrl)); 01784 } 01785 exit; 01786 // $this->set_no_cache(); // Set no_cache if PATH_INFO is NOT used as simulateStaticDoc. and if absRefPrefix_force shows that such an URL has been passed along. 01787 } 01788 } 01789 01790 01791 01792 01793 01794 01795 01796 01797 01798 01799 01800 01801 01802 01803 /******************************************** 01804 * 01805 * Further initialization and data processing 01806 * (jumpurl/submission of forms) 01807 * 01808 *******************************************/ 01809 01818 function getCompressedTCarray() { 01819 global $TCA; 01820 01821 $GLOBALS['TT']->push('Get Compressed TC array'); 01822 if (!$this->TCAloaded) { 01823 // Create hash string for storage / retrieval of cached content: 01824 $tempHash = md5('tables.php:'. 01825 filemtime(TYPO3_extTableDef_script ? PATH_typo3conf.TYPO3_extTableDef_script : PATH_t3lib.'stddb/tables.php'). 01826 (TYPO3_extTableDef_script?filemtime(PATH_typo3conf.TYPO3_extTableDef_script):''). 01827 ($GLOBALS['TYPO3_LOADED_EXT']['_CACHEFILE'] ? filemtime(PATH_typo3conf.$GLOBALS['TYPO3_LOADED_EXT']['_CACHEFILE'].'_ext_tables.php') : '') 01828 ); 01829 // Try to fetch if: 01830 list($TCA,$this->TCAcachedExtras) = unserialize($this->sys_page->getHash($tempHash, 0)); 01831 // If no result, create it: 01832 if (!is_array($TCA)) { 01833 $this->includeTCA(0); 01834 $newTc = Array(); 01835 $this->TCAcachedExtras = array(); // Collects other information 01836 01837 foreach($TCA as $key => $val) { 01838 $newTc[$key]['ctrl'] = $val['ctrl']; 01839 $newTc[$key]['feInterface'] = $val['feInterface']; 01840 01841 // Collect information about localization exclusion of fields: 01842 t3lib_div::loadTCA($key); 01843 if (is_array($TCA[$key]['columns'])) { 01844 $this->TCAcachedExtras[$key]['l10n_mode'] = array(); 01845 foreach($TCA[$key]['columns'] as $fN => $fV) { 01846 if ($fV['l10n_mode']) { 01847 $this->TCAcachedExtras[$key]['l10n_mode'][$fN] = $fV['l10n_mode']; 01848 } 01849 } 01850 } 01851 } 01852 01853 // Store it in cache: 01854 $TCA = $newTc; 01855 $this->sys_page->storeHash($tempHash, serialize(array($newTc,$this->TCAcachedExtras)), 'SHORT TC'); 01856 } 01857 } 01858 $GLOBALS['TT']->pull(); 01859 } 01860 01872 function includeTCA($TCAloaded=1) { 01873 global $TCA, $PAGES_TYPES, $LANG_GENERAL_LABELS, $TBE_MODULES; 01874 if (!$this->TCAloaded) { 01875 $TCA = Array(); 01876 include (TYPO3_tables_script ? PATH_typo3conf.TYPO3_tables_script : PATH_t3lib.'stddb/tables.php'); 01877 // Extension additions 01878 if ($GLOBALS['TYPO3_LOADED_EXT']['_CACHEFILE']) { 01879 include(PATH_typo3conf.$GLOBALS['TYPO3_LOADED_EXT']['_CACHEFILE'].'_ext_tables.php'); 01880 } else { 01881 include(PATH_t3lib.'stddb/load_ext_tables.php'); 01882 } 01883 // ext-script 01884 if (TYPO3_extTableDef_script) { 01885 include (PATH_typo3conf.TYPO3_extTableDef_script); 01886 } 01887 01888 $this->TCAloaded = $TCAloaded; 01889 } 01890 } 01891 01899 function settingLanguage() { 01900 01901 // Get values from TypoScript: 01902 $this->sys_language_uid = $this->sys_language_content = intval($this->config['config']['sys_language_uid']); 01903 list($this->sys_language_mode,$sys_language_content) = t3lib_div::trimExplode(';', $this->config['config']['sys_language_mode']); 01904 $this->sys_language_contentOL = $this->config['config']['sys_language_overlay']; 01905 01906 // If sys_language_uid is set to another language than default: 01907 if ($this->sys_language_uid>0) { 01908 // Request the overlay record for the sys_language_uid: 01909 $olRec = $this->sys_page->getPageOverlay($this->id, $this->sys_language_uid); 01910 if (!count($olRec)) { 01911 01912 // If no OL record exists and a foreign language is asked for... 01913 if ($this->sys_language_uid) { 01914 01915 // If requested translation is not available: 01916 if (t3lib_div::hideIfNotTranslated($this->page['l18n_cfg'])) { 01917 $this->pageNotFoundAndExit('Page is not available in the requested language.'); 01918 } else { 01919 switch((string)$this->sys_language_mode) { 01920 case 'strict': 01921 $this->pageNotFoundAndExit('Page is not available in the requested language (strict).'); 01922 break; 01923 case 'content_fallback': 01924 $fallBackOrder = t3lib_div::intExplode(',', $sys_language_content); 01925 foreach($fallBackOrder as $orderValue) { 01926 if (!strcmp($orderValue,'0') || count($this->sys_page->getPageOverlay($this->id, $orderValue))) { 01927 $this->sys_language_content = $orderValue; // Setting content uid (but leaving the sys_language_uid) 01928 break; 01929 } 01930 } 01931 break; 01932 case 'ignore': 01933 $this->sys_language_content = $this->sys_language_uid; 01934 break; 01935 default: 01936 // Default is that everything defaults to the default language... 01937 $this->sys_language_uid = $this->sys_language_content = 0; 01938 break; 01939 } 01940 } 01941 } 01942 } else { 01943 // Setting sys_language if an overlay record was found (which it is only if a language is used) 01944 $this->page = $this->sys_page->getPageOverlay($this->page, $this->sys_language_uid); 01945 } 01946 } 01947 01948 // Setting sys_language_uid inside sys-page: 01949 $this->sys_page->sys_language_uid = $this->sys_language_uid; 01950 01951 // If default translation is not available: 01952 if ((!$this->sys_language_uid || !$this->sys_language_content) && $this->page['l18n_cfg']&1) { 01953 $this->pageNotFoundAndExit('Page is not available in default language.'); 01954 } 01955 01956 // Updating content of the two rootLines IF the language key is set! 01957 if ($this->sys_language_uid && is_array($this->tmpl->rootLine)) { 01958 reset($this->tmpl->rootLine); 01959 while(list($rLk)=each($this->tmpl->rootLine)) { 01960 $this->tmpl->rootLine[$rLk] = $this->sys_page->getPageOverlay($this->tmpl->rootLine[$rLk]); 01961 } 01962 } 01963 if ($this->sys_language_uid && is_array($this->rootLine)) { 01964 reset($this->rootLine); 01965 while(list($rLk)=each($this->rootLine)) { 01966 $this->rootLine[$rLk] = $this->sys_page->getPageOverlay($this->rootLine[$rLk]); 01967 } 01968 } 01969 01970 // Finding the ISO code: 01971 if (t3lib_extMgm::isLoaded('static_info_tables') && $this->sys_language_content) { // using sys_language_content because the ISO code only (currently) affect content selection from FlexForms - which should follow "sys_language_content" 01972 $sys_language_row = $this->sys_page->getRawRecord('sys_language',$this->sys_language_content,'static_lang_isocode'); 01973 if (is_array($sys_language_row) && $sys_language_row['static_lang_isocode']) { 01974 $stLrow = $this->sys_page->getRawRecord('static_languages',$sys_language_row['static_lang_isocode'],'lg_iso_2'); 01975 $this->sys_language_isocode = $stLrow['lg_iso_2']; 01976 } 01977 } 01978 01979 // Setting softMergeIfNotBlank: 01980 $table_fields = t3lib_div::trimExplode(',', $this->config['config']['sys_language_softMergeIfNotBlank'],1); 01981 foreach($table_fields as $TF) { 01982 list($tN,$fN) = explode(':',$TF); 01983 $this->TCAcachedExtras[$tN]['l10n_mode'][$fN] = 'mergeIfNotBlank'; 01984 } 01985 } 01986 01992 function settingLocale() { 01993 01994 // Setting locale 01995 if ($this->config['config']['locale_all']) { 01996 # Change by Rene Fritz, 22/10 2002 01997 # there's a problem that PHP parses float values in scripts wrong if the locale LC_NUMERIC is set to something with a comma as decimal point 01998 # this does not work in php 4.2.3 01999 #setlocale('LC_ALL',$this->config['config']['locale_all']); 02000 #setlocale('LC_NUMERIC','en_US'); 02001 02002 # so we set all except LC_NUMERIC 02003 setlocale(LC_COLLATE,$this->config['config']['locale_all']); 02004 setlocale(LC_CTYPE,$this->config['config']['locale_all']); 02005 setlocale(LC_MONETARY,$this->config['config']['locale_all']); 02006 setlocale(LC_TIME,$this->config['config']['locale_all']); 02007 02008 $this->localeCharset = $this->csConvObj->get_locale_charset($this->config['config']['locale_all']); 02009 } 02010 } 02011 02017 function checkDataSubmission() { 02018 $ret = ''; 02019 if ($_POST['formtype_db'] || $_POST['formtype_mail']) { 02020 $refInfo = parse_url(t3lib_div::getIndpEnv('HTTP_REFERER')); 02021 if (t3lib_div::getIndpEnv('TYPO3_HOST_ONLY')==$refInfo['host'] || $this->TYPO3_CONF_VARS['SYS']['doNotCheckReferer']) { 02022 if ($this->locDataCheck($_POST['locationData'])) { 02023 if ($_POST['formtype_mail']) { 02024 $ret = 'email'; 02025 } elseif ($_POST['formtype_db'] && is_array($_POST['data'])) { 02026 $ret = 'fe_tce'; 02027 } 02028 $GLOBALS['TT']->setTSlogMessage('"Check Data Submission": Return value: '.$ret,0); 02029 return $ret; 02030 } 02031 } else $GLOBALS['TT']->setTSlogMessage('"Check Data Submission": HTTP_HOST and REFERER HOST did not match when processing submitted formdata!',3); 02032 } 02033 02034 // Hook for processing data submission to extensions: 02035 if (is_array($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['checkDataSubmission'])) { 02036 foreach($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['checkDataSubmission'] as $_classRef) { 02037 $_procObj = &t3lib_div::getUserObj($_classRef); 02038 $_procObj->checkDataSubmission($this); 02039 } 02040 } 02041 return $ret; 02042 } 02043 02051 function fe_tce() { 02052 $fe_tce = t3lib_div::makeInstance('tslib_feTCE'); 02053 $fe_tce->start(t3lib_div::_POST('data'),$this->config['FEData.']); 02054 $fe_tce->includeScripts(); 02055 } 02056 02065 function locDataCheck($locationData) { 02066 $locData = explode(':',$locationData); 02067 if (!$locData[1] || $this->sys_page->checkRecord($locData[1],$locData[2],1)) { 02068 if (count($this->sys_page->getPage($locData[0]))) { // $locData[1] -check means that a record is checked only if the locationData has a value for a record else than the page. 02069 return 1; 02070 } else $GLOBALS['TT']->setTSlogMessage('LocationData Error: The page pointed to by location data ('.$locationData.') was not accessible.',2); 02071 } else $GLOBALS['TT']->setTSlogMessage('LocationData Error: Location data ('.$locationData.') record pointed to was not accessible.',2); 02072 } 02073 02081 function sendFormmail() { 02082 $formmail = t3lib_div::makeInstance('t3lib_formmail'); 02083 02084 $EMAIL_VARS = t3lib_div::_POST(); 02085 $locationData = $EMAIL_VARS['locationData']; 02086 unset($EMAIL_VARS['locationData']); 02087 unset($EMAIL_VARS['formtype_mail']); 02088 02089 $integrityCheck = $this->TYPO3_CONF_VARS['FE']['strictFormmail']; 02090 02091 if(!$this->TYPO3_CONF_VARS['FE']['secureFormmail']) { 02092 // Check recipient field: 02093 $encodedFields = explode(',','recipient,recipient_copy'); // These two fields are the ones which contain recipient addresses that can be misused to send mail from foreign servers. 02094 foreach($encodedFields as $fieldKey) { 02095 if (strlen($EMAIL_VARS[$fieldKey])) { 02096 if ($res = $this->codeString($EMAIL_VARS[$fieldKey], TRUE)) { // Decode... 02097 $EMAIL_VARS[$fieldKey] = $res; // Set value if OK 02098 } elseif ($integrityCheck) { // Otherwise abort: 02099 $GLOBALS['TT']->setTSlogMessage('"Formmail" discovered a field ('.$fieldKey.') which could not be decoded to a valid string. Sending formmail aborted due to security reasons!',3); 02100 return false; 02101 } else { 02102 $GLOBALS['TT']->setTSlogMessage('"Formmail" discovered a field ('.$fieldKey.') which could not be decoded to a valid string. The security level accepts this, but you should consider a correct coding though!',2); 02103 } 02104 } 02105 } 02106 } else { 02107 $locData = explode(':',$locationData); 02108 $record = $this->sys_page->checkRecord($locData[1],$locData[2],1); 02109 $EMAIL_VARS['recipient'] = $record['subheader']; 02110 $EMAIL_VARS['recipient_copy'] = $this->extractRecipientCopy($record['bodytext']); 02111 } 02112 02113 // Hook for preprocessing of the content for formmails: 02114 if (is_array($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['sendFormmail-PreProcClass'])) { 02115 foreach($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['sendFormmail-PreProcClass'] as $_classRef) { 02116 $_procObj = &t3lib_div::getUserObj($_classRef); 02117 $EMAIL_VARS = $_procObj->sendFormmail_preProcessVariables($EMAIL_VARS,$this); 02118 } 02119 } 02120 02121 $formmail->start($EMAIL_VARS); 02122 $formmail->sendtheMail(); 02123 $GLOBALS['TT']->setTSlogMessage('"Formmail" invoked, sending mail to '.$EMAIL_VARS['recipient'],0); 02124 } 02125 02132 function extractRecipientCopy($bodytext) { 02133 $recipient_copy = ''; 02134 $fdef = array(); 02135 //|recipient_copy=hidden|karsten@localhost.localdomain 02136 preg_match('/^[\s]*\|[\s]*recipient_copy[\s]*=[\s]*hidden[\s]*\|(.*)$/m', $bodytext, $fdef); 02137 $recipient_copy = (!empty($fdef[1])) ? $fdef[1] : ''; 02138 return $recipient_copy; 02139 } 02140 02146 function setExternalJumpUrl() { 02147 if ($extUrl = $this->sys_page->getExtURL($this->page, $this->config['config']['disablePageExternalUrl'])) { 02148 $this->jumpurl = $extUrl; 02149 } 02150 } 02151 02157 function checkJumpUrlReferer() { 02158 if (strcmp($this->jumpurl,'') && !$this->TYPO3_CONF_VARS['SYS']['doNotCheckReferer']) { 02159 $referer = parse_url(t3lib_div::getIndpEnv('HTTP_REFERER')); 02160 if (isset($referer['host']) && !($referer['host'] == t3lib_div::getIndpEnv('TYPO3_HOST_ONLY'))) { 02161 unset($this->jumpurl); 02162 } 02163 } 02164 } 02165 02172 function jumpUrl() { 02173 if ($this->jumpurl) { 02174 if (t3lib_div::_GP('juSecure')) { 02175 $hArr = array( 02176 $this->jumpurl, 02177 t3lib_div::_GP('locationData'), 02178 $this->TYPO3_CONF_VARS['SYS']['encryptionKey'] 02179 ); 02180 $calcJuHash=t3lib_div::shortMD5(serialize($hArr)); 02181 $locationData = t3lib_div::_GP('locationData'); 02182 $juHash = t3lib_div::_GP('juHash'); 02183 if ($juHash == $calcJuHash) { 02184 if ($this->locDataCheck($locationData)) { 02185 $this->jumpurl = rawurldecode($this->jumpurl); // 211002 - goes with cObj->filelink() rawurlencode() of filenames so spaces can be allowed. 02186 if (@is_file($this->jumpurl)) { 02187 $mimeType = t3lib_div::_GP('mimeType'); 02188 $mimeType = $mimeType ? $mimeType : 'application/octet-stream'; 02189 Header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 02190 Header('Content-Type: '.$mimeType); 02191 Header('Content-Disposition: attachment; filename='.basename($this->jumpurl)); 02192 readfile($this->jumpurl); 02193 exit; 02194 } else die('jumpurl Secure: "'.$this->jumpurl.'" was not a valid file!'); 02195 } else die('jumpurl Secure: locationData, '.$locationData.', was not accessible.'); 02196 } else die('jumpurl Secure: Calculated juHash, '.$calcJuHash.', did not match the submitted juHash.'); 02197 } else { 02198 $TSConf = $this->getPagesTSconfig(); 02199 if ($TSConf['TSFE.']['jumpUrl_transferSession']) { 02200 $uParts = parse_url($this->jumpurl); 02201 $params = '&FE_SESSION_KEY='.rawurlencode($this->fe_user->id.'-'.md5($this->fe_user->id.'/'.$this->TYPO3_CONF_VARS['SYS']['encryptionKey'])); 02202 $this->jumpurl.=($uParts['query']?'':'?').$params; // Add the session parameter ... 02203 } 02204 Header('Location: '.$this->jumpurl); 02205 exit; 02206 } 02207 } 02208 } 02209 02216 function setUrlIdToken() { 02217 if ($this->config['config']['ftu']) { 02218 $this->getMethodUrlIdToken = $this->TYPO3_CONF_VARS['FE']['get_url_id_token']; 02219 } else { 02220 $this->getMethodUrlIdToken = ''; 02221 } 02222 } 02223 02224 02225 02226 02227 02228 02229 02230 02231 02232 02233 02234 02235 02236 02237 02238 02239 02240 02241 02242 02243 02244 02245 02246 02247 /******************************************** 02248 * 02249 * Page generation; cache handling 02250 * 02251 *******************************************/ 02252 02259 function isGeneratePage() { 02260 return (!$this->cacheContentFlag && !$this->jumpurl); 02261 } 02262 02269 function tempPageCacheContent() { 02270 $this->tempContent = false; 02271 02272 if (!$this->no_cache) { 02273 $seconds = 30; 02274 $title = htmlspecialchars($this->tmpl->printTitle($this->page['title'])); 02275 $request_uri = htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI')); 02276 02277 $stdMsg = ' 02278 <strong>Page is being generated.</strong><br /> 02279 If this message does not disappear within '.$seconds.' seconds, please reload.'; 02280 02281 $message = $this->config['config']['message_page_is_being_generated']; 02282 if (strcmp('', $message)) { 02283 $message = $this->csConvObj->utf8_encode($message,$this->renderCharset); // This page is always encoded as UTF-8 02284 $message = str_replace('###TITLE###', $title, $message); 02285 $message = str_replace('###REQUEST_URI###', $request_uri, $message); 02286 } else $message = $stdMsg; 02287 02288 $temp_content = '<?xml version="1.0" encoding="UTF-8"?> 02289 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 02290 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 02291 <html xmlns="http://www.w3.org/1999/xhtml"> 02292 <head> 02293 <title>'.$title.'</title> 02294 <meta http-equiv="refresh" content="10" /> 02295 </head> 02296 <body style="background-color:white; font-family:Verdana,Arial,Helvetica,sans-serif; color:#cccccc; text-align:center;">'. 02297 $message.' 02298 </body> 02299 </html>'; 02300 02301 // Fix 'nice errors' feature in modern browsers 02302 $padSuffix = '<!--pad-->'; // prevent any trims 02303 $padSize = 768 - strlen($padSuffix) - strlen($temp_content); 02304 if ($padSize > 0) { 02305 $temp_content = str_pad($temp_content, $padSize, "\n") . $padSuffix; 02306 } 02307 02308 if (!$this->headerNoCache() && $cachedRow = $this->getFromCache_queryRow()) { 02309 // We are here because between checking for cached content earlier and now some other HTTP-process managed to store something in cache AND it was not due to a shift-reload by-pass. 02310 // This is either the "Page is being generated" screen or it can be the final result. 02311 // In any case we should not begin another rendering process also, so we silently disable caching and render the page ourselves and thats it. 02312 // Actually $cachedRow contains content that we could show instead of rendering. Maybe we should do that to gain more performance but then we should set all the stuff done in $this->getFromCache()... For now we stick to this... 02313 $this->set_no_cache(); 02314 } else { 02315 $this->tempContent = TRUE; // This flag shows that temporary content is put in the cache 02316 $this->setPageCacheContent($temp_content, $this->config, $GLOBALS['EXEC_TIME']+$seconds); 02317 } 02318 } 02319 } 02320 02326 function realPageCacheContent() { 02327 $cache_timeout = $this->page['cache_timeout'] ? $this->page['cache_timeout'] : ($this->cacheTimeOutDefault ? $this->cacheTimeOutDefault : 60*60*24); // seconds until a cached page is too old 02328 $timeOutTime = $GLOBALS['EXEC_TIME']+$cache_timeout; 02329 if ($this->config['config']['cache_clearAtMidnight']) { 02330 $midnightTime = mktime (0,0,0,date('m',$timeOutTime),date('d',$timeOutTime),date('Y',$timeOutTime)); 02331 if ($midnightTime > $GLOBALS['EXEC_TIME']) { // If the midnight time of the expire-day is greater than the current time, we may set the timeOutTime to the new midnighttime. 02332 $timeOutTime = $midnightTime; 02333 } 02334 } 02335 $this->tempContent = false; 02336 $this->setPageCacheContent($this->content, $this->config, $timeOutTime); 02337 02338 // Hook for cache post processing (eg. writing static files!) 02339 if (is_array($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['insertPageIncache'])) { 02340 foreach($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['insertPageIncache'] as $_classRef) { 02341 $_procObj = &t3lib_div::getUserObj($_classRef); 02342 $_procObj->insertPageIncache($this,$timeOutTime); 02343 } 02344 } 02345 } 02346 02356 function setPageCacheContent($content,$data,$tstamp) { 02357 $this->clearPageCacheContent(); 02358 $insertFields = array( 02359 'hash' => $this->newHash, 02360 'page_id' => $this->id, 02361 'HTML' => $content, 02362 'temp_content' => $this->tempContent, 02363 'cache_data' => serialize($data), 02364 'expires' => $tstamp, 02365 'tstamp' => $GLOBALS['EXEC_TIME'] 02366 ); 02367 02368 $this->cacheExpires = $tstamp; 02369 02370 if ($this->page_cache_reg1) { 02371 $insertFields['reg1'] = intval($this->page_cache_reg1); 02372 } 02373 $this->pageCachePostProcess($insertFields,'set'); 02374 02375 $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_pages', $insertFields); 02376 } 02377 02383 function clearPageCacheContent() { 02384 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pages', 'hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->newHash, 'cache_pages')); 02385 } 02386 02393 function clearPageCacheContent_pidList($pidList) { 02394 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pages', 'page_id IN ('.$GLOBALS['TYPO3_DB']->cleanIntList($pidList).')'); 02395 } 02396 02404 function pageCachePostProcess(&$row,$type) { 02405 02406 if ($this->TYPO3_CONF_VARS['FE']['pageCacheToExternalFiles']) { 02407 $cacheFileName = PATH_site.'typo3temp/cache_pages/'.$row['hash']{0}.$row['hash']{1}.'/'.$row['hash'].'.html'; 02408 switch((string)$type) { 02409 case 'get': 02410 $row['HTML'] = @is_file($cacheFileName) ? t3lib_div::getUrl($cacheFileName) : '<!-- CACHING ERROR, sorry -->'; 02411 break; 02412 case 'set': 02413 t3lib_div::writeFileToTypo3tempDir($cacheFileName,$row['HTML']); 02414 $row['HTML'] = ''; 02415 break; 02416 } 02417 } 02418 } 02419 02427 function setSysLastChanged() { 02428 if ($this->page['SYS_LASTCHANGED'] < intval($this->register['SYS_LASTCHANGED'])) { 02429 $GLOBALS['TYPO3_DB']->exec_UPDATEquery('pages', 'uid='.intval($this->id), array('SYS_LASTCHANGED' => intval($this->register['SYS_LASTCHANGED']))); 02430 } 02431 } 02432 02433 02434 02435 02436 02437 02438 02439 02440 02441 02442 02443 02444 02445 02446 02447 02448 02449 02450 02451 02452 /******************************************** 02453 * 02454 * Page generation; rendering and inclusion 02455 * 02456 *******************************************/ 02457 02463 function generatePage_preProcessing() { 02464 ksort($this->all); 02465 // Same codeline as in getFromCache(). BUT $this->all has been set in the meantime, so we can't just skip this line and let it be set above! Keep this line! 02466 $this->newHash = $this->getHash(); 02467 $this->config['hash_base'] = $this->hash_base; // For cache management informational purposes. 02468 02469 // Here we put some temporary stuff in the cache in order to let the first hit generate the page. The temporary cache will expire after a few seconds (typ. 30) or will be cleared by the rendered page, which will also clear and rewrite the cache. 02470 $this->tempPageCacheContent(); 02471 02472 // Setting cache_timeout_default. May be overridden by PHP include scritps. 02473 $this->cacheTimeOutDefault = intval($this->config['config']['cache_period']); 02474 02475 // page is generated 02476 $this->no_cacheBeforePageGen = $this->no_cache; 02477 } 02478 02485 function generatePage_whichScript() { 02486 if (!$this->TYPO3_CONF_VARS['FE']['noPHPscriptInclude'] && $this->config['config']['pageGenScript']) { 02487 return $this->tmpl->getFileName($this->config['config']['pageGenScript']); 02488 } 02489 } 02490 02497 function generatePage_postProcessing() { 02498 // This is to ensure, that the page is NOT cached if the no_cache parameter was set before the page was generated. This is a safety precaution, as it could have been unset by some script. 02499 if ($this->no_cacheBeforePageGen) $this->set_no_cache(); 02500 02501 // Tidy up the code, if flag... 02502 if ($this->TYPO3_CONF_VARS['FE']['tidy_option'] == 'all') { 02503 $GLOBALS['TT']->push('Tidy, all',''); 02504 $this->content = $this->tidyHTML($this->content); 02505 $GLOBALS['TT']->pull(); 02506 } 02507 02508 // XHTML-clean the code, if flag set 02509 if ($this->doXHTML_cleaning() == 'all') { 02510 $GLOBALS['TT']->push('XHTML clean, all',''); 02511 $XHTML_clean = t3lib_div::makeInstance('t3lib_parsehtml'); 02512 $this->content = $XHTML_clean->XHTML_clean($this->content); 02513 $GLOBALS['TT']->pull(); 02514 } 02515 02516 // Fix local anchors in links, if flag set 02517 if ($this->doLocalAnchorFix() == 'all') { 02518 $GLOBALS['TT']->push('Local anchor fix, all',''); 02519 $this->prefixLocalAnchorsWithScript(); 02520 $GLOBALS['TT']->pull(); 02521 } 02522 02523 // Hook for post-processing of page content cached/non-cached: 02524 if (is_array($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-all'])) { 02525 $_params = array('pObj' => &$this); 02526 foreach($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-all'] as $_funcRef) { 02527 t3lib_div::callUserFunction($_funcRef,$_params,$this); 02528 } 02529 } 02530 02531 // Processing if caching is enabled: 02532 if (!$this->no_cache) { 02533 // Tidy up the code, if flag... 02534 if ($this->TYPO3_CONF_VARS['FE']['tidy_option'] == 'cached') { 02535 $GLOBALS['TT']->push('Tidy, cached',''); 02536 $this->content = $this->tidyHTML($this->content); 02537 $GLOBALS['TT']->pull(); 02538 } 02539 // XHTML-clean the code, if flag set 02540 if ($this->doXHTML_cleaning() == 'cached') { 02541 $GLOBALS['TT']->push('XHTML clean, cached',''); 02542 $XHTML_clean = t3lib_div::makeInstance('t3lib_parsehtml'); 02543 $this->content = $XHTML_clean->XHTML_clean($this->content); 02544 $GLOBALS['TT']->pull(); 02545 } 02546 // Fix local anchors in links, if flag set 02547 if ($this->doLocalAnchorFix() == 'cached') { 02548 $GLOBALS['TT']->push('Local anchor fix, cached',''); 02549 $this->prefixLocalAnchorsWithScript(); 02550 $GLOBALS['TT']->pull(); 02551 } 02552 02553 // Hook for post-processing of page content before being cached: 02554 if (is_array($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-cached'])) { 02555 $_params = array('pObj' => &$this); 02556 foreach($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-cached'] as $_funcRef) { 02557 t3lib_div::callUserFunction($_funcRef,$_params,$this); 02558 } 02559 } 02560 } 02561 02562 // Convert char-set for output: (should be BEFORE indexing of the content (changed 22/4 2005)), because otherwise indexed search might convert from the wrong charset! One thing is that the charset mentioned in the HTML header would be wrong since the output charset (metaCharset) has not been converted to from renderCharset. And indexed search will internally convert from metaCharset to renderCharset so the content MUST be in metaCharset already! 02563 $this->content = $this->convOutputCharset($this->content,'mainpage'); 02564 02565 // Hook for indexing pages 02566 if (is_array($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['pageIndexing'])) { 02567 foreach($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['pageIndexing'] as $_classRef) { 02568 $_procObj = &t3lib_div::getUserObj($_classRef); 02569 $_procObj->hook_indexContent($this); 02570 } 02571 } 02572 02573 // Storing for cache: 02574 if (!$this->no_cache) { 02575 $this->realPageCacheContent(); 02576 } elseif ($this->tempContent) { // If there happens to be temporary content in the cache and the cache was not cleared due to new content put in it... ($this->no_cache=0) 02577 $this->clearPageCacheContent(); 02578 } 02579 02580 // Sets sys-last-change: 02581 $this->setSysLastChanged(); 02582 } 02583 02589 function INTincScript() { 02590 $GLOBALS['TT']->push('Split content'); 02591 $INTiS_splitC = explode('<!--INT_SCRIPT.',$this->content); // Splits content with the key. 02592 $this->content=''; 02593 $GLOBALS['TT']->setTSlogMessage('Parts: '.count($INTiS_splitC)); 02594 $GLOBALS['TT']->pull(); 02595 02596 // Deprecated stuff: 02597 $this->additionalHeaderData = is_array($this->config['INTincScript_ext']['additionalHeaderData']) ? $this->config['INTincScript_ext']['additionalHeaderData'] : array(); 02598 $this->additionalJavaScript = $this->config['INTincScript_ext']['additionalJavaScript']; 02599 $this->additionalCSS = $this->config['INTincScript_ext']['additionalCSS']; 02600 $this->JSCode = $this->additionalHeaderData['JSCode']; 02601 $this->JSImgCode = $this->additionalHeaderData['JSImgCode']; 02602 $this->divSection=''; 02603 02604 $INTiS_config = $GLOBALS['TSFE']->config['INTincScript']; 02605 foreach($INTiS_splitC as $INTiS_c => $INTiS_cPart) { 02606 if (substr($INTiS_cPart,32,3)=='-->') { // If the split had a comment-end after 32 characters it's probably a split-string 02607 $INTiS_key = 'INT_SCRIPT.'.substr($INTiS_cPart,0,32); 02608 $GLOBALS['TT']->push('Include '.$INTiS_config[$INTiS_key]['file'],''); 02609 $incContent=''; 02610 if (is_array($INTiS_config[$INTiS_key])) { 02611 $INTiS_cObj = unserialize($INTiS_config[$INTiS_key]['cObj']); 02612 $INTiS_cObj->INT_include=1; 02613 switch($INTiS_config[$INTiS_key]['type']) { 02614 case 'SCRIPT': 02615 $incContent = $INTiS_cObj->PHP_SCRIPT($INTiS_config[$INTiS_key]['conf']); 02616 break; 02617 case 'COA': 02618 $incContent = $INTiS_cObj->COBJ_ARRAY($INTiS_config[$INTiS_key]['conf']); 02619 break; 02620 case 'FUNC': 02621 $incContent = $INTiS_cObj->USER($INTiS_config[$INTiS_key]['conf']); 02622 break; 02623 case 'POSTUSERFUNC': 02624 $incContent = $INTiS_cObj->callUserFunction($INTiS_config[$INTiS_key]['postUserFunc'], $INTiS_config[$INTiS_key]['conf'], $INTiS_config[$INTiS_key]['content']); 02625 break; 02626 } 02627 } 02628 $this->content.= $this->convOutputCharset($incContent,'INC-'.$INTiS_c); 02629 $this->content.= substr($INTiS_cPart,35); 02630 $GLOBALS['TT']->pull($incContent); 02631 } else { 02632 $this->content.= ($INTiS_c?'<!--INT_SCRIPT.':'').$INTiS_cPart; 02633 } 02634 } 02635 $GLOBALS['TT']->push('Substitute header section'); 02636 $this->INTincScript_loadJSCode(); 02637 $this->content = str_replace('<!--HD_'.$this->config['INTincScript_ext']['divKey'].'-->', $this->convOutputCharset(implode(chr(10),$this->additionalHeaderData),'HD'), $this->content); 02638 $this->content = str_replace('<!--TDS_'.$this->config['INTincScript_ext']['divKey'].'-->', $this->convOutputCharset($this->divSection,'TDS'), $this->content); 02639 $this->setAbsRefPrefix(); 02640 $GLOBALS['TT']->pull(); 02641 } 02642 02649 function INTincScript_loadJSCode() { 02650 if ($this->JSImgCode) { // If any images added, then add them to the javascript section 02651 $this->additionalHeaderData['JSImgCode']=' 02652 <script type="text/javascript"> 02653 /*<![CDATA[*/ 02654 <!-- 02655 if (version == "n3") { 02656 '.trim($this->JSImgCode).' 02657 } 02658 // --> 02659 /*]]>*/ 02660 </script>'; 02661 } 02662 if ($this->JSCode || count($this->additionalJavaScript)) { // Add javascript 02663 $this->additionalHeaderData['JSCode']=' 02664 <script type="text/javascript"> 02665 /*<![CDATA[*/ 02666 <!-- 02667 '.implode(chr(10),$this->additionalJavaScript).' 02668 '.trim($this->JSCode).' 02669 // --> 02670 /*]]>*/ 02671 </script>'; 02672 } 02673 if (count($this->additionalCSS)) { // Add javascript 02674 $this->additionalHeaderData['_CSS']=' 02675 <style type="text/css"> 02676 /*<![CDATA[*/ 02677 <!-- 02678 '.implode(chr(10),$this->additionalCSS).' 02679 // --> 02680 /*]]>*/ 02681 </style>'; 02682 } 02683 } 02684 02690 function isINTincScript() { 02691 return (is_array($this->config['INTincScript']) && !$this->jumpurl); 02692 } 02693 02699 function doXHTML_cleaning() { 02700 return $this->config['config']['xhtml_cleaning']; 02701 } 02702 02708 function doLocalAnchorFix() { 02709 return $this->config['config']['prefixLocalAnchors']; 02710 } 02711 02712 02713 02714 02715 02716 02717 02718 02719 02720 02721 02722 02723 02724 02725 02726 02727 /******************************************** 02728 * 02729 * Finished off; outputting, storing session data, statistics... 02730 * 02731 *******************************************/ 02732 02739 function isOutputting() { 02740 02741 // Initialize by status of jumpUrl: 02742 $enableOutput = (!$this->jumpurl); 02743 02744 // Call hook for possible disabling of output: 02745 if (is_array($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['isOutputting'])) { 02746 $_params = array('pObj' => &$this, 'enableOutput' => &$enableOutput); 02747 foreach($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['isOutputting'] as $_funcRef) { 02748 t3lib_div::callUserFunction($_funcRef,$_params,$this); 02749 } 02750 } 02751 02752 return $enableOutput; 02753 } 02754 02762 function processOutput() { 02763 02764 // Set header for charset-encoding unless disabled 02765 if (!$this->config['config']['disableCharsetHeader']) { 02766 $headLine = 'Content-Type:text/html;charset='.trim($this->metaCharset); 02767 header($headLine); 02768 } 02769 02770 // Set cache related headers to client (used to enable proxy / client caching!) 02771 if ($this->config['config']['sendCacheHeaders']) { 02772 $this->sendCacheHeaders(); 02773 } 02774 02775 // Set headers, if any 02776 if ($this->config['config']['additionalHeaders']) { 02777 $headerArray = explode('|', $this->config['config']['additionalHeaders']); 02778 while(list(,$headLine)=each($headerArray)) { 02779 $headLine = trim($headLine); 02780 header($headLine); 02781 } 02782 } 02783 02784 // Send appropriate status code in case of temporary content 02785 if ($this->tempContent) { 02786 $this->addTempContentHttpHeaders(); 02787 } 02788 02789 // Make substitution of eg. username/uid in content only if cache-headers for client/proxy caching is NOT sent! 02790 if (!$this->isClientCachable) { 02791 $this->contentStrReplace(); 02792 } 02793 02794 // Tidy up the code, if flag... 02795 if ($this->TYPO3_CONF_VARS['FE']['tidy_option'] == 'output') { 02796 $GLOBALS['TT']->push('Tidy, output',''); 02797 $this->content = $this->tidyHTML($this->content); 02798 $GLOBALS['TT']->pull(); 02799 } 02800 // XHTML-clean the code, if flag set 02801 if ($this->doXHTML_cleaning() == 'output') { 02802 $GLOBALS['TT']->push('XHTML clean, output',''); 02803 $XHTML_clean = t3lib_div::makeInstance('t3lib_parsehtml'); 02804 $this->content = $XHTML_clean->XHTML_clean($this->content); 02805 $GLOBALS['TT']->pull(); 02806 } 02807 // Fix local anchors in links, if flag set 02808 if ($this->doLocalAnchorFix() == 'output') { 02809 $GLOBALS['TT']->push('Local anchor fix, output',''); 02810 $this->prefixLocalAnchorsWithScript(); 02811 $GLOBALS['TT']->pull(); 02812 } 02813 02814 // Hook for post-processing of page content before output: 02815 if (is_array($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-output'])) { 02816 $_params = array('pObj' => &$this); 02817 foreach($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-output'] as $_funcRef) { 02818 t3lib_div::callUserFunction($_funcRef,$_params,$this); 02819 } 02820 } 02821 02822 // Send content-lenght header. Notice that all HTML content outside the length of the content-length header will be cut off! Therefore content of unknown length from included PHP-scripts and if admin users are logged in (admin panel might show...) we disable it! 02823 if ($this->config['config']['enableContentLengthHeader'] && !$this->isEXTincScript() && !$this->beUserLogin && !$this->doWorkspacePreview()) { 02824 header('Content-Length: '.strlen($this->content)); 02825 } 02826 } 02827 02835 function sendCacheHeaders() { 02836 02837 // Getting status whether we can send cache control headers for proxy caching: 02838 $doCache = $this->isStaticCacheble(); 02839 02840 // This variable will be TRUE unless cache headers are configured to be sent ONLY if a branch does not allow logins and logins turns out to be allowed anyway... 02841 $loginsDeniedCfg = !$this->config['config']['sendCacheHeaders_onlyWhenLoginDeniedInBranch'] || !$this->loginAllowedInBranch; 02842 02843 // Finally, when backend users are logged in, do not send cache headers at all (Admin Panel might be displayed for instance). 02844 if ($doCache 02845 && !$this->beUserLogin 02846 && !$this->doWorkspacePreview() 02847 && $loginsDeniedCfg) { 02848 02849 // Build headers: 02850 $headers = array( 02851 'Last-Modified: '.gmdate('D, d M Y H:i:s T', $this->register['SYS_LASTCHANGED']), 02852 'Expires: '.gmdate('D, d M Y H:i:s T', $this->cacheExpires), 02853 'ETag: '.md5($this->content), 02854 'Cache-Control: max-age='.($this->cacheExpires - $GLOBALS['EXEC_TIME']), // no-cache 02855 'Pragma: public', 02856 ); 02857 02858 $this->isClientCachable = TRUE; 02859 } else { 02860 // Build headers: 02861 $headers = array( 02862 #'Last-Modified: '.gmdate('D, d M Y H:i:s T', $this->register['SYS_LASTCHANGED']), 02863 #'ETag: '.md5($this->content), 02864 02865 #'Cache-Control: no-cache', 02866 #'Pragma: no-cache', 02867 'Cache-Control: private', // Changed to this according to Ole Tange, FI.dk 02868 ); 02869 02870 $this->isClientCachable = FALSE; 02871 02872 // Now, if a backend user is logged in, tell him in the Admin Panel log what the caching status would have been: 02873 if ($this->beUserLogin) { 02874 if ($doCache) { 02875 $GLOBALS['TT']->setTSlogMessage('Cache-headers with max-age "'.($this->cacheExpires - $GLOBALS['EXEC_TIME']).'" would have been sent'); 02876 } else { 02877 $reasonMsg = ''; 02878 $reasonMsg.= !$this->no_cache ? '' : 'Caching disabled (no_cache). '; 02879 $reasonMsg.= !$this->isINTincScript() ? '' : '*_INT object(s) on page. '; 02880 $reasonMsg.= !$this->isEXTincScript() ? '' : '*_EXT object(s) on page. '; 02881 $reasonMsg.= !is_array($this->fe_user->user) ? '' : 'Frontend user logged in. '; 02882 $GLOBALS['TT']->setTSlogMessage('Cache-headers would disable proxy caching! Reason(s): "'.$reasonMsg.'"',1); 02883 } 02884 } 02885 } 02886 02887 // Send headers: 02888 foreach($headers as $hL) { 02889 header($hL); 02890 } 02891 } 02892 02903 function isStaticCacheble() { 02904 $doCache = !$this->no_cache 02905 && !$this->isINTincScript() 02906 && !$this->isEXTincScript() 02907 && !$this->isUserOrGroupSet(); 02908 return $doCache; 02909 } 02910 02916 function contentStrReplace() { 02917 // Substitutes username mark with the username 02918 if ($this->fe_user->user['uid']) { 02919 02920 // User name: 02921 $token = trim($this->config['config']['USERNAME_substToken']); 02922 $this->content = str_replace($token ? $token : '<!--###USERNAME###-->',$this->fe_user->user['username'],$this->content); 02923 02924 // User uid (if configured): 02925 $token = trim($this->config['config']['USERUID_substToken']); 02926 if ($token) { 02927 $this->content = str_replace($token, $this->fe_user->user['uid'], $this->content); 02928 } 02929 } 02930 // Substitutes get_URL_ID in case of GET-fallback 02931 if ($this->getMethodUrlIdToken) { 02932 $this->content = str_replace($this->getMethodUrlIdToken, $this->fe_user->get_URL_ID, $this->content); 02933 } 02934 } 02935 02942 function isEXTincScript() { 02943 return is_array($this->config['EXTincScript']); 02944 } 02945 02951 function storeSessionData() { 02952 $this->fe_user->storeSessionData(); 02953 } 02954 02961 function setParseTime() { 02962 // Compensates for the time consumed with Back end user initialization. 02963 $this->scriptParseTime = $GLOBALS['TT']->convertMicrotime($GLOBALS['TYPO3_MISC']['microtime_end']) 02964 - $GLOBALS['TT']->convertMicrotime($GLOBALS['TYPO3_MISC']['microtime_start']) 02965 - ($GLOBALS['TT']->convertMicrotime($GLOBALS['TYPO3_MISC']['microtime_BE_USER_end'])-$GLOBALS['TT']->convertMicrotime($GLOBALS['TYPO3_MISC']['microtime_BE_USER_start'])); 02966 } 02967 02973 function statistics() { 02974 if ($this->config['config']['stat'] && 02975 (!strcmp('',$this->config['config']['stat_typeNumList']) || t3lib_div::inList(str_replace(' ','',$this->config['config']['stat_typeNumList']), $this->type)) && 02976 (!$this->config['config']['stat_excludeBEuserHits'] || !$this->beUserLogin) && 02977 (!$this->config['config']['stat_excludeIPList'] || !t3lib_div::cmpIP(t3lib_div::getIndpEnv('REMOTE_ADDR'),str_replace(' ','',$this->config['config']['stat_excludeIPList'])))) { 02978 02979 $GLOBALS['TT']->push('Stat'); 02980 if (t3lib_extMgm::isLoaded('sys_stat') && $this->config['config']['stat_mysql']) { 02981 02982 // Jumpurl: 02983 $sword = t3lib_div::_GP('sword'); 02984 if ($sword) { 02985 $jumpurl_msg = 'sword:'.$sword; 02986 } elseif ($this->jumpurl) { 02987 $jumpurl_msg = 'jumpurl:'.$this->jumpurl; 02988 } else { 02989 $jumpurl_msg = ''; 02990 } 02991 02992 // Flags: bits: 0 = BE_user, 1=Cached page? 02993 $flags=0; 02994 if ($this->beUserLogin) {$flags|=1;} 02995 if ($this->cacheContentFlag) {$flags|=2;} 02996 02997 // Ref url: 02998 $refUrl = t3lib_div::getIndpEnv('HTTP_REFERER'); 02999 $thisUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_DIR'); 03000 if (t3lib_div::isFirstPartOfStr($refUrl,$thisUrl)) { 03001 $refUrl='[LOCAL]'; 03002 } 03003 03004 $insertFields = array( 03005 'page_id' => intval($this->id), // id 03006 'page_type' => intval($this->type), // type 03007 'jumpurl' => $jumpurl_msg, // jumpurl message 03008 'feuser_id' => $this->fe_user->user['uid'], // fe_user id, integer 03009 'cookie' => $this->fe_user->id, // cookie as set or retrieve. If people has cookies disabled this will vary all the time... 03010 'sureCookie' => hexdec(substr($this->fe_user->cookieId,0,8)), // This is the cookie value IF the cookie WAS actually set. However the first hit where the cookie is set will thus NOT be logged here. So this lets you select for a session of at least two clicks... 03011 'rl0' => $this->config['rootLine'][0]['uid'], // RootLevel 0 uid 03012 'rl1' => $this->config['rootLine'][1]['uid'], // RootLevel 1 uid 03013 'client_browser' => $GLOBALS['CLIENT']['BROWSER'], // Client browser (net, msie, opera) 03014 'client_version' => $GLOBALS['CLIENT']['VERSION'], // Client version (double value) 03015 'client_os' => $GLOBALS['CLIENT']['SYSTEM'], // Client Operating system (win, mac, unix) 03016 'parsetime' => intval($this->scriptParseTime), // Parsetime for the page. 03017 'flags' => $flags, // Flags: Is be user logged in? Is page cached? 03018 'IP' => t3lib_div::getIndpEnv('REMOTE_ADDR'), // Remote IP address 03019 'host' => t3lib_div::getIndpEnv('REMOTE_HOST'), // Remote Host Address 03020 'referer' => $refUrl, // Referer URL 03021 'browser' => t3lib_div::getIndpEnv('HTTP_USER_AGENT'), // User Agent Info. 03022 'tstamp' => $GLOBALS['EXEC_TIME'] // Time stamp 03023 ); 03024 03025 // Hook for preprocessing the list of fields to insert into sys_stat: 03026 if (is_array($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['sys_stat-PreProcClass'])) { 03027 foreach($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['sys_stat-PreProcClass'] as $_classRef) { 03028 $_procObj = &t3lib_div::getUserObj($_classRef); 03029 $insertFields = $_procObj->sysstat_preProcessFields($insertFields,$this); 03030 } 03031 } 03032 03033 03034 $GLOBALS['TT']->push('Store SQL'); 03035 $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_stat', $insertFields); 03036 $GLOBALS['TT']->pull(); 03037 } 03038 03039 // Apache: 03040 if ($this->config['config']['stat_apache'] && $this->config['stat_vars']['pageName']) { 03041 if (@is_file($this->config['stat_vars']['logFile'])) { 03042 $LogLine = ((t3lib_div::getIndpEnv('REMOTE_HOST') && !$this->config['config']['stat_apache_noHost']) ? t3lib_div::getIndpEnv('REMOTE_HOST') : t3lib_div::getIndpEnv('REMOTE_ADDR')).' - - '.Date('[d/M/Y:H:i:s +0000]',$GLOBALS['EXEC_TIME']).' "GET '.$this->config['stat_vars']['pageName'].' HTTP/1.1" 200 '.strlen($this->content); 03043 if (!$this->config['config']['stat_apache_notExtended']) { 03044 $LogLine.= ' "'.t3lib_div::getIndpEnv('HTTP_REFERER').'" "'.t3lib_div::getIndpEnv('HTTP_USER_AGENT').'"'; 03045 } 03046 03047 $GLOBALS['TT']->push('Write to log file (fputs)'); 03048 $logfilehandle = fopen($this->config['stat_vars']['logFile'], 'a'); 03049 fputs($logfilehandle, $LogLine.chr(10)); 03050 @fclose($logfilehandle); 03051 $GLOBALS['TT']->pull(); 03052 03053 $GLOBALS['TT']->setTSlogMessage('Writing to logfile: OK',0); 03054 } else { 03055 $GLOBALS['TT']->setTSlogMessage('Writing to logfile: Error - logFile did not exist!',3); 03056 } 03057 } 03058 $GLOBALS['TT']->pull(); 03059 } 03060 } 03061 03067 function previewInfo() { 03068 if ($this->fePreview) { 03069 03070 if ($this->fePreview==2) { 03071 $text = 'Preview of workspace "'.$this->whichWorkspace(TRUE).'" ('.$this->whichWorkspace().')'; 03072 } else { 03073 $text = 'PREVIEW!'; 03074 } 03075 03076 $stdMsg = ' 03077 <br /> 03078 <div align="center"> 03079 <table border="3" bordercolor="black" cellpadding="2" bgcolor="red"> 03080 <tr> 03081 <td> <font face="Verdana" size="1"><b>'.htmlspecialchars($text).'</b></font> </td> 03082 </tr> 03083 </table> 03084 </div>'; 03085 03086 if ($this->fePreview==2) { 03087 $temp_content = $this->config['config']['message_preview_workspace'] ? 03088 @sprintf($this->config['config']['message_preview_workspace'], $this->whichWorkspace(TRUE),$this->whichWorkspace()) : 03089 $stdMsg; 03090 } else { 03091 $temp_content = $this->config['config']['message_preview'] ? $this->config['config']['message_preview'] : $stdMsg; 03092 } 03093 echo $temp_content; 03094 } 03095 } 03096 03102 function hook_eofe() { 03103 03104 // Call hook for end-of-frontend processing: 03105 if (is_array($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['hook_eofe'])) { 03106 $_params = array('pObj' => &$this); 03107 foreach($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['hook_eofe'] as $_funcRef) { 03108 t3lib_div::callUserFunction($_funcRef,$_params,$this); 03109 } 03110 } 03111 } 03112 03118 function beLoginLinkIPList() { 03119 if ($this->config['config']['beLoginLinkIPList']) { 03120 if (t3lib_div::cmpIP(t3lib_div::getIndpEnv('REMOTE_ADDR'), $this->config['config']['beLoginLinkIPList'])) { 03121 $label = !$this->beUserLogin ? $this->config['config']['beLoginLinkIPList_login'] : $this->config['config']['beLoginLinkIPList_logout']; 03122 if ($label) { 03123 if (!$this->beUserLogin) { 03124 $link = '<a href="'.htmlspecialchars(TYPO3_mainDir.'index.php?redirect_url='.rawurlencode(t3lib_div::getIndpEnv("REQUEST_URI"))).'">'.$label.'</a>'; 03125 } else { 03126 $link = '<a href="'.htmlspecialchars(TYPO3_mainDir.'index.php?L=OUT&redirect_url='.rawurlencode(t3lib_div::getIndpEnv("REQUEST_URI"))).'">'.$label.'</a>'; 03127 } 03128 return $link; 03129 } 03130 } 03131 } 03132 } 03133 03139 function addTempContentHttpHeaders() { 03140 header('HTTP/1.0 503 Service unavailable'); 03141 header('Retry-after: 3600'); 03142 header('Pragma: no-cache'); 03143 header('Cache-control: no-cache'); 03144 header('Expire: 0'); 03145 } 03146 03147 03148 03149 03150 03151 03152 03153 03154 03155 03156 03157 03158 03159 03160 03161 03162 03163 03164 03165 03166 03167 /******************************************** 03168 * 03169 * Various internal API functions 03170 * 03171 *******************************************/ 03172 03173 03185 function makeSimulFileName($inTitle,$page,$type,$addParams='',$no_cache='') { 03186 $titleChars = intval($this->config['config']['simulateStaticDocuments_addTitle']); 03187 // Default value is 30 but values > 1 will be override this 03188 if($titleChars==1) { $titleChars = 30; } 03189 03190 $out = ''; 03191 if ($titleChars) { 03192 $out = $this->fileNameASCIIPrefix($inTitle, $titleChars); 03193 } 03194 $enc = ''; 03195 03196 if (strcmp($addParams,'') && !$no_cache) { 03197 switch ((string)$this->config['config']['simulateStaticDocuments_pEnc']) { 03198 case 'md5': 03199 $md5 = substr(md5($addParams),0,10); 03200 $enc = '+M5'.$md5; 03201 03202 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('md5hash', 'cache_md5params', 'md5hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($md5, 'cache_md5params')); 03203 if (!$GLOBALS['TYPO3_DB']->sql_num_rows($res)) { 03204 $insertFields = array( 03205 'md5hash' => $md5, 03206 'tstamp' => time(), 03207 'type' => 1, 03208 'params' => $addParams 03209 ); 03210 03211 $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_md5params', $insertFields); 03212 } 03213 break; 03214 case 'base64': 03215 $enc = '+B6'.str_replace('=','_',str_replace('/','-',base64_encode($addParams))); 03216 break; 03217 } 03218 } 03219 // Setting page and type number: 03220 $url = $out.$page.$enc; 03221 $url.= ($type || $out || !$this->config['config']['simulateStaticDocuments_noTypeIfNoTitle']) ? '.'.$type : ''; 03222 return $url; 03223 } 03224 03232 function simulateStaticDocuments_pEnc_onlyP_proc($linkVars) { 03233 $remainLinkVars = ''; 03234 if (strcmp($linkVars,'')) { 03235 $p = explode('&',$linkVars); 03236 sort($p); // This sorts the parameters - and may not be needed and further it will generate new MD5 hashes in many cases. Maybe not so smart. Hmm? 03237 $rem = array(); 03238 foreach($p as $k => $v) { 03239 if (strlen($v)) { 03240 list($pName) = explode('=',$v,2); 03241 $pName = rawurldecode($pName); 03242 if (!$this->pEncAllowedParamNames[$pName]) { 03243 unset($p[$k]); 03244 $rem[] = $v; 03245 } 03246 } else unset($p[$k]); 03247 } 03248 03249 $linkVars = count($p) ? '&'.implode('&',$p) : ''; 03250 $remainLinkVars = count($rem) ? '&'.implode('&',$rem) : ''; 03251 } 03252 return array($linkVars, $remainLinkVars); 03253 } 03254 03261 function getSimulFileName() { 03262 $url=''; 03263 $url.=$this->makeSimulFileName($this->page['title'], $this->page['alias']?$this->page['alias']:$this->id, $this->type).'.html'; 03264 return $url; 03265 } 03266 03272 function setSimulReplacementChar() { 03273 $replacement = $defChar = t3lib_div::compat_version('4.0.0') ? '-' : '_'; 03274 if (isset($this->config['config']['simulateStaticDocuments_replacementChar'])) { 03275 $replacement = trim($this->config['config']['simulateStaticDocuments_replacementChar']); 03276 if (urlencode($replacement) != $replacement) { 03277 // Invalid character 03278 $replacement = $defChar; 03279 } 03280 } 03281 $this->config['config']['simulateStaticDocuments_replacementChar'] = $replacement; 03282 } 03283 03292 function fileNameASCIIPrefix($inTitle,$titleChars,$mergeChar='.') { 03293 $out = $this->csConvObj->specCharsToASCII($this->renderCharset, $inTitle); 03294 // Get replacement character 03295 $replacementChar = &$this->config['config']['simulateStaticDocuments_replacementChar']; 03296 $replacementChars = '_\-' . ($replacementChar != '_' && $replacementChar != '-' ? $replacementChar : ''); 03297 $out = preg_replace('/[^A-Za-z0-9_-]/', $replacementChar, trim(substr($out, 0, $titleChars))); 03298 $out = preg_replace('/([' . $replacementChars . ']){2,}/', '\1', $out); 03299 $out = preg_replace('/[' . $replacementChars . ']?$/', '', $out); 03300 $out = preg_replace('/^[' . $replacementChars . ']?/', '', $out); 03301 if (strlen($out)) { 03302 $out .= $mergeChar; 03303 } 03304 03305 return $out; 03306 } 03307 03315 function encryptEmail($string,$back=0) { 03316 $out = ''; 03317 03318 if ($this->spamProtectEmailAddresses === 'ascii') { 03319 for ($a=0; $a<strlen($string); $a++) { 03320 $out .= '&#'.ord(substr($string, $a, 1)).';'; 03321 } 03322 } else { 03323 for ($a=0; $a<strlen($string); $a++) { 03324 $charValue = ord(substr($string,$a,1)); 03325 $charValue+= intval($this->spamProtectEmailAddresses)*($back?-1:1); 03326 $out.= chr($charValue); 03327 } 03328 } 03329 return $out; 03330 } 03331 03341 function codeString($string, $decode=FALSE) { 03342 03343 if ($decode) { 03344 list($md5Hash, $str) = explode(':',$string,2); 03345 $newHash = substr(md5($this->TYPO3_CONF_VARS['SYS']['encryptionKey'].':'.$str),0,10); 03346 if (!strcmp($md5Hash, $newHash)) { 03347 $str = base64_decode($str); 03348 $str = $this->roundTripCryptString($str); 03349 return $str; 03350 } else return FALSE; // Decoding check failed! Original string not produced by this server! 03351 } else { 03352 $str = $string; 03353 $str = $this->roundTripCryptString($str); 03354 $str = base64_encode($str); 03355 $newHash = substr(md5($this->TYPO3_CONF_VARS['SYS']['encryptionKey'].':'.$str),0,10); 03356 return $newHash.':'.$str; 03357 } 03358 } 03359 03367 function roundTripCryptString($string) { 03368 $out = ''; 03369 $strLen = strlen($string); 03370 $cryptLen = strlen($this->TYPO3_CONF_VARS['SYS']['encryptionKey']); 03371 03372 for ($a=0; $a < $strLen; $a++) { 03373 $xorVal = $cryptLen>0 ? ord($this->TYPO3_CONF_VARS['SYS']['encryptionKey']{($a%$cryptLen)}) : 255; 03374 $out.= chr(ord($string{$a}) ^ $xorVal); 03375 } 03376 03377 return $out; 03378 } 03379 03387 function checkFileInclude($incFile) { 03388 return !$this->TYPO3_CONF_VARS['FE']['noPHPscriptInclude'] 03389 || substr($incFile,0,14)=='media/scripts/' 03390 || substr($incFile,0,4+strlen(TYPO3_mainDir))==TYPO3_mainDir.'ext/' 03391 || substr($incFile,0,7+strlen(TYPO3_mainDir))==TYPO3_mainDir.'sysext/' 03392 || substr($incFile,0,14)=='typo3conf/ext/'; 03393 } 03394 03402 function newCObj() { 03403 $this->cObj =t3lib_div::makeInstance('tslib_cObj'); 03404 $this->cObj->start($this->page,'pages'); 03405 } 03406 03415 function setAbsRefPrefix() { 03416 if ($this->absRefPrefix) { 03417 $this->content = str_replace('"media/', '"'.$this->absRefPrefix.'media/', $this->content); 03418 $this->content = str_replace('"fileadmin/', '"'.$this->absRefPrefix.'fileadmin/', $this->content); 03419 } 03420 } 03421 03429 function baseUrlWrap($url) { 03430 if ($this->baseUrl) { 03431 $urlParts = parse_url($url); 03432 if (!strlen($urlParts['scheme']) && $url{0}!=='/') { 03433 $url = $this->baseUrl.$url; 03434 } 03435 } 03436 return $url; 03437 } 03438 03448 function printError($label,$header='Error!') { 03449 t3lib_timeTrack::debug_typo3PrintError($header,$label,0,t3lib_div::getIndpEnv('TYPO3_SITE_URL')); 03450 } 03451 03459 function updateMD5paramsRecord($hash) { 03460 $GLOBALS['TYPO3_DB']->exec_UPDATEquery('cache_md5params', 'md5hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($hash, 'cache_md5params'), array('tstamp' => time())); 03461 } 03462 03470 function tidyHTML($content) { 03471 if ($this->TYPO3_CONF_VARS['FE']['tidy'] && $this->TYPO3_CONF_VARS['FE']['tidy_path']) { 03472 $oldContent = $content; 03473 $fname = t3lib_div::tempnam('typo3_tidydoc_'); // Create temporary name 03474 @unlink ($fname); // Delete if exists, just to be safe. 03475 $fp = fopen ($fname,'wb'); // Open for writing 03476 fputs ($fp, $content); // Put $content 03477 @fclose ($fp); // Close 03478 03479 exec ($this->TYPO3_CONF_VARS['FE']['tidy_path'].' '.$fname, $output); // run the $content through 'tidy', which formats the HTML to nice code. 03480 @unlink ($fname); // Delete the tempfile again 03481 $content = implode(chr(10),$output); 03482 if (!trim($content)) { 03483 $content = $oldContent; // Restore old content due empty return value. 03484 $GLOBALS['TT']->setTSlogMessage('"tidy" returned an empty value!',2); 03485 } 03486 $GLOBALS['TT']->setTSlogMessage('"tidy" content lenght: '.strlen($content),0); 03487 } 03488 return $content; 03489 } 03490 03496 function prefixLocalAnchorsWithScript() { 03497 $scriptPath = substr(t3lib_div::getIndpEnv('TYPO3_REQUEST_URL'),strlen(t3lib_div::getIndpEnv('TYPO3_SITE_URL'))); 03498 $this->content = preg_replace('/(<(a|area).*?href=")(#[^"]*")/i','$1' . htmlspecialchars($scriptPath) . '$3',$this->content); 03499 } 03500 03506 function workspacePreviewInit() { 03507 $previewWS = t3lib_div::_GP('ADMCMD_previewWS'); 03508 if ($this->beUserLogin && is_object($GLOBALS['BE_USER']) && t3lib_div::testInt($previewWS)) { 03509 if ($previewWS>=-1 && ($previewWS==0 || $GLOBALS['BE_USER']->checkWorkspace($previewWS))) { // Check Access to workspace. Live (0) is OK to preview for all. 03510 $this->workspacePreview = intval($previewWS); 03511 } else { 03512 $this->workspacePreview = -99; // No preview, will default to "Live" at the moment 03513 } 03514 } 03515 } 03516 03522 function doWorkspacePreview() { 03523 return (string)$this->workspacePreview!==''; 03524 } 03525 03532 function whichWorkspace($returnTitle = FALSE) { 03533 if ($this->doWorkspacePreview()) { 03534 $ws = intval($this->workspacePreview); 03535 } elseif ($this->beUserLogin) { 03536 $ws = $GLOBALS['BE_USER']->workspace; 03537 } else return FALSE; 03538 03539 if ($returnTitle) { 03540 if ($ws===-1) { 03541 return 'Default Draft Workspace'; 03542 } else { 03543 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('title', 'sys_workspace', 'uid='.intval($ws)); 03544 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 03545 return $row['title']; 03546 } 03547 } 03548 } else { 03549 return $ws; 03550 } 03551 } 03552 03553 03554 03555 03556 03557 03558 03559 03560 03561 03562 03563 03564 03565 03566 03567 03568 03569 03570 03571 03572 03573 03574 03575 03576 03577 03578 /******************************************** 03579 * 03580 * Various external API functions - for use in plugins etc. 03581 * 03582 *******************************************/ 03583 03584 03590 function getStorageSiterootPids() { 03591 $res=array(); 03592 reset($this->rootLine); 03593 while(list(,$rC)=each($this->rootLine)) { 03594 if (!$res['_STORAGE_PID']) $res['_STORAGE_PID']=intval($rC['storage_pid']); 03595 if (!$res['_SITEROOT']) $res['_SITEROOT']=$rC['is_siteroot']?intval($rC['uid']):0; 03596 } 03597 return $res; 03598 } 03599 03605 function getPagesTSconfig() { 03606 if (!is_array($this->pagesTSconfig)) { 03607 reset($this->rootLine); 03608 $TSdataArray = array(); 03609 $TSdataArray[] = $this->TYPO3_CONF_VARS['BE']['defaultPageTSconfig']; // Setting default configuration: 03610 while(list($k,$v)=each($this->rootLine)) { 03611 $TSdataArray[]=$v['TSconfig']; 03612 } 03613 // Parsing the user TS (or getting from cache) 03614 $TSdataArray = t3lib_TSparser::checkIncludeLines_array($TSdataArray); 03615 $userTS = implode(chr(10).'[GLOBAL]'.chr(10),$TSdataArray); 03616 $hash = md5('pageTS:'.$userTS); 03617 $cachedContent = $this->sys_page->getHash($hash,0); 03618 if (isset($cachedContent)) { 03619 $this->pagesTSconfig = unserialize($cachedContent); 03620 } else { 03621 $parseObj = t3lib_div::makeInstance('t3lib_TSparser'); 03622 $parseObj->parse($userTS); 03623 $this->pagesTSconfig = $parseObj->setup; 03624 $this->sys_page->storeHash($hash,serialize($this->pagesTSconfig),'PAGES_TSconfig'); 03625 } 03626 } 03627 return $this->pagesTSconfig; 03628 } 03629 03638 function setJS($key,$content='') { 03639 if ($key) { 03640 switch($key) { 03641 case 'mouseOver': 03642 $this->additionalJavaScript[$key]= 03643 ' // JS function for mouse-over 03644 function over(name,imgObj) { // 03645 if (version == "n3" && document[name]) {document[name].src = eval(name+"_h.src");} 03646 else if (typeof(document.getElementById)=="function" && document.getElementById(name)) {document.getElementById(name).src = eval(name+"_h.src");} 03647 else if (imgObj) {imgObj.src = eval(name+"_h.src");} 03648 } 03649 // JS function for mouse-out 03650 function out(name,imgObj) { // 03651 if (version == "n3" && document[name]) {document[name].src = eval(name+"_n.src");} 03652 else if (typeof(document.getElementById)=="function" && document.getElementById(name)) {document.getElementById(name).src = eval(name+"_n.src");} 03653 else if (imgObj) {imgObj.src = eval(name+"_n.src");} 03654 }'; 03655 break; 03656 case 'openPic': 03657 $this->additionalJavaScript[$key]= 03658 ' function openPic(url,winName,winParams) { // 03659 var theWindow = window.open(url,winName,winParams); 03660 if (theWindow) {theWindow.focus();} 03661 }'; 03662 break; 03663 default: 03664 $this->additionalJavaScript[$key]=$content; 03665 break; 03666 } 03667 } 03668 } 03669 03678 function setCSS($key,$content) { 03679 if ($key) { 03680 switch($key) { 03681 default: 03682 $this->additionalCSS[$key]=$content; 03683 break; 03684 } 03685 } 03686 } 03687 03693 function make_seed() { 03694 list($usec, $sec) = explode(' ', microtime()); 03695 $seedV = (float)$sec + ((float)$usec * 100000); 03696 srand($seedV); 03697 } 03698 03706 function uniqueHash($str='') { 03707 return md5($this->uniqueString.'_'.$str.$this->uniqueCounter++); 03708 } 03709 03715 function set_no_cache() { 03716 $this->no_cache = 1; 03717 } 03718 03725 function set_cache_timeout_default($seconds) { 03726 $this->cacheTimeOutDefault = intval($seconds); 03727 } 03728 03741 function plainMailEncoded($email,$subject,$message,$headers='') { 03742 $urlmode=$this->config['config']['notification_email_urlmode']; // '76', 'all', '' 03743 03744 if ($urlmode) { 03745 $message=t3lib_div::substUrlsInPlainText($message,$urlmode); 03746 } 03747 03748 $encoding = $this->config['config']['notification_email_encoding'] ? $this->config['config']['notification_email_encoding'] : 'quoted-printable'; 03749 $charset = $this->config['config']['notification_email_charset'] ? $this->config['config']['notification_email_charset'] : ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] ? $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] : 'ISO-8859-1'); 03750 03751 t3lib_div::plainMailEncoded( 03752 $email, 03753 $subject, 03754 $message, 03755 $headers, 03756 $encoding, 03757 $charset 03758 ); 03759 } 03760 03761 03762 03763 03764 03765 03766 03767 03768 03769 03770 03771 03772 03773 /********************************************* 03774 * 03775 * Localization and character set conversion 03776 * 03777 *********************************************/ 03778 03785 function sL($input) { 03786 if (strcmp(substr($input,0,4),'LLL:')) { 03787 $t = explode('|',$input); 03788 return $t[$this->langSplitIndex] ? $t[$this->langSplitIndex] : $t[0]; 03789 } else { 03790 if (!isset($this->LL_labels_cache[$this->lang][$input])) { // If cached label 03791 $restStr = trim(substr($input,4)); 03792 $extPrfx=''; 03793 if (!strcmp(substr($restStr,0,4),'EXT:')) { 03794 $restStr = trim(substr($restStr,4)); 03795 $extPrfx='EXT:'; 03796 } 03797 $parts = explode(':',$restStr); 03798 $parts[0]=$extPrfx.$parts[0]; 03799 if (!isset($this->LL_files_cache[$parts[0]])) { // Getting data if not cached 03800 $this->LL_files_cache[$parts[0]] = $this->readLLfile($parts[0]); 03801 } 03802 $this->LL_labels_cache[$this->lang][$input] = $this->csConv($this->getLLL($parts[1],$this->LL_files_cache[$parts[0]])); 03803 } 03804 return $this->LL_labels_cache[$this->lang][$input]; 03805 } 03806 } 03807 03814 function readLLfile($fileRef) { 03815 return t3lib_div::readLLfile($fileRef,$this->lang); 03816 } 03817 03825 function getLLL($index,$LOCAL_LANG) { 03826 if (strcmp($LOCAL_LANG[$this->lang][$index],'')) { 03827 return $LOCAL_LANG[$this->lang][$index]; 03828 } else { 03829 return $LOCAL_LANG['default'][$index]; 03830 } 03831 } 03832 03839 function initLLvars() { 03840 03841 // Setting language key and split index: 03842 $this->lang = $this->config['config']['language'] ? $this->config['config']['language'] : 'default'; 03843 03844 $ls = explode('|',TYPO3_languages); 03845 while(list($i,$v)=each($ls)) { 03846 if ($v==$this->lang) {$this->langSplitIndex=$i; break;} 03847 } 03848 03849 // Setting charsets: 03850 $this->renderCharset = $this->csConvObj->parse_charset($this->config['config']['renderCharset'] ? $this->config['config']['renderCharset'] : ($this->TYPO3_CONF_VARS['BE']['forceCharset'] ? $this->TYPO3_CONF_VARS['BE']['forceCharset'] : $this->defaultCharSet)); // Rendering charset of HTML page. 03851 $this->metaCharset = $this->csConvObj->parse_charset($this->config['config']['metaCharset'] ? $this->config['config']['metaCharset'] : $this->renderCharset); // Output charset of HTML page. 03852 $this->labelsCharset = $this->csConvObj->parse_charset($this->csConvObj->charSetArray[$this->lang] ? $this->csConvObj->charSetArray[$this->lang] : 'iso-8859-1'); 03853 if ($this->renderCharset != $this->labelsCharset) { 03854 $this->convCharsetToFrom = array( 03855 'from' => $this->labelsCharset, 03856 'to' => $this->renderCharset 03857 ); 03858 } 03859 } 03860 03873 function csConv($str,$from='') { 03874 if ($from) { 03875 $output = $this->csConvObj->conv($str,$this->csConvObj->parse_charset($from),$this->renderCharset,1); 03876 return $output ? $output : $str; 03877 } elseif (is_array($this->convCharsetToFrom)) { 03878 return $this->csConvObj->conv($str,$this->convCharsetToFrom['from'],$this->convCharsetToFrom['to'],1); 03879 } else { 03880 return $str; 03881 } 03882 } 03883 03891 function convOutputCharset($content,$label='') { 03892 if ($this->renderCharset != $this->metaCharset) { 03893 $content = $this->csConvObj->conv($content,$this->renderCharset,$this->metaCharset,TRUE); 03894 } 03895 03896 return $content; 03897 } 03898 03904 function convPOSTCharset() { 03905 if ($this->renderCharset != $this->metaCharset && is_array($_POST) && count($_POST)) { 03906 $this->csConvObj->convArray($_POST,$this->metaCharset,$this->renderCharset); 03907 $GLOBALS['HTTP_POST_VARS'] = $_POST; 03908 } 03909 } 03910 } 03911 03912 03913 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_fe.php']) { 03914 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_fe.php']); 03915 } 03916 ?>