Documentation TYPO3 par Ameos |
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2006 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 ***************************************************************/ 00083 require_once (PATH_t3lib.'class.t3lib_tsparser.php'); 00084 require_once (PATH_t3lib.'class.t3lib_matchcondition.php'); 00085 00086 00087 00088 00089 00090 00091 00092 00093 00094 00095 00096 00097 00098 00099 00100 00109 class t3lib_TStemplate { 00110 00111 // Debugging, analysis: 00112 var $tt_track = 1; // If set, the global tt-timeobject is used to log the performance. 00113 var $forceTemplateParsing=0; // If set, the template is always rendered. Used from Admin Panel. 00114 00115 // Backend Analysis modules settings: 00116 var $matchAlternative=array(); // This array is passed on to matchObj by generateConfig(). If it holds elements, they are used for matching instead. See commment at the match-class. Used for backend modules only. Never frontend! 00117 var $matchAll=0; // If set, the match-class matches everything! Used for backend modules only. Never frontend! 00118 var $parseEditorCfgField=0; // If set, the Backend Editor Configuration TypoScript is also parsed (this is not needed for the frontend) 00119 var $backend_info = 0; 00120 var $getFileName_backPath=''; // Set from the backend - used to set an absolute path (PATH_site) so that relative resources are properly found with getFileName() 00121 00122 // Externally set breakpoints (used by Backend Modules) 00123 var $ext_constants_BRP=0; 00124 var $ext_config_BRP=0; 00125 var $ext_editorcfg_BRP=0; 00126 var $ext_regLinenumbers=FALSE; 00127 00128 // Constants: 00129 var $uplPath = 'uploads/tf/'; 00130 var $tempPath = 'typo3temp/'; 00131 var $menuclasses = 'gmenu,tmenu,imgmenu,jsmenu'; 00132 00133 // Set Internally: 00134 var $whereClause = ''; // This MUST be initialized by the init() function 00135 var $debug = 0; 00136 var $allowedPaths = array(); // This is the only paths (relative!!) that are allowed for resources in TypoScript. Should all be appended with '/'. You can extend these by the global array TYPO3_CONF_VARS. See init() function. 00137 var $currentPageData = ''; // Contains "currentPageData" when rendered/fetched from cache. See getCurrentPageData() 00138 var $simulationHiddenOrTime=0; // See init(); Set if preview of some kind is enabled. 00139 00140 var $loaded = 0; // Set, if the TypoScript template structure is loaded and OK, see ->start() 00141 var $setup = Array( // Default TypoScript Setup code 00142 'styles.' => Array ( 00143 'insertContent' => 'CONTENT', 00144 'insertContent.' => Array ( 00145 'table' => 'tt_content', 00146 'select.' => Array ( 00147 'orderBy' => 'sorting', 00148 'where' => 'colPos=0', 00149 'languageField' => 'sys_language_uid' 00150 ) 00151 ) 00152 ), 00153 'config.' => Array ( 00154 'extTarget' => '_top', 00155 'stat' => 1, 00156 'stat_typeNumList' => '0,1' 00157 ) 00158 ); 00159 var $flatSetup = Array ( 00160 ); 00161 var $const = Array ( // Default TypoScript Constants code: 00162 '_clear' => '<img src="clear.gif" width="1" height="1" alt="" />', 00163 '_blackBorderWrap' => '<table border="0" bgcolor="black" cellspacing="0" cellpadding="1"><tr><td> | </td></tr></table>', 00164 '_tableWrap' => '<table border="0" cellspacing="0" cellpadding="0"> | </table>', 00165 '_tableWrap_DEBUG' => '<table border="1" cellspacing="0" cellpadding="0"> | </table>', 00166 '_stdFrameParams' => 'frameborder="no" marginheight="0" marginwidth="0" noresize="noresize"', 00167 '_stdFramesetParams' => 'border="0" framespacing="0" frameborder="no"' 00168 ); 00169 00170 00171 // For fetching TypoScript code from template hierarchy before parsing it. Each array contains code field values from template records/files: 00172 var $config = array(); // Setup field 00173 var $constants = array(); // Constant field 00174 var $editorcfg = array(); // Backend Editor Configuration field 00175 00176 var $hierarchyInfo = array(); // For Template Analyser in backend 00177 var $hierarchyInfoToRoot = array(); // For Template Analyser in backend (setup content only) 00178 var $nextLevel=0; // Next-level flag (see runThroughTemplates()) 00179 var $rootId; // The Page UID of the root page 00180 var $rootLine; // The rootline from current page to the root page 00181 var $absoluteRootLine; // Rootline all the way to the root. Set but runThroughTemplates 00182 var $outermostRootlineIndexWithTemplate=0; // A pointer to the last entry in the rootline where a template was found. 00183 var $rowSum; // Array of arrays with title/uid of templates in hierarchy 00184 var $resources=''; // Resources for the template hierarchy in a comma list 00185 var $sitetitle=''; // The current site title field. 00186 var $sections; // Tracking all conditions found during parsing of TypoScript. Used for the "all" key in currentPageData 00187 var $sectionsMatch; // Tracking all matching conditions found 00188 00189 // Backend: ts_analyzer 00190 var $clearList_const=array(); 00191 var $clearList_setup=array(); 00192 var $clearList_editorcfg=array(); 00193 var $parserErrors=array(); 00194 var $setup_constants = array(); 00195 00196 // Other: 00197 var $fileCache = Array(); // Used by getFileName for caching of references to file resources 00198 var $frames = Array(); // Keys are frame names and values are type-values, which must be used to refer correctly to the content of the frames. 00199 var $MPmap = ''; // Contains mapping of Page id numbers to MP variables. 00200 00201 00202 00203 00211 function init() { 00212 // $this->whereClause is used only to select templates from sys_template. 00213 // $GLOBALS['SIM_EXEC_TIME'] is used so that we're able to simulate a later time as a test... 00214 $this->whereClause='AND deleted=0 '; 00215 if (!$GLOBALS['TSFE']->showHiddenRecords) { 00216 $this->whereClause.='AND hidden=0 '; 00217 } 00218 if ($GLOBALS['TSFE']->showHiddenRecords || $GLOBALS['SIM_EXEC_TIME']!=$GLOBALS['EXEC_TIME']) { // Set the simulation flag, if simulation is detected! 00219 $this->simulationHiddenOrTime=1; 00220 } 00221 $this->whereClause.= 'AND (starttime<='.$GLOBALS['SIM_EXEC_TIME'].') AND (endtime=0 OR endtime>'.$GLOBALS['SIM_EXEC_TIME'].')'; 00222 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']) { 00223 $this->menuclasses='tmenu,jsmenu,gmenu'; 00224 } 00225 00226 // Sets the paths from where TypoScript resources are allowed to be used: 00227 $this->allowedPaths = Array ('media/','fileadmin/','uploads/','typo3temp/','t3lib/fonts/',TYPO3_mainDir.'ext/',TYPO3_mainDir.'sysext/','typo3conf/ext/'); 00228 if ($GLOBALS['TYPO3_CONF_VARS']['FE']['addAllowedPaths']) { 00229 $pathArr = t3lib_div::trimExplode(',',$GLOBALS['TYPO3_CONF_VARS']['FE']['addAllowedPaths'],1); 00230 while(list(,$p)=each($pathArr)) { 00231 // Once checked for path, but as this may run from typo3/mod/web/ts/ dir, that'll not work!! So the paths ar uncritically included here. 00232 $this->allowedPaths[] = $p; 00233 } 00234 } 00235 } 00236 00249 function getCurrentPageData() { 00250 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('content', 'cache_pagesection', 'page_id='.intval($GLOBALS['TSFE']->id).' AND mpvar_hash='.t3lib_div::md5int($GLOBALS['TSFE']->MP)); 00251 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00252 $this->currentPageData = unserialize($row['content']); 00253 } else { 00254 $this->currentPageData = 'none'; 00255 } 00256 return $this->currentPageData; 00257 } 00258 00266 function matching($cc) { 00267 if (is_array($cc['all'])) { 00268 reset($cc['all']); 00269 $matchObj = t3lib_div::makeInstance('t3lib_matchCondition'); 00270 $matchObj->altRootLine=$cc['rootLine']; 00271 while(list($key,$pre)=each($cc['all'])) { 00272 if ($matchObj->match($pre)) { 00273 $sectionsMatch[$key]=$pre; 00274 } 00275 } 00276 $cc['match']=$sectionsMatch; 00277 } 00278 return $cc; 00279 } 00280 00290 function start($theRootLine) { 00291 if (is_array($theRootLine)) { 00292 $setupData=''; 00293 $cc=Array(); 00294 $hash=''; 00295 $this->runThroughTemplates($theRootLine); 00296 00297 // Getting the currentPageData if not already found 00298 if (!$this->currentPageData) { 00299 $this->getCurrentPageData(); 00300 } 00301 00302 // This is about getting the hash string which is used to fetch the cached TypoScript template. 00303 // If there was some cached currentPageData that's good (it gives us the hash), 00304 // However if the actual rowSum and the rowSum of currentPageData is different from each other, thats a problem, and we should re-make the current page data. 00305 if (is_array($this->currentPageData) && 00306 !strcmp(serialize($this->rowSum), serialize($this->currentPageData['rowSum'])) // The two ROWsums must NOT be different from each other - which they will be if start/endtime or hidden has changed! 00307 ) { 00308 // If currentPageData was actually there, we match the result... 00309 $cc['all'] = $this->currentPageData['all']; 00310 $cc['rowSum'] = $this->currentPageData['rowSum']; 00311 $cc = $this->matching($cc); 00312 $hash = md5(serialize($cc)); 00313 } else { 00314 // If currentPageData was not there, we first find $rowSum (freshly generated). After that we try to see, if rowSum is stored with a list of all matching-parameters. If so we match the result 00315 $rowSumHash = md5('ROWSUM:'.serialize($this->rowSum)); 00316 $result = t3lib_pageSelect::getHash($rowSumHash, 0); 00317 if ($result) { 00318 $cc['all'] = unserialize($result); 00319 $cc['rowSum'] = $this->rowSum; 00320 $cc = $this->matching($cc); 00321 $hash = md5(serialize($cc)); 00322 } 00323 } 00324 00325 if ($hash) { 00326 // Get TypoScript setup array 00327 $setupData = t3lib_pageSelect::getHash($hash, 0); 00328 } 00329 00330 if ($hash && $setupData && !$this->forceTemplateParsing) { 00331 // If TypoScript setup structure was cached we unserialize it here: 00332 $this->setup = unserialize($setupData); 00333 } else { 00334 // Make configuration 00335 $this->generateConfig(); 00336 00337 // This stores the template hash thing 00338 $cc=Array(); 00339 $cc['all']=$this->sections; // All sections in the template at this point is found 00340 $cc['rowSum']=$this->rowSum; // The line of templates is collected 00341 $cc = $this->matching($cc); 00342 00343 $hash = md5(serialize($cc)); 00344 00345 // This stores the data. 00346 t3lib_pageSelect::storeHash($hash, serialize($this->setup), 'TS TEMPLATE'); 00347 00348 if ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('TS template size, serialized: '.strlen(serialize($this->setup)).' bytes'); 00349 00350 $rowSumHash = md5('ROWSUM:'.serialize($this->rowSum)); 00351 t3lib_pageSelect::storeHash($rowSumHash, serialize($cc['all']), 'TMPL CONDITIONS - AL'); 00352 } 00353 // Add rootLine 00354 $cc['rootLine'] = $this->rootLine; 00355 // Make global and save. 00356 $GLOBALS['TSFE']->all=$cc; 00357 00358 if (!$this->simulationHiddenOrTime) { // Only save currentPageData, if we're not simulating by hidden/starttime/endtime 00359 $insertFields = array( 00360 'page_id' => intval($GLOBALS['TSFE']->id), 00361 'mpvar_hash' => t3lib_div::md5int($GLOBALS['TSFE']->MP), 00362 'content' => serialize($cc), 00363 'tstamp' => $GLOBALS['EXEC_TIME'] 00364 ); 00365 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pagesection', 'page_id='.intval($GLOBALS['TSFE']->id).' AND mpvar_hash='.t3lib_div::md5int($GLOBALS['TSFE']->MP)); 00366 00367 $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_pagesection', $insertFields); 00368 } 00369 // If everything OK. 00370 if ($this->rootId && $this->rootLine && $this->setup) { 00371 $this->loaded = 1; 00372 } 00373 } 00374 } 00375 00376 00377 00378 00379 00380 00381 00382 00383 00384 00385 00386 00387 00388 00389 00390 /******************************************************************* 00391 * 00392 * Fetching TypoScript code text for the Template Hierarchy 00393 * 00394 *******************************************************************/ 00395 00406 function runThroughTemplates($theRootLine,$start_template_uid=0) { 00407 $this->constants = Array(); 00408 $this->config = Array(); 00409 $this->editorcfg = Array(); 00410 $this->rowSum = Array(); 00411 $this->hierarchyInfoToRoot = Array(); 00412 $this->absoluteRootLine=$theRootLine; // Is the TOTAL rootline 00413 00414 reset ($this->absoluteRootLine); 00415 $c=count($this->absoluteRootLine); 00416 for ($a=0;$a<$c;$a++) { 00417 if ($this->nextLevel) { // If some template loaded before has set a template-id for the next level, then load this template first! 00418 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'uid='.intval($this->nextLevel).' '.$this->whereClause); 00419 $this->nextLevel = 0; 00420 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00421 $this->versionOL($row); 00422 if (is_array($row)) { 00423 $this->processTemplate($row,'sys_'.$row['uid'],$this->absoluteRootLine[$a]['uid'],'sys_'.$row['uid']); 00424 $this->outermostRootlineIndexWithTemplate=$a; 00425 } 00426 } 00427 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00428 } 00429 $addC=''; 00430 if ($a==($c-1) && $start_template_uid) { // If first loop AND there is set an alternative template uid, use that 00431 $addC=' AND uid='.intval($start_template_uid); 00432 } 00433 00434 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'pid='.intval($this->absoluteRootLine[$a]['uid']).$addC.' '.$this->whereClause,'','sorting',1); 00435 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00436 $this->versionOL($row); 00437 if (is_array($row)) { 00438 $this->processTemplate($row,'sys_'.$row['uid'],$this->absoluteRootLine[$a]['uid'],'sys_'.$row['uid']); 00439 $this->outermostRootlineIndexWithTemplate=$a; 00440 } 00441 } 00442 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00443 $this->rootLine[] = $this->absoluteRootLine[$a]; 00444 } 00445 } 00446 00459 function processTemplate($row, $idList,$pid,$templateID='',$templateParent='') { 00460 // Adding basic template record information to rowSum array 00461 $this->rowSum[]=Array($row['uid'],$row['title'],$row['tstamp']); 00462 00463 // Processing "Clear"-flags 00464 if ($row['clear']) { 00465 $clConst = $row['clear']&1; 00466 $clConf = $row['clear']&2; 00467 if ($clConst) { 00468 $this->constants = Array(); 00469 $this->clearList_const=array(); 00470 } 00471 if ($clConf) { 00472 $this->config = Array(); 00473 $this->hierarchyInfoToRoot = Array(); 00474 $this->clearList_setup=array(); 00475 00476 $this->editorcfg = Array(); 00477 $this->clearList_editorcfg=array(); 00478 } 00479 } 00480 00481 // Include static records (static_template) or files (from extensions) (#1/2) 00482 if (!$row['includeStaticAfterBasedOn']) { // NORMAL inclusion, The EXACT same code is found below the basedOn inclusion!!! 00483 $this->includeStaticTypoScriptSources($idList,$templateID,$pid,$row); 00484 } 00485 00486 // Include "Based On" sys_templates: 00487 if (trim($row['basedOn'])) { // 'basedOn' is a list of templates to include 00488 // Manually you can put this value in the field and then the based_on ID will be taken from the $_GET var defined by '=....'. 00489 // Example: If $row['basedOn'] is 'EXTERNAL_BASED_ON_TEMPLATE_ID=based_on_uid', then the global var, based_on_uid - given by the URL like '&based_on_uid=999' - is included instead! 00490 // This feature allows us a hack to test/demonstrate various included templates on the same set of content bearing pages. Used by the "freesite" extension. 00491 $basedOn_hackFeature = explode('=',$row['basedOn']); 00492 if ($basedOn_hackFeature[0]=='EXTERNAL_BASED_ON_TEMPLATE_ID' && $basedOn_hackFeature[1]) { 00493 $id = intval(t3lib_div::_GET($basedOn_hackFeature[1])); 00494 if ($id && !t3lib_div::inList($idList,'sys_'.$id)) { // if $id is not allready included ... 00495 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'uid='.$id.' '.$this->whereClause); 00496 if ($subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { // there was a template, then we fetch that 00497 $this->versionOL($subrow); 00498 if (is_array($subrow)) { 00499 $this->processTemplate($subrow,$idList.',sys_'.$id,$pid, 'sys_'.$id,$templateID); 00500 } 00501 } 00502 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00503 } 00504 } else { // NORMAL OPERATION: 00505 $basedOnArr = t3lib_div::intExplode(',',$row['basedOn']); 00506 while(list(,$id)=each($basedOnArr)) { // traversing list 00507 if (!t3lib_div::inList($idList,'sys_'.$id)) { // if $id is not allready included ... 00508 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'uid='.intval($id).' '.$this->whereClause); 00509 if ($subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { // there was a template, then we fetch that 00510 $this->versionOL($subrow); 00511 if (is_array($subrow)) { 00512 $this->processTemplate($subrow,$idList.',sys_'.$id,$pid, 'sys_'.$id,$templateID); 00513 } 00514 } 00515 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00516 } 00517 } 00518 } 00519 } 00520 00521 // Include static records (static_template) or files (from extensions) (#2/2) 00522 if ($row['includeStaticAfterBasedOn']) { 00523 $this->includeStaticTypoScriptSources($idList,$templateID,$pid,$row); 00524 } 00525 00526 // Creating hierarchy information; Used by backend analysis tools 00527 $this->hierarchyInfo[] = $this->hierarchyInfoToRoot[] = array( 00528 'root'=>trim($row['root']), 00529 'next'=>$row['nextLevel'], 00530 'clConst'=>$clConst, 00531 'clConf'=>$clConf, 00532 'templateID'=>$templateID, 00533 'templateParent'=>$templateParent, 00534 'title'=>$row['title'], 00535 'uid'=>$row['uid'], 00536 'pid'=>$row['pid'], 00537 'configLines' => substr_count($row['config'], chr(10))+1 00538 ); 00539 00540 // Adding the content of the fields constants (Constants), config (Setup) and editorcfg (Backend Editor Configuration) to the internal arrays. 00541 $this->constants[] = $row['constants']; 00542 $this->config[] = $row['config']; 00543 if ($this->parseEditorCfgField) $this->editorcfg[] = $row['editorcfg']; 00544 00545 // For backend analysis (Template Analyser) provide the order of added constants/config/editorcfg template IDs 00546 $this->clearList_const[]=$templateID; 00547 $this->clearList_setup[]=$templateID; 00548 if ($this->parseEditorCfgField) $this->clearList_editorcfg[]=$templateID; 00549 00550 // Add resources and sitetitle if found: 00551 if (trim($row['resources'])) { 00552 $this->resources = $row['resources'].','.$this->resources; 00553 } 00554 if (trim($row['sitetitle'])) { 00555 $this->sitetitle = $row['sitetitle']; 00556 } 00557 // If the template record is a Rootlevel record, set the flag and clear the template rootLine (so it starts over from this point) 00558 if (trim($row['root'])) { 00559 $this->rootId = $pid; 00560 $this->rootLine = Array(); 00561 } 00562 // If a template is set to be active on the next level set this internal value to point to this UID. (See runThroughTemplates()) 00563 if ($row['nextLevel']) { 00564 $this->nextLevel = $row['nextLevel']; 00565 } else { 00566 $this->nextLevel = 0; 00567 } 00568 } 00569 00580 function includeStaticTypoScriptSources($idList,$templateID,$pid,$row) { 00581 // Static Template Records (static_template): include_static is a list of static templates to include 00582 if (trim($row['include_static'])) { 00583 $include_staticArr = t3lib_div::intExplode(',',$row['include_static']); 00584 reset($include_staticArr); 00585 while(list(,$id)=each($include_staticArr)) { // traversing list 00586 if (!t3lib_div::inList($idList,'static_'.$id)) { // if $id is not allready included ... 00587 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'static_template', 'uid='.intval($id)); 00588 if ($subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { // there was a template, then we fetch that 00589 $subrow = $this->prependStaticExtra($subrow); 00590 $this->processTemplate($subrow,$idList.',static_'.$id,$pid,'static_'.$id,$templateID); 00591 } 00592 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00593 } 00594 } 00595 } 00596 00597 // Static Template Files (Text files from extensions): include_static_file is a list of static files to include (from extensions) 00598 if (trim($row['include_static_file'])) { 00599 $include_static_fileArr = t3lib_div::trimExplode(',',$row['include_static_file'],1); 00600 reset($include_static_fileArr); 00601 while(list(,$ISF_file)=each($include_static_fileArr)) { // traversing list 00602 $ISF_file = trim($ISF_file); 00603 if (substr($ISF_file,0,4)=='EXT:') { 00604 list($ISF_extKey,$ISF_localPath) = explode('/',substr($ISF_file,4),2); 00605 if (strcmp($ISF_extKey,'') && t3lib_extMgm::isLoaded($ISF_extKey) && strcmp($ISF_localPath,'')) { 00606 $ISF_localPath = ereg_replace('\/$','',$ISF_localPath).'/'; 00607 $ISF_filePath = t3lib_extMgm::extPath($ISF_extKey).$ISF_localPath; 00608 if (@is_dir($ISF_filePath)) { 00609 $mExtKey = str_replace('_','',$ISF_extKey.'/'.$ISF_localPath); 00610 $subrow=array( 00611 'constants'=> @is_file($ISF_filePath.'constants.txt') ?t3lib_div::getUrl($ISF_filePath.'constants.txt'):'', 00612 'config'=> @is_file($ISF_filePath.'setup.txt') ?t3lib_div::getUrl($ISF_filePath.'setup.txt'):'', 00613 'editorcfg'=> @is_file($ISF_filePath.'editorcfg.txt') ?t3lib_div::getUrl($ISF_filePath.'editorcfg.txt'):'', 00614 'include_static'=> @is_file($ISF_filePath.'include_static.txt')?implode(',',array_unique(t3lib_div::intExplode(',',t3lib_div::getUrl($ISF_filePath.'include_static.txt')))):'', 00615 'include_static_file'=> @is_file($ISF_filePath.'include_static_file.txt')?implode(',',array_unique(explode(',',t3lib_div::getUrl($ISF_filePath.'include_static_file.txt')))):'', 00616 'title' => $ISF_file, 00617 'uid' => $mExtKey 00618 ); 00619 $subrow = $this->prependStaticExtra($subrow); 00620 00621 $this->processTemplate($subrow,$idList.',ext_'.$mExtKey,$pid, 'ext_'.$mExtKey,$templateID); 00622 } 00623 } 00624 } 00625 } 00626 } 00627 00628 $this->addExtensionStatics($idList,$templateID,$pid,$row); 00629 } 00630 00642 function addExtensionStatics($idList,$templateID,$pid,$row) { 00643 global $TYPO3_LOADED_EXT; 00644 00645 if ($row['static_file_mode']==1 || ($row['static_file_mode']==0 && substr($templateID,0,4)=='sys_' && $row['root'])) { 00646 reset($TYPO3_LOADED_EXT); 00647 while(list($extKey,$files)=each($TYPO3_LOADED_EXT)) { 00648 if (is_array($files) && ($files['ext_typoscript_constants.txt'] || $files['ext_typoscript_setup.txt'] || $files['ext_typoscript_editorcfg.txt'])) { 00649 $mExtKey = str_replace('_','',$extKey); 00650 $subrow=array( 00651 'constants'=> $files['ext_typoscript_constants.txt']?t3lib_div::getUrl($files['ext_typoscript_constants.txt']):'', 00652 'config'=> $files['ext_typoscript_setup.txt']?t3lib_div::getUrl($files['ext_typoscript_setup.txt']):'', 00653 'editorcfg'=> $files['ext_typoscript_editorcfg.txt']?t3lib_div::getUrl($files['ext_typoscript_editorcfg.txt']):'', 00654 'title' => $extKey, 00655 'uid' => $mExtKey 00656 ); 00657 $subrow = $this->prependStaticExtra($subrow); 00658 00659 $this->processTemplate($subrow,$idList.',ext_'.$mExtKey,$pid, 'ext_'.$mExtKey,$templateID); 00660 } 00661 } 00662 } 00663 } 00664 00675 function prependStaticExtra($subrow) { 00676 $subrow['config'].=$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_setup.'][$subrow['uid']]; 00677 $subrow['editorcfg'].=$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_editorcfg.'][$subrow['uid']]; 00678 $subrow['constants'].=$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_constants.'][$subrow['uid']]; 00679 return $subrow; 00680 } 00681 00688 function versionOL(&$row) { 00689 if (is_object($GLOBALS['TSFE'])) { // Frontend: 00690 $GLOBALS['TSFE']->sys_page->versionOL('sys_template',$row); 00691 } else { // Backend: 00692 t3lib_BEfunc::workspaceOL('sys_template',$row); 00693 } 00694 } 00695 00696 00697 00698 00699 00700 00701 00702 00703 00704 00705 00706 00707 00708 00709 00710 00711 00712 /******************************************************************* 00713 * 00714 * Parsing TypoScript code text from Template Records into PHP array 00715 * 00716 *******************************************************************/ 00717 00725 function generateConfig() { 00726 // Add default TS for all three code types: 00727 array_unshift($this->constants,''.$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_constants']); // Adding default TS/constants 00728 array_unshift($this->config,''.$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_setup']); // Adding default TS/setup 00729 array_unshift($this->editorcfg,''.$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_editorcfg']); // Adding default TS/editorcfg 00730 00731 // Parse the TypoScript code text for include-instructions! 00732 $this->procesIncludes(); 00733 00734 // These vars are also set lateron... 00735 $this->setup['resources']= $this->resources; 00736 $this->setup['sitetitle']= $this->sitetitle; 00737 00738 00739 00740 // **************************** 00741 // Parse TypoScript Constants 00742 // **************************** 00743 00744 // Initialize parser and match-condition classes: 00745 $constants = t3lib_div::makeInstance('t3lib_TSparser'); 00746 $constants->breakPointLN=intval($this->ext_constants_BRP); 00747 $constants->setup = $this->const; 00748 $constants->setup = $this->mergeConstantsFromPageTSconfig($constants->setup); 00749 $matchObj = t3lib_div::makeInstance('t3lib_matchCondition'); 00750 $matchObj->matchAlternative = $this->matchAlternative; 00751 $matchObj->matchAll = $this->matchAll; // Matches ALL conditions in TypoScript 00752 00753 // Traverse constants text fields and parse them 00754 foreach($this->constants as $str) { 00755 $constants->parse($str,$matchObj); 00756 } 00757 00758 // Read out parse errors if any 00759 $this->parserErrors['constants']=$constants->errors; 00760 00761 // Then flatten the structure from a multi-dim array to a single dim array with all constants listed as key/value pairs (ready for substitution) 00762 $this->flatSetup = Array(); 00763 $this->flattenSetup($constants->setup,'',''); 00764 00765 00766 00767 // *********************************************** 00768 // Parse TypoScript Setup (here called "config") 00769 // *********************************************** 00770 // Initialize parser and match-condition classes: 00771 $config = t3lib_div::makeInstance('t3lib_TSparser'); 00772 $config->breakPointLN = intval($this->ext_config_BRP); 00773 $config->regLinenumbers = $this->ext_regLinenumbers; 00774 $config->setup = $this->setup; 00775 00776 // Transfer information about conditions found in "Constants" and which of them returned true. 00777 $config->sections = $constants->sections; 00778 $config->sectionsMatch = $constants->sectionsMatch; 00779 00780 // Traverse setup text fields and concatenate them into one, single string separated by a [GLOBAL] condition 00781 $all=''; 00782 foreach($this->config as $str) { 00783 $all.="\n[GLOBAL]\n".$str; 00784 } 00785 00786 // Substitute constants in the Setup code: 00787 if ($this->tt_track) $GLOBALS['TT']->push('Substitute Constants ('.count($this->flatSetup).')'); 00788 $all = $this->substituteConstants($all); 00789 if ($this->tt_track) $GLOBALS['TT']->pull(); 00790 00791 // Searching for possible unsubstituted constants left (only for information) 00792 if (strstr($all,'{$')) { 00793 $findConst = explode('{$',$all); 00794 $theConstList=Array(); 00795 next($findConst); 00796 while(list(,$constVal)=each($findConst)) { 00797 $constLen=t3lib_div::intInRange(strcspn($constVal,'}'),0,50); 00798 $theConstList[]='{$'.substr($constVal,0,$constLen+1); 00799 } 00800 if ($this->tt_track) $GLOBALS['TT']->setTSlogMessage(implode(',',$theConstList).': Constants may remain un-substituted!!',2); 00801 } 00802 00803 // Logging the textual size of the TypoScript Setup field text with all constants substituted: 00804 if ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('TypoScript template size as textfile: '.strlen($all).' bytes'); 00805 00806 // Finally parse the Setup field TypoScript code (where constants are now substituted) 00807 $config->parse($all,$matchObj); 00808 00809 // Read out parse errors if any 00810 $this->parserErrors['config']=$config->errors; 00811 00812 // Transfer the TypoScript array from the parser object to the internal $this->setup array: 00813 $this->setup = $config->setup; 00814 if ($this->backend_info) { 00815 $this->setup_constants = $constants->setup; // Used for backend purposes only 00816 } 00817 00818 00819 00820 00821 // ************************************************** 00822 // Parse Backend Editor Configuration (backend only) 00823 // ************************************************** 00824 if ($this->parseEditorCfgField) { 00825 $editorcfg = t3lib_div::makeInstance('t3lib_TSparser'); 00826 $editorcfg->breakPointLN=intval($this->ext_editorcfg_BRP); 00827 $editorcfg->setup = array(); // Empty as a start... 00828 00829 $all = implode("\n[GLOBAL]\n",$this->editorcfg); 00830 00831 // substitute constants in config 00832 $all = $this->substituteConstants($all); 00833 00834 // parse Config 00835 $matchObj->matchAll=1; // This should make sure that conditions are disabled. For now they are NOT active for the backend. 00836 $editorcfg->parse($all,$matchObj); 00837 $this->parserErrors['editorcfg']=$editorcfg->errors; 00838 $this->setup_editorcfg = $editorcfg->setup; 00839 } 00840 00841 00842 00843 00844 00845 // **************************************************************** 00846 // Final processing of the $this->setup TypoScript Template array 00847 // Basically: This is unsetting/setting of certain reserved keys. 00848 // **************************************************************** 00849 00850 // These vars are allready set after 'processTemplate', but because $config->setup overrides them (in the line above!), we set them again. They are not changed compared to the value they had in the top of the page! 00851 unset($this->setup['resources']); 00852 unset($this->setup['resources.']); 00853 $this->setup['resources']= implode(',',t3lib_div::trimExplode(',',$this->resources,1)); 00854 00855 unset($this->setup['sitetitle']); 00856 unset($this->setup['sitetitle.']); 00857 $this->setup['sitetitle']= $this->sitetitle; 00858 00859 // Unsetting some vars... 00860 unset($this->setup['types.']); 00861 unset($this->setup['types']); 00862 if (is_array($this->setup)) { 00863 reset ($this->setup); 00864 while(list($theKey,)=each($this->setup)) { 00865 if ($this->setup[$theKey]=='PAGE') { 00866 $tN = $this->setup[$theKey.'.']['typeNum']; 00867 if (isset($tN)) { 00868 $this->setup['types.'][$tN] = $theKey; 00869 } elseif(!$this->setup['types.'][0]) { // If there is no type 0 yet and typeNum was not set, we use the current object as the default 00870 $this->setup['types.'][0] = $theKey; 00871 } 00872 } 00873 } 00874 } 00875 unset($this->setup['styles.']); 00876 unset($this->setup['temp.']); 00877 unset($constants); 00878 00879 // Storing the conditions found/matched information: 00880 $this->sections = $config->sections; 00881 $this->sectionsMatch = $config->sectionsMatch; 00882 } 00883 00891 function procesIncludes() { 00892 reset($this->constants); 00893 while(list($k)=each($this->constants)) { 00894 $this->constants[$k]=t3lib_TSparser::checkIncludeLines($this->constants[$k]); 00895 } 00896 00897 reset($this->config); 00898 while(list($k)=each($this->config)) { 00899 $this->config[$k]=t3lib_TSparser::checkIncludeLines($this->config[$k]); 00900 } 00901 00902 reset($this->editorcfg); 00903 while(list($k)=each($this->editorcfg)) { 00904 $this->editorcfg[$k]=t3lib_TSparser::checkIncludeLines($this->editorcfg[$k]); 00905 } 00906 } 00907 00915 function mergeConstantsFromPageTSconfig($constArray) { 00916 $TSdataArray = array(); 00917 $TSdataArray[]=$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig']; // Setting default configuration: 00918 00919 for ($a=0;$a<=$this->outermostRootlineIndexWithTemplate;$a++) { 00920 $TSdataArray[]=$this->absoluteRootLine[$a]['TSconfig']; 00921 } 00922 // Parsing the user TS (or getting from cache) 00923 $TSdataArray = t3lib_TSparser::checkIncludeLines_array($TSdataArray); 00924 $userTS = implode(chr(10).'[GLOBAL]'.chr(10),$TSdataArray); 00925 00926 $parseObj = t3lib_div::makeInstance('t3lib_TSparser'); 00927 $parseObj->parse($userTS); 00928 00929 if (is_array($parseObj->setup['TSFE.']['constants.'])) { 00930 $constArray = t3lib_div::array_merge_recursive_overrule($constArray,$parseObj->setup['TSFE.']['constants.']); 00931 } 00932 return $constArray; 00933 } 00934 00944 function flattenSetup($setupArray, $prefix, $resourceFlag) { 00945 if (is_array($setupArray)) { 00946 reset($setupArray); 00947 while(list($key,$val)=each($setupArray)) { 00948 if ($prefix || substr($key,0,16)!='TSConstantEditor') { // We don't want 'TSConstantEditor' in the flattend setup on the first level (190201) 00949 if (is_array($val)) { 00950 $this->flattenSetup($val,$prefix.$key, ($key=='file.')); 00951 } elseif ($resourceFlag) { 00952 $this->flatSetup[$prefix.$key] = $this->getFileName($val); 00953 } else { 00954 $this->flatSetup[$prefix.$key] = $val; 00955 } 00956 } 00957 } 00958 } 00959 } 00960 00968 function substituteConstants($all) { 00969 if ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('Constants to substitute: '.count($this->flatSetup)); 00970 00971 $noChange = false; 00972 // recursive substitution of constants (up to 10 nested levels) 00973 for ($i = 0; $i < 10 && !$noChange; $i++) { 00974 $old_all = $all; 00975 $all = preg_replace_callback('/\{\$(.[^}]*)\}/', array($this, 'substituteConstantsCallBack'), $all); 00976 if ($old_all == $all) { 00977 $noChange = true; 00978 } 00979 } 00980 00981 return $all; 00982 } 00983 00991 function substituteConstantsCallBack($matches) { 00992 // replace {$CONST} if found in $this->flatSetup, else leave unchanged 00993 return isset($this->flatSetup[$matches[1]]) && !is_array($this->flatSetup[$matches[1]]) ? $this->flatSetup[$matches[1]] : $matches[0]; 00994 } 00995 00996 00997 00998 00999 01000 01001 01002 01003 01004 01005 /******************************************************************* 01006 * 01007 * Various API functions, used from elsewhere in the frontend classes 01008 * 01009 *******************************************************************/ 01010 01022 function splitConfArray($conf,$splitCount) { 01023 01024 // Initialize variables: 01025 $splitCount = intval($splitCount); 01026 $conf2 = Array(); 01027 01028 if ($splitCount && is_array($conf)) { 01029 01030 // Initialize output to carry at least the keys: 01031 for ($aKey=0;$aKey<$splitCount;$aKey++) { 01032 $conf2[$aKey] = array(); 01033 } 01034 01035 // Recursive processing of array keys: 01036 foreach($conf as $cKey => $val) { 01037 if (is_array($val)) { 01038 $tempConf = $this->splitConfArray($val,$splitCount); 01039 foreach($tempConf as $aKey => $val) { 01040 $conf2[$aKey][$cKey] = $val; 01041 } 01042 } 01043 } 01044 01045 // Splitting of all values on this level of the TypoScript object tree: 01046 foreach($conf as $cKey => $val) { 01047 if (!is_array($val)) { 01048 if (!strstr($val,'|*|') && !strstr($val,'||')) { 01049 for ($aKey=0;$aKey<$splitCount;$aKey++) { 01050 $conf2[$aKey][$cKey] = $val; 01051 } 01052 } else { 01053 $main = explode ('|*|',$val); 01054 $mainCount = count($main); 01055 01056 $lastC = 0; 01057 $middleC = 0; 01058 $firstC = 0; 01059 01060 if ($main[0]) { 01061 $first = explode('||',$main[0]); 01062 $firstC = count($first); 01063 } 01064 if ($main[1]) { 01065 $middle = explode('||',$main[1]); 01066 $middleC = count($middle); 01067 } 01068 if ($main[2]) { 01069 $last = explode('||',$main[2]); 01070 $lastC = count($last); 01071 $value = $last[0]; 01072 } 01073 01074 for ($aKey=0;$aKey<$splitCount;$aKey++) { 01075 if ($firstC && isset($first[$aKey])) { 01076 $value = $first[$aKey]; 01077 } elseif ($middleC) { 01078 $value = $middle[($aKey-$firstC)%$middleC]; 01079 } 01080 if ($lastC && $lastC>=($splitCount-$aKey)) { 01081 $value = $last[$lastC-($splitCount-$aKey)]; 01082 } 01083 $conf2[$aKey][$cKey] = trim($value); 01084 } 01085 } 01086 } 01087 } 01088 } 01089 return $conf2; 01090 } 01091 01099 function getFileName($fileFromSetup) { 01100 $file = trim($fileFromSetup); 01101 if (!$file) { 01102 return; 01103 } elseif (strstr($file,'../')) { 01104 if ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('File path "'.$file.'" contained illegal string "../"!',3); 01105 return; 01106 } 01107 // cache 01108 $hash = md5($file); 01109 if (isset($this->fileCache[$hash])) { 01110 return $this->fileCache[$hash]; 01111 } 01112 01113 if (!strcmp(substr($file,0,4),'EXT:')) { 01114 $newFile=''; 01115 list($extKey,$script)=explode('/',substr($file,4),2); 01116 if ($extKey && t3lib_extMgm::isLoaded($extKey)) { 01117 $extPath=t3lib_extMgm::extPath($extKey); 01118 $newFile=substr($extPath,strlen(PATH_site)).$script; 01119 } 01120 if (!@is_file(PATH_site.$newFile)) { 01121 if ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('Extension media file "'.$newFile.'" was not found!',3); 01122 return; 01123 } else $file=$newFile; 01124 } 01125 01126 // find 01127 if (strstr($file,'/')) { // here it is manual media 01128 if(!strcmp(substr($file,0,6),'media/')) $file = 'typo3/sysext/cms/tslib/'.$file; 01129 if (@is_file($this->getFileName_backPath.$file)) { 01130 $outFile = $file; 01131 $fileInfo = t3lib_div::split_fileref($outFile); 01132 reset($this->allowedPaths); 01133 $OK=0; 01134 while(list(,$val)=each($this->allowedPaths)) { 01135 if (substr($fileInfo['path'],0,strlen($val))==$val){$OK=1; break;} 01136 } 01137 if ($OK) { 01138 $this->fileCache[$hash]=$outFile; 01139 return $outFile; 01140 } elseif ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('"'.$file.'" was not located in the allowed paths: ('.implode(',',$this->allowedPaths).')',3); 01141 } elseif ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('"'.$this->getFileName_backPath.$file.'" is not a file (non-uploads/.. resource, did not exist).',3); 01142 } else { // Here it is uploaded media: 01143 $outFile = $this->extractFromResources($this->setup['resources'],$file); 01144 if ($outFile) { 01145 if (@is_file($this->uplPath.$outFile)) { 01146 $this->fileCache[$hash] = $this->uplPath.$outFile; 01147 return $this->uplPath.$outFile; 01148 } elseif ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('"'.$this->uplPath.$outFile.'" is not a file (did not exist).',3); 01149 } elseif ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('"'.$file.'" is not a file (uploads/.. resource).',3); 01150 } 01151 } 01152 01162 function extractFromResources($res,$file) { 01163 if (t3lib_div::inList($res,$file)) { 01164 $outFile = $file; 01165 } elseif (strstr($file,'*')) { 01166 $fileparts=explode('*',$file); 01167 $c=count($fileparts); 01168 $files = explode(',',$res); 01169 while(list(,$val)=each($files)) { 01170 $test = trim($val); 01171 if (ereg('^'.quotemeta($fileparts[0]).'.*'.quotemeta($fileparts[$c-1]).'$', $test)) { 01172 $outFile = $test; 01173 break; 01174 } 01175 } 01176 } 01177 return $outFile; 01178 } 01179 01190 function checkFile($name,$menuArr) { 01191 reset ($menuArr); 01192 while (list($aKey,)=each($menuArr)) { 01193 $menuArr[$aKey][$name] = $this->getFileName($menuArr[$aKey][$name]); 01194 } 01195 return $menuArr; 01196 } 01197 01207 function printTitle($title,$no_title=0,$titleFirst=0) { 01208 $st = trim($this->setup['sitetitle']) ? $this->setup['sitetitle']:''; 01209 $title = $no_title ? '' : $title; 01210 if ($titleFirst) { 01211 $temp=$st; 01212 $st=$title; 01213 $title=$temp; 01214 } 01215 if ($title && $st) { 01216 return $st.': '.$title; 01217 } else { 01218 return $st.$title; 01219 } 01220 } 01221 01230 function fileContent($fName) { 01231 $incFile = $this->getFileName($fName); 01232 if ($incFile && $fd=fopen($incFile,'rb')) { 01233 $content = ''; 01234 while (!feof($fd)) { 01235 $content.=fread($fd, 5000); 01236 } 01237 fclose( $fd ); 01238 return $content; 01239 } 01240 } 01241 01250 function wrap($content,$wrap) { 01251 if ($wrap) { 01252 $wrapArr = explode('|', $wrap); 01253 return trim($wrapArr[0]).$content.trim($wrapArr[1]); 01254 } else return $content; 01255 } 01256 01264 function removeQueryString($url) { 01265 if (substr($url,-1)=='?') { 01266 return substr($url,0,-1); 01267 } else { 01268 return $url; 01269 } 01270 } 01271 01281 function sortedKeyList($setupArr, $acceptOnlyProperties=FALSE) { 01282 $keyArr = Array(); 01283 01284 reset($setupArr); 01285 while(list($key,)=each($setupArr)) { 01286 $ikey = intval($key); 01287 if (!strcmp($ikey,$key) || $acceptOnlyProperties) { 01288 $keyArr[] = $ikey; 01289 } 01290 } 01291 01292 $keyArr = array_unique($keyArr); 01293 sort($keyArr); 01294 return $keyArr; 01295 } 01296 01297 01298 01299 01300 01301 01302 01303 01304 01305 01306 /******************************************************************* 01307 * 01308 * Functions for creating links 01309 * 01310 *******************************************************************/ 01311 01328 function linkData($page,$oTarget,$no_cache,$script,$overrideArray='',$addParams='',$typeOverride='') { 01329 global $TYPO3_CONF_VARS; 01330 01331 $LD = Array(); 01332 01333 // Overriding some fields in the page record and still preserves the values by adding them as parameters. Little strange function. 01334 if (is_array($overrideArray)) { 01335 foreach($overrideArray as $theKey => $theNewVal) { 01336 $addParams.= '&real_'.$theKey.'='.rawurlencode($page[$theKey]); 01337 $page[$theKey] = $theNewVal; 01338 } 01339 } 01340 01341 // Adding Mount Points, "&MP=", parameter for the current page if any is set: 01342 if (!strstr($addParams,'&MP=')) { 01343 if (trim($GLOBALS['TSFE']->MP_defaults[$page['uid']])) { // Looking for hardcoded defaults: 01344 $addParams.= '&MP='.rawurlencode(trim($GLOBALS['TSFE']->MP_defaults[$page['uid']])); 01345 } elseif ($GLOBALS['TSFE']->config['config']['MP_mapRootPoints']) { // Else look in automatically created map: 01346 $m = $this->getFromMPmap($page['uid']); 01347 if ($m) { 01348 $addParams.= '&MP='.rawurlencode($m); 01349 } 01350 } 01351 } 01352 01353 // Setting ID/alias: 01354 if (!$script) {$script = $GLOBALS['TSFE']->config['mainScript'];} 01355 if ($page['alias']) { 01356 $LD['url'] = $script.'?id='.rawurlencode($page['alias']); 01357 } else { 01358 $LD['url'] = $script.'?id='.$page['uid']; 01359 } 01360 // Setting target 01361 $LD['target'] = trim($page['target']) ? trim($page['target']) : $oTarget; 01362 01363 // typeNum 01364 $typeNum = $this->setup[$LD['target'].'.']['typeNum']; 01365 if (!$typeOverride && intval($GLOBALS['TSFE']->config['config']['forceTypeValue'])) { 01366 $typeOverride = intval($GLOBALS['TSFE']->config['config']['forceTypeValue']); 01367 } 01368 if (strcmp($typeOverride,'')) { $typeNum = $typeOverride; } // Override... 01369 if ($typeNum) { 01370 $LD['type'] = '&type='.intval($typeNum); 01371 } else { 01372 $LD['type'] = ''; 01373 } 01374 $LD['orig_type'] = $LD['type']; // Preserving the type number. Will not be cleared if simulateStaticDocuments. 01375 01376 // noCache 01377 $LD['no_cache'] = (trim($page['no_cache']) || $no_cache) ? '&no_cache=1' : ''; 01378 01379 // linkVars 01380 if ($GLOBALS['TSFE']->config['config']['uniqueLinkVars']) { 01381 if ($addParams) { 01382 $LD['linkVars'] = t3lib_div::implodeArrayForUrl('',t3lib_div::explodeUrl2Array($GLOBALS['TSFE']->linkVars.$addParams)); 01383 } else { 01384 $LD['linkVars'] = $GLOBALS['TSFE']->linkVars; 01385 } 01386 } else { 01387 $LD['linkVars'] = $GLOBALS['TSFE']->linkVars.$addParams; 01388 } 01389 01390 // If simulateStaticDocuments is enabled: 01391 if ($GLOBALS['TSFE']->config['config']['simulateStaticDocuments']) { 01392 $LD['type'] = ''; 01393 $LD['url'] = ''; 01394 01395 // MD5/base64 method limitation: 01396 $remainLinkVars=''; 01397 $flag_simulateStaticDocuments_pEnc = t3lib_div::inList('md5,base64',$GLOBALS['TSFE']->config['config']['simulateStaticDocuments_pEnc']) && !$LD['no_cache']; 01398 if ($flag_simulateStaticDocuments_pEnc) { 01399 list($LD['linkVars'], $remainLinkVars) = $GLOBALS['TSFE']->simulateStaticDocuments_pEnc_onlyP_proc($LD['linkVars']); 01400 } 01401 01402 $LD['url'].=$GLOBALS['TSFE']->makeSimulFileName( 01403 $page['title'], 01404 $page['alias'] ? $page['alias'] : $page['uid'], 01405 intval($typeNum), 01406 $LD['linkVars'], 01407 $LD['no_cache']?1:0 01408 ); 01409 01410 if ($flag_simulateStaticDocuments_pEnc) { 01411 $LD['linkVars']=$remainLinkVars; 01412 } 01413 if ($GLOBALS['TSFE']->config['config']['simulateStaticDocuments']=='PATH_INFO') { 01414 $LD['url'] = str_replace('.','/',$LD['url']); 01415 $LD['url'] = 'index.php/'.$LD['url'].'/?'; 01416 } else { 01417 $LD['url'].= '.html?'; 01418 } 01419 } 01420 01421 // Add absRefPrefix if exists. 01422 $LD['url'] = $GLOBALS['TSFE']->absRefPrefix.$LD['url']; 01423 01424 // If the special key 'sectionIndex_uid' (added 'manually' in tslib/menu.php to the page-record) is set, then the link jumps directly to a section on the page. 01425 $LD['sectionIndex'] = $page['sectionIndex_uid'] ? '#'.$page['sectionIndex_uid'] : ''; 01426 01427 // Compile the normal total url 01428 $LD['totalURL']= $this->removeQueryString($LD['url'].$LD['type'].$LD['no_cache'].$LD['linkVars'].$GLOBALS['TSFE']->getMethodUrlIdToken).$LD['sectionIndex']; 01429 01430 // Call post processing function for link rendering: 01431 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tstemplate.php']['linkData-PostProc'])) { 01432 $_params = array( 01433 'LD' => &$LD, 01434 'args' => array('page'=>$page, 'oTarget'=>$oTarget, 'no_cache'=>$no_cache, 'script'=>$script, 'overrideArray'=>$overrideArray, 'addParams'=>$addParams, 'typeOverride'=>$typeOverride), 01435 'typeNum' => $typeNum 01436 ); 01437 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tstemplate.php']['linkData-PostProc'] as $_funcRef) { 01438 t3lib_div::callUserFunction($_funcRef,$_params,$this); 01439 } 01440 } 01441 01442 // Return the LD-array 01443 return $LD; 01444 } 01445 01455 function getFromMPmap($pageId=0) { 01456 01457 // Create map if not found already: 01458 if (!is_array($this->MPmap)) { 01459 $this->MPmap = array(); 01460 01461 $rootPoints = t3lib_div::trimExplode(',', strtolower($GLOBALS['TSFE']->config['config']['MP_mapRootPoints']),1); 01462 foreach($rootPoints as $p) { // Traverse rootpoints: 01463 if ($p == 'root') { 01464 $p = $this->rootLine[0]['uid']; 01465 $initMParray = array(); 01466 if ($this->rootLine[0]['_MOUNT_OL'] && $this->rootLine[0]['_MP_PARAM']) { 01467 $initMParray[] = $this->rootLine[0]['_MP_PARAM']; 01468 } 01469 } 01470 $this->initMPmap_create($p,$initMParray); 01471 } 01472 } 01473 01474 // Finding MP var for Page ID: 01475 if ($pageId) { 01476 if (is_array($this->MPmap[$pageId]) && count($this->MPmap[$pageId])) { 01477 return implode(',',$this->MPmap[$pageId]); 01478 } 01479 } 01480 } 01481 01491 function initMPmap_create($id,$MP_array=array(),$level=0) { 01492 01493 $id = intval($id); 01494 if($id<=0) return; 01495 01496 // First level, check id 01497 if (!$level) { 01498 01499 // Find mount point if any: 01500 $mount_info = $GLOBALS['TSFE']->sys_page->getMountPointInfo($id); 01501 01502 // Overlay mode: 01503 if (is_array($mount_info) && $mount_info['overlay']) { 01504 $MP_array[] = $mount_info['MPvar']; 01505 $id = $mount_info['mount_pid']; 01506 } 01507 01508 // Set mapping information for this level: 01509 $this->MPmap[$id] = $MP_array; 01510 01511 // Normal mode: 01512 if (is_array($mount_info) && !$mount_info['overlay']) { 01513 $MP_array[] = $mount_info['MPvar']; 01514 $id = $mount_info['mount_pid']; 01515 } 01516 } 01517 01518 if ($id && $level<20) { 01519 01520 $nextLevelAcc = array(); 01521 01522 // Select and traverse current level pages: 01523 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 01524 'uid,pid,doktype,mount_pid,mount_pid_ol', 01525 'pages', 01526 'pid='.intval($id).' AND deleted=0 AND doktype!=255 AND doktype!=6' // 255 = Garbage bin, 6 = Backend User Section 01527 ); 01528 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 01529 01530 // Find mount point if any: 01531 $next_id = $row['uid']; 01532 $next_MP_array = $MP_array; 01533 $mount_info = $GLOBALS['TSFE']->sys_page->getMountPointInfo($next_id, $row); 01534 01535 // Overlay mode: 01536 if (is_array($mount_info) && $mount_info['overlay']) { 01537 $next_MP_array[] = $mount_info['MPvar']; 01538 $next_id = $mount_info['mount_pid']; 01539 } 01540 01541 if (!isset($this->MPmap[$next_id])) { 01542 01543 // Set mapping information for this level: 01544 $this->MPmap[$next_id] = $next_MP_array; 01545 01546 // Normal mode: 01547 if (is_array($mount_info) && !$mount_info['overlay']) { 01548 $next_MP_array[] = $mount_info['MPvar']; 01549 $next_id = $mount_info['mount_pid']; 01550 } 01551 01552 // Register recursive call 01553 // (have to do it this way since ALL of the current level should be registered BEFORE the sublevel at any time) 01554 $nextLevelAcc[] = array($next_id,$next_MP_array); 01555 } 01556 } 01557 01558 // Call recursively, if any: 01559 foreach($nextLevelAcc as $pSet) { 01560 $this->initMPmap_create($pSet[0],$pSet[1],$level+1); 01561 } 01562 } 01563 } 01564 } 01565 01566 01567 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tstemplate.php']) { 01568 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tstemplate.php']); 01569 } 01570 ?>