Documentation TYPO3 par Ameos |
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2004 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 ***************************************************************/ 00081 require_once (PATH_t3lib.'class.t3lib_tsparser.php'); 00082 require_once (PATH_t3lib.'class.t3lib_matchcondition.php'); 00083 00084 00085 00086 00087 00088 00089 00090 00091 00092 00093 00094 00095 00096 00097 00098 00107 class t3lib_TStemplate { 00108 00109 // Debugging, analysis: 00110 var $tt_track = 1; // If set, the global tt-timeobject is used to log the performance. 00111 var $forceTemplateParsing=0; // If set, the template is always rendered. Used from Admin Panel. 00112 00113 // Backend Analysis modules settings: 00114 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! 00115 var $matchAll=0; // If set, the match-class matches everything! Used for backend modules only. Never frontend! 00116 var $parseEditorCfgField=0; // If set, the Backend Editor Configuration TypoScript is also parsed (this is not needed for the frontend) 00117 var $backend_info = 0; 00118 var $getFileName_backPath=''; // Set from the backend - used to set an absolute path (PATH_site) so that relative resources are properly found with getFileName() 00119 00120 // Externally set breakpoints (used by Backend Modules) 00121 var $ext_constants_BRP=0; 00122 var $ext_config_BRP=0; 00123 var $ext_editorcfg_BRP=0; 00124 var $ext_regLinenumbers=FALSE; 00125 00126 // Constants: 00127 var $uplPath = 'uploads/tf/'; 00128 var $tempPath = 'typo3temp/'; 00129 var $menuclasses = 'gmenu,tmenu,imgmenu,jsmenu'; 00130 00131 // Set Internally: 00132 var $whereClause = ''; // This MUST be initialized by the init() function 00133 var $debug = 0; 00134 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. 00135 var $currentPageData = ''; // Contains "currentPageData" when rendered/fetched from cache. See getCurrentPageData() 00136 var $simulationHiddenOrTime=0; // See init(); Set if preview of some kind is enabled. 00137 00138 var $loaded = 0; // Set, if the TypoScript template structure is loaded and OK, see ->start() 00139 var $setup = Array( // Default TypoScript Setup code 00140 'styles.' => Array ( 00141 'insertContent' => 'CONTENT', 00142 'insertContent.' => Array ( 00143 'table' => 'tt_content', 00144 'select.' => Array ( 00145 'orderBy' => 'sorting', 00146 'where' => 'colPos=0', 00147 'languageField' => 'sys_language_uid' 00148 ) 00149 ) 00150 ), 00151 'config.' => Array ( 00152 'extTarget' => '_top', 00153 'stat' => 1, 00154 'stat_typeNumList' => '0,1' 00155 ) 00156 ); 00157 var $flatSetup = Array ( 00158 ); 00159 var $const = Array ( // Default TypoScript Constants code: 00160 '_clear' => '<img src="clear.gif" width="1" height="1" alt="" />', 00161 '_blackBorderWrap' => '<table border="0" bgcolor="black" cellspacing="0" cellpadding="1"><tr><td> | </td></tr></table>', 00162 '_tableWrap' => '<table border="0" cellspacing="0" cellpadding="0"> | </table>', 00163 '_tableWrap_DEBUG' => '<table border="1" cellspacing="0" cellpadding="0"> | </table>', 00164 '_stdFrameParams' => 'frameborder="no" marginheight="0" marginwidth="0" noresize="noresize"', 00165 '_stdFramesetParams' => 'border="0" framespacing="0" frameborder="no"' 00166 ); 00167 00168 00169 // For fetching TypoScript code from template hierarchy before parsing it. Each array contains code field values from template records/files: 00170 var $config = array(); // Setup field 00171 var $constants = array(); // Constant field 00172 var $editorcfg = array(); // Backend Editor Configuration field 00173 00174 var $hierarchyInfo = array(); // For Template Analyser in backend 00175 var $hierarchyInfoToRoot = array(); // For Template Analyser in backend (setup content only) 00176 var $nextLevel=0; // Next-level flag (see runThroughTemplates()) 00177 var $rootId; // The Page UID of the root page 00178 var $rootLine; // The rootline from current page to the root page 00179 var $absoluteRootLine; // Rootline all the way to the root. Set but runThroughTemplates 00180 var $outermostRootlineIndexWithTemplate=0; // A pointer to the last entry in the rootline where a template was found. 00181 var $rowSum; // Array of arrays with title/uid of templates in hierarchy 00182 var $resources=''; // Resources for the template hierarchy in a comma list 00183 var $sitetitle=''; // The current site title field. 00184 var $sections; // Tracking all conditions found during parsing of TypoScript. Used for the "all" key in currentPageData 00185 var $sectionsMatch; // Tracking all matching conditions found 00186 00187 // Backend: ts_analyzer 00188 var $clearList_const=array(); 00189 var $clearList_setup=array(); 00190 var $clearList_editorcfg=array(); 00191 var $parserErrors=array(); 00192 var $setup_constants = array(); 00193 00194 // Other: 00195 var $fileCache = Array(); // Used by getFileName for caching of references to file resources 00196 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. 00197 var $MPmap = ''; // Contains mapping of Page id numbers to MP variables. 00198 00199 00200 00201 00209 function init() { 00210 // $this->whereClause is used only to select templates from sys_template. 00211 // $GLOBALS['SIM_EXEC_TIME'] is used so that we're able to simulate a later time as a test... 00212 $this->whereClause='AND deleted=0 '; 00213 if (!$GLOBALS['TSFE']->showHiddenRecords) { 00214 $this->whereClause.='AND hidden=0 '; 00215 } 00216 if ($GLOBALS['TSFE']->showHiddenRecords || $GLOBALS['SIM_EXEC_TIME']!=$GLOBALS['EXEC_TIME']) { // Set the simulation flag, if simulation is detected! 00217 $this->simulationHiddenOrTime=1; 00218 } 00219 $this->whereClause.= 'AND (starttime<='.$GLOBALS['SIM_EXEC_TIME'].') AND (endtime=0 OR endtime>'.$GLOBALS['SIM_EXEC_TIME'].')'; 00220 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']) { 00221 $this->menuclasses='tmenu,jsmenu,gmenu'; 00222 } 00223 00224 // Sets the paths from where TypoScript resources are allowed to be used: 00225 $this->allowedPaths = Array ('media/','fileadmin/','uploads/','typo3temp/','t3lib/fonts/',TYPO3_mainDir.'ext/',TYPO3_mainDir.'sysext/','typo3conf/ext/'); 00226 if ($GLOBALS['TYPO3_CONF_VARS']['FE']['addAllowedPaths']) { 00227 $pathArr = t3lib_div::trimExplode(',',$GLOBALS['TYPO3_CONF_VARS']['FE']['addAllowedPaths'],1); 00228 while(list(,$p)=each($pathArr)) { 00229 // 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. 00230 $this->allowedPaths[] = $p; 00231 } 00232 } 00233 } 00234 00247 function getCurrentPageData() { 00248 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('content', 'cache_pagesection', 'page_id='.intval($GLOBALS['TSFE']->id).' AND mpvar_hash='.t3lib_div::md5int($GLOBALS['TSFE']->MP)); 00249 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00250 $this->currentPageData = unserialize($row['content']); 00251 } else { 00252 $this->currentPageData = 'none'; 00253 } 00254 return $this->currentPageData; 00255 } 00256 00264 function matching($cc) { 00265 if (is_array($cc['all'])) { 00266 reset($cc['all']); 00267 $matchObj = t3lib_div::makeInstance('t3lib_matchCondition'); 00268 $matchObj->altRootLine=$cc['rootLine']; 00269 while(list($key,$pre)=each($cc['all'])) { 00270 if ($matchObj->match($pre)) { 00271 $sectionsMatch[$key]=$pre; 00272 } 00273 } 00274 $cc['match']=$sectionsMatch; 00275 } 00276 return $cc; 00277 } 00278 00288 function start($theRootLine) { 00289 if (is_array($theRootLine)) { 00290 $setupData=''; 00291 $cc=Array(); 00292 $hash=''; 00293 $this->runThroughTemplates($theRootLine); 00294 00295 // Getting the currentPageData if not already found 00296 if (!$this->currentPageData) { 00297 $this->getCurrentPageData(); 00298 } 00299 00300 // This is about getting the hash string which is used to fetch the cached TypoScript template. 00301 // If there was some cached currentPageData that's good (it gives us the hash), 00302 // 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. 00303 if (is_array($this->currentPageData) && 00304 !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! 00305 ) { 00306 // If currentPageData was actually there, we match the result... 00307 $cc['all'] = $this->currentPageData['all']; 00308 $cc['rowSum'] = $this->currentPageData['rowSum']; 00309 $cc = $this->matching($cc); 00310 $hash = md5(serialize($cc)); 00311 } else { 00312 // 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 00313 $rowSumHash = md5('ROWSUM:'.serialize($this->rowSum)); 00314 $result = t3lib_pageSelect::getHash($rowSumHash, 0); 00315 if ($result) { 00316 $cc['all'] = unserialize($result); 00317 $cc['rowSum'] = $this->rowSum; 00318 $cc = $this->matching($cc); 00319 $hash = md5(serialize($cc)); 00320 } 00321 } 00322 00323 if ($hash) { 00324 // Get TypoScript setup array 00325 $setupData = t3lib_pageSelect::getHash($hash, 0); 00326 } 00327 00328 if ($hash && $setupData && !$this->forceTemplateParsing) { 00329 // If TypoScript setup structure was cached we unserialize it here: 00330 $this->setup = unserialize($setupData); 00331 } else { 00332 // Make configuration 00333 $this->generateConfig(); 00334 00335 // This stores the template hash thing 00336 $cc=Array(); 00337 $cc['all']=$this->sections; // All sections in the template at this point is found 00338 $cc['rowSum']=$this->rowSum; // The line of templates is collected 00339 $cc = $this->matching($cc); 00340 00341 $hash = md5(serialize($cc)); 00342 00343 // This stores the data. 00344 t3lib_pageSelect::storeHash($hash, serialize($this->setup), 'TS TEMPLATE'); 00345 00346 if ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('TS template size, serialized: '.strlen(serialize($this->setup)).' bytes'); 00347 00348 $rowSumHash = md5('ROWSUM:'.serialize($this->rowSum)); 00349 t3lib_pageSelect::storeHash($rowSumHash, serialize($cc['all']), 'TMPL CONDITIONS - ALL'); 00350 } 00351 // Add rootLine 00352 $cc['rootLine'] = $this->rootLine; 00353 // Make global and save. 00354 $GLOBALS['TSFE']->all=$cc; 00355 00356 if (!$this->simulationHiddenOrTime) { // Only save currentPageData, if we're not simulating by hidden/starttime/endtime 00357 $insertFields = array( 00358 'page_id' => intval($GLOBALS['TSFE']->id), 00359 'mpvar_hash' => t3lib_div::md5int($GLOBALS['TSFE']->MP), 00360 'content' => serialize($cc), 00361 'tstamp' => $GLOBALS['EXEC_TIME'] 00362 ); 00363 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pagesection', 'page_id='.intval($GLOBALS['TSFE']->id).' AND mpvar_hash='.t3lib_div::md5int($GLOBALS['TSFE']->MP)); 00364 $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_pagesection', $insertFields); 00365 } 00366 // If everything OK. 00367 if ($this->rootId && $this->rootLine && $this->setup) { 00368 $this->loaded = 1; 00369 } 00370 } 00371 } 00372 00373 00374 00375 00376 00377 00378 00379 00380 00381 00382 00383 00384 00385 00386 00387 /******************************************************************* 00388 * 00389 * Fetching TypoScript code text for the Template Hierarchy 00390 * 00391 *******************************************************************/ 00392 00403 function runThroughTemplates($theRootLine,$start_template_uid=0) { 00404 $this->constants = Array(); 00405 $this->config = Array(); 00406 $this->editorcfg = Array(); 00407 $this->rowSum = Array(); 00408 $this->hierarchyInfoToRoot = Array(); 00409 $this->absoluteRootLine=$theRootLine; // Is the TOTAL rootline 00410 00411 reset ($this->absoluteRootLine); 00412 $c=count($this->absoluteRootLine); 00413 for ($a=0;$a<$c;$a++) { 00414 if ($this->nextLevel) { // If some template loaded before has set a template-id for the next level, then load this template first! 00415 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'uid='.intval($this->nextLevel).' '.$this->whereClause); 00416 $this->nextLevel = 0; 00417 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00418 $this->processTemplate($row,'sys_'.$row['uid'],$this->absoluteRootLine[$a]['uid'],'sys_'.$row['uid']); 00419 $this->outermostRootlineIndexWithTemplate=$a; 00420 } 00421 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00422 } 00423 $addC=''; 00424 if ($a==($c-1) && $start_template_uid) { // If first loop AND there is set an alternative template uid, use that 00425 $addC=' AND uid='.intval($start_template_uid); 00426 } 00427 00428 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'pid='.intval($this->absoluteRootLine[$a]['uid']).$addC.' '.$this->whereClause,'','sorting',1); 00429 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00430 $this->processTemplate($row,'sys_'.$row['uid'],$this->absoluteRootLine[$a]['uid'],'sys_'.$row['uid']); 00431 $this->outermostRootlineIndexWithTemplate=$a; 00432 } 00433 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00434 $this->rootLine[] = $this->absoluteRootLine[$a]; 00435 } 00436 } 00437 00450 function processTemplate($row, $idList,$pid,$templateID='',$templateParent='') { 00451 // Adding basic template record information to rowSum array 00452 $this->rowSum[]=Array($row['uid'],$row['title'],$row['tstamp']); 00453 00454 // Processing "Clear"-flags 00455 if ($row['clear']) { 00456 $clConst = $row['clear']&1; 00457 $clConf = $row['clear']&2; 00458 if ($clConst) { 00459 $this->constants = Array(); 00460 $this->clearList_const=array(); 00461 } 00462 if ($clConf) { 00463 $this->config = Array(); 00464 $this->hierarchyInfoToRoot = Array(); 00465 $this->clearList_setup=array(); 00466 00467 $this->editorcfg = Array(); 00468 $this->clearList_editorcfg=array(); 00469 } 00470 } 00471 00472 // Include static records (static_template) or files (from extensions) (#1/2) 00473 if (!$row['includeStaticAfterBasedOn']) { // NORMAL inclusion, The EXACT same code is found below the basedOn inclusion!!! 00474 $this->includeStaticTypoScriptSources($idList,$templateID,$pid,$row); 00475 } 00476 00477 // Include "Based On" sys_templates: 00478 if (trim($row['basedOn'])) { // 'basedOn' is a list of templates to include 00479 // Manually you can put this value in the field and then the based_on ID will be taken from the $_GET var defined by '=....'. 00480 // 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! 00481 // 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. 00482 $basedOn_hackFeature = explode('=',$row['basedOn']); 00483 if ($basedOn_hackFeature[0]=='EXTERNAL_BASED_ON_TEMPLATE_ID' && $basedOn_hackFeature[1]) { 00484 $id = intval(t3lib_div::_GET($basedOn_hackFeature[1])); 00485 if ($id && !t3lib_div::inList($idList,'sys_'.$id)) { // if $id is not allready included ... 00486 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'uid='.$id.' '.$this->whereClause); 00487 if ($subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { // there was a template, then we fetch that 00488 $this->processTemplate($subrow,$idList.',sys_'.$id,$pid, 'sys_'.$id,$templateID); 00489 } 00490 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00491 } 00492 } else { // NORMAL OPERATION: 00493 $basedOnArr = t3lib_div::intExplode(',',$row['basedOn']); 00494 while(list(,$id)=each($basedOnArr)) { // traversing list 00495 if (!t3lib_div::inList($idList,'sys_'.$id)) { // if $id is not allready included ... 00496 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'uid='.intval($id).' '.$this->whereClause); 00497 if ($subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { // there was a template, then we fetch that 00498 $this->processTemplate($subrow,$idList.',sys_'.$id,$pid, 'sys_'.$id,$templateID); 00499 } 00500 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00501 } 00502 } 00503 } 00504 } 00505 00506 // Include static records (static_template) or files (from extensions) (#2/2) 00507 if ($row['includeStaticAfterBasedOn']) { 00508 $this->includeStaticTypoScriptSources($idList,$templateID,$pid,$row); 00509 } 00510 00511 // Creating hierarchy information; Used by backend analysis tools 00512 $this->hierarchyInfo[] = $this->hierarchyInfoToRoot[] = array( 00513 'root'=>trim($row['root']), 00514 'next'=>$row['nextLevel'], 00515 'clConst'=>$clConst, 00516 'clConf'=>$clConf, 00517 'templateID'=>$templateID, 00518 'templateParent'=>$templateParent, 00519 'title'=>$row['title'], 00520 'uid'=>$row['uid'], 00521 'pid'=>$row['pid'], 00522 'configLines' => substr_count($row['config'], chr(10))+1 00523 ); 00524 00525 // Adding the content of the fields constants (Constants), config (Setup) and editorcfg (Backend Editor Configuration) to the internal arrays. 00526 $this->constants[] = $row['constants']; 00527 $this->config[] = $row['config']; 00528 if ($this->parseEditorCfgField) $this->editorcfg[] = $row['editorcfg']; 00529 00530 // For backend analysis (Template Analyser) provide the order of added constants/config/editorcfg template IDs 00531 $this->clearList_const[]=$templateID; 00532 $this->clearList_setup[]=$templateID; 00533 if ($this->parseEditorCfgField) $this->clearList_editorcfg[]=$templateID; 00534 00535 // Add resources and sitetitle if found: 00536 if (trim($row['resources'])) { 00537 $this->resources = $row['resources'].','.$this->resources; 00538 } 00539 if (trim($row['sitetitle'])) { 00540 $this->sitetitle = $row['sitetitle']; 00541 } 00542 // If the template record is a Rootlevel record, set the flag and clear the template rootLine (so it starts over from this point) 00543 if (trim($row['root'])) { 00544 $this->rootId = $pid; 00545 $this->rootLine = Array(); 00546 } 00547 // If a template is set to be active on the next level set this internal value to point to this UID. (See runThroughTemplates()) 00548 if ($row['nextLevel']) { 00549 $this->nextLevel = $row['nextLevel']; 00550 } else { 00551 $this->nextLevel = 0; 00552 } 00553 } 00554 00565 function includeStaticTypoScriptSources($idList,$templateID,$pid,$row) { 00566 // Static Template Records (static_template): include_static is a list of static templates to include 00567 if (trim($row['include_static'])) { 00568 $include_staticArr = t3lib_div::intExplode(',',$row['include_static']); 00569 reset($include_staticArr); 00570 while(list(,$id)=each($include_staticArr)) { // traversing list 00571 if (!t3lib_div::inList($idList,'static_'.$id)) { // if $id is not allready included ... 00572 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'static_template', 'uid='.intval($id)); 00573 if ($subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { // there was a template, then we fetch that 00574 $subrow = $this->prependStaticExtra($subrow); 00575 $this->processTemplate($subrow,$idList.',static_'.$id,$pid,'static_'.$id,$templateID); 00576 } 00577 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00578 } 00579 } 00580 } 00581 00582 // Static Template Files (Text files from extensions): include_static_file is a list of static files to include (from extensions) 00583 if (trim($row['include_static_file'])) { 00584 $include_static_fileArr = t3lib_div::trimExplode(',',$row['include_static_file'],1); 00585 reset($include_static_fileArr); 00586 while(list(,$ISF_file)=each($include_static_fileArr)) { // traversing list 00587 $ISF_file = trim($ISF_file); 00588 if (substr($ISF_file,0,4)=='EXT:') { 00589 list($ISF_extKey,$ISF_localPath) = explode('/',substr($ISF_file,4),2); 00590 if (strcmp($ISF_extKey,'') && t3lib_extMgm::isLoaded($ISF_extKey) && strcmp($ISF_localPath,'')) { 00591 $ISF_localPath = ereg_replace('\/$','',$ISF_localPath).'/'; 00592 $ISF_filePath = t3lib_extMgm::extPath($ISF_extKey).$ISF_localPath; 00593 if (@is_dir($ISF_filePath)) { 00594 $mExtKey = str_replace('_','',$ISF_extKey.'/'.$ISF_localPath); 00595 $subrow=array( 00596 'constants'=> @is_file($ISF_filePath.'constants.txt') ?t3lib_div::getUrl($ISF_filePath.'constants.txt'):'', 00597 'config'=> @is_file($ISF_filePath.'setup.txt') ?t3lib_div::getUrl($ISF_filePath.'setup.txt'):'', 00598 'editorcfg'=> @is_file($ISF_filePath.'editorcfg.txt') ?t3lib_div::getUrl($ISF_filePath.'editorcfg.txt'):'', 00599 'include_static'=> @is_file($ISF_filePath.'include_static.txt')?implode(',',array_unique(t3lib_div::intExplode(',',t3lib_div::getUrl($ISF_filePath.'include_static.txt')))):'', 00600 'title' => $ISF_file, 00601 'uid' => $mExtKey 00602 ); 00603 $subrow = $this->prependStaticExtra($subrow); 00604 00605 $this->processTemplate($subrow,$idList.',ext_'.$mExtKey,$pid, 'ext_'.$mExtKey,$templateID); 00606 } 00607 } 00608 } 00609 } 00610 } 00611 00612 $this->addExtensionStatics($idList,$templateID,$pid,$row); 00613 } 00614 00626 function addExtensionStatics($idList,$templateID,$pid,$row) { 00627 global $TYPO3_LOADED_EXT; 00628 00629 if ($row['static_file_mode']==1 || ($row['static_file_mode']==0 && substr($templateID,0,4)=='sys_' && $row['root'])) { 00630 reset($TYPO3_LOADED_EXT); 00631 while(list($extKey,$files)=each($TYPO3_LOADED_EXT)) { 00632 if (is_array($files) && ($files['ext_typoscript_constants.txt'] || $files['ext_typoscript_setup.txt'] || $files['ext_typoscript_editorcfg.txt'])) { 00633 $mExtKey = str_replace('_','',$extKey); 00634 $subrow=array( 00635 'constants'=> $files['ext_typoscript_constants.txt']?t3lib_div::getUrl($files['ext_typoscript_constants.txt']):'', 00636 'config'=> $files['ext_typoscript_setup.txt']?t3lib_div::getUrl($files['ext_typoscript_setup.txt']):'', 00637 'editorcfg'=> $files['ext_typoscript_editorcfg.txt']?t3lib_div::getUrl($files['ext_typoscript_editorcfg.txt']):'', 00638 'title' => $extKey, 00639 'uid' => $mExtKey 00640 ); 00641 $subrow = $this->prependStaticExtra($subrow); 00642 00643 $this->processTemplate($subrow,$idList.',ext_'.$mExtKey,$pid, 'ext_'.$mExtKey,$templateID); 00644 } 00645 } 00646 } 00647 } 00648 00659 function prependStaticExtra($subrow) { 00660 $subrow['config'].=$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_setup.'][$subrow['uid']]; 00661 $subrow['editorcfg'].=$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_editorcfg.'][$subrow['uid']]; 00662 $subrow['constants'].=$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_constants.'][$subrow['uid']]; 00663 return $subrow; 00664 } 00665 00666 00667 00668 00669 00670 00671 00672 00673 00674 00675 00676 00677 00678 00679 00680 00681 00682 /******************************************************************* 00683 * 00684 * Parsing TypoScript code text from Template Records into PHP array 00685 * 00686 *******************************************************************/ 00687 00695 function generateConfig() { 00696 // Add default TS for all three code types: 00697 array_unshift($this->constants,''.$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_constants']); // Adding default TS/constants 00698 array_unshift($this->config,''.$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_setup']); // Adding default TS/setup 00699 array_unshift($this->editorcfg,''.$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_editorcfg']); // Adding default TS/editorcfg 00700 00701 // Parse the TypoScript code text for include-instructions! 00702 $this->procesIncludes(); 00703 00704 // These vars are also set lateron... 00705 $this->setup['resources']= $this->resources; 00706 $this->setup['sitetitle']= $this->sitetitle; 00707 00708 00709 00710 // **************************** 00711 // Parse TypoScript Constants 00712 // **************************** 00713 00714 // Initialize parser and match-condition classes: 00715 $constants = t3lib_div::makeInstance('t3lib_TSparser'); 00716 $constants->breakPointLN=intval($this->ext_constants_BRP); 00717 $constants->setup = $this->const; 00718 $constants->setup = $this->mergeConstantsFromPageTSconfig($constants->setup); 00719 $matchObj = t3lib_div::makeInstance('t3lib_matchCondition'); 00720 $matchObj->matchAlternative = $this->matchAlternative; 00721 $matchObj->matchAll = $this->matchAll; // Matches ALL conditions in TypoScript 00722 00723 // Traverse constants text fields and parse them 00724 foreach($this->constants as $str) { 00725 $constants->parse($str,$matchObj); 00726 } 00727 00728 // Read out parse errors if any 00729 $this->parserErrors['constants']=$constants->errors; 00730 00731 // 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) 00732 $this->flatSetup = Array(); 00733 $this->flattenSetup($constants->setup,'',''); 00734 00735 00736 00737 // *********************************************** 00738 // Parse TypoScript Setup (here called "config") 00739 // *********************************************** 00740 // Initialize parser and match-condition classes: 00741 $config = t3lib_div::makeInstance('t3lib_TSparser'); 00742 $config->breakPointLN = intval($this->ext_config_BRP); 00743 $config->regLinenumbers = $this->ext_regLinenumbers; 00744 $config->setup = $this->setup; 00745 00746 // Transfer information about conditions found in "Constants" and which of them returned true. 00747 $config->sections = $constants->sections; 00748 $config->sectionsMatch = $constants->sectionsMatch; 00749 00750 // Traverse setup text fields and concatenate them into one, single string separated by a [GLOBAL] condition 00751 $all=''; 00752 foreach($this->config as $str) { 00753 $all.="\n[GLOBAL]\n".$str; 00754 } 00755 00756 // Substitute constants in the Setup code: 00757 if ($this->tt_track) $GLOBALS['TT']->push('Substitute Constants ('.count($this->flatSetup).')'); 00758 $all = $this->substituteConstants($all); 00759 if ($this->tt_track) $GLOBALS['TT']->pull(); 00760 00761 // Searching for possible unsubstituted constants left (only for information) 00762 if (strstr($all,'{$')) { 00763 $findConst = explode('{$',$all); 00764 $theConstList=Array(); 00765 next($findConst); 00766 while(list(,$constVal)=each($findConst)) { 00767 $constLen=t3lib_div::intInRange(strcspn($constVal,'}'),0,50); 00768 $theConstList[]='{$'.substr($constVal,0,$constLen+1); 00769 } 00770 if ($this->tt_track) $GLOBALS['TT']->setTSlogMessage(implode(',',$theConstList).': Constants may remain un-substituted!!',2); 00771 } 00772 00773 // Logging the textual size of the TypoScript Setup field text with all constants substituted: 00774 if ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('TypoScript template size as textfile: '.strlen($all).' bytes'); 00775 00776 // Finally parse the Setup field TypoScript code (where constants are now substituted) 00777 $config->parse($all,$matchObj); 00778 00779 // Read out parse errors if any 00780 $this->parserErrors['config']=$config->errors; 00781 00782 // Transfer the TypoScript array from the parser object to the internal $this->setup array: 00783 $this->setup = $config->setup; 00784 if ($this->backend_info) { 00785 $this->setup_constants = $constants->setup; // Used for backend purposes only 00786 } 00787 00788 00789 00790 00791 // ************************************************** 00792 // Parse Backend Editor Configuration (backend only) 00793 // ************************************************** 00794 if ($this->parseEditorCfgField) { 00795 $editorcfg = t3lib_div::makeInstance('t3lib_TSparser'); 00796 $editorcfg->breakPointLN=intval($this->ext_editorcfg_BRP); 00797 $editorcfg->setup = array(); // Empty as a start... 00798 00799 $all = implode("\n[GLOBAL]\n",$this->editorcfg); 00800 00801 // substitute constants in config 00802 $all = $this->substituteConstants($all); 00803 00804 // parse Config 00805 $matchObj->matchAll=1; // This should make sure that conditions are disabled. For now they are NOT active for the backend. 00806 $editorcfg->parse($all,$matchObj); 00807 $this->parserErrors['editorcfg']=$editorcfg->errors; 00808 $this->setup_editorcfg = $editorcfg->setup; 00809 } 00810 00811 00812 00813 00814 00815 // **************************************************************** 00816 // Final processing of the $this->setup TypoScript Template array 00817 // Basically: This is unsetting/setting of certain reserved keys. 00818 // **************************************************************** 00819 00820 // 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! 00821 unset($this->setup['resources']); 00822 unset($this->setup['resources.']); 00823 $this->setup['resources']= implode(',',t3lib_div::trimExplode(',',$this->resources,1)); 00824 00825 unset($this->setup['sitetitle']); 00826 unset($this->setup['sitetitle.']); 00827 $this->setup['sitetitle']= $this->sitetitle; 00828 00829 // Unsetting some vars... 00830 unset($this->setup['types.']); 00831 unset($this->setup['types']); 00832 if (is_array($this->setup)) { 00833 reset ($this->setup); 00834 while(list($theKey,)=each($this->setup)) { 00835 if ($this->setup[$theKey]=='PAGE') { 00836 $tN = $this->setup[$theKey.'.']['typeNum']; 00837 if (isset($tN)) { 00838 $this->setup['types.'][$tN] = $theKey; 00839 } 00840 } 00841 } 00842 } 00843 unset($this->setup['styles.']); 00844 unset($this->setup['temp.']); 00845 unset($constants); 00846 00847 // Storing the conditions found/matched information: 00848 $this->sections = $config->sections; 00849 $this->sectionsMatch = $config->sectionsMatch; 00850 } 00851 00859 function procesIncludes() { 00860 reset($this->constants); 00861 while(list($k)=each($this->constants)) { 00862 $this->constants[$k]=t3lib_TSparser::checkIncludeLines($this->constants[$k]); 00863 } 00864 00865 reset($this->config); 00866 while(list($k)=each($this->config)) { 00867 $this->config[$k]=t3lib_TSparser::checkIncludeLines($this->config[$k]); 00868 } 00869 00870 reset($this->editorcfg); 00871 while(list($k)=each($this->editorcfg)) { 00872 $this->editorcfg[$k]=t3lib_TSparser::checkIncludeLines($this->editorcfg[$k]); 00873 } 00874 } 00875 00883 function mergeConstantsFromPageTSconfig($constArray) { 00884 $TSdataArray = array(); 00885 $TSdataArray[]=$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig']; // Setting default configuration: 00886 00887 for ($a=0;$a<=$this->outermostRootlineIndexWithTemplate;$a++) { 00888 $TSdataArray[]=$this->absoluteRootLine[$a]['TSconfig']; 00889 } 00890 // Parsing the user TS (or getting from cache) 00891 $TSdataArray = t3lib_TSparser::checkIncludeLines_array($TSdataArray); 00892 $userTS = implode(chr(10).'[GLOBAL]'.chr(10),$TSdataArray); 00893 00894 $parseObj = t3lib_div::makeInstance('t3lib_TSparser'); 00895 $parseObj->parse($userTS); 00896 00897 if (is_array($parseObj->setup['TSFE.']['constants.'])) { 00898 $constArray = t3lib_div::array_merge_recursive_overrule($constArray,$parseObj->setup['TSFE.']['constants.']); 00899 } 00900 return $constArray; 00901 } 00902 00912 function flattenSetup($setupArray, $prefix, $resourceFlag) { 00913 if (is_array($setupArray)) { 00914 reset($setupArray); 00915 while(list($key,$val)=each($setupArray)) { 00916 if ($prefix || substr($key,0,16)!='TSConstantEditor') { // We don't want 'TSConstantEditor' in the flattend setup on the first level (190201) 00917 if (is_array($val)) { 00918 $this->flattenSetup($val,$prefix.$key, ($key=='file.')); 00919 } elseif ($resourceFlag) { 00920 $this->flatSetup[$prefix.$key] = $this->getFileName($val); 00921 } else { 00922 $this->flatSetup[$prefix.$key] = $val; 00923 } 00924 } 00925 } 00926 } 00927 } 00928 00936 function substituteConstants($all) { 00937 if ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('Constants to substitute: '.count($this->flatSetup)); 00938 reset($this->flatSetup); 00939 while (list($const,$val)=each($this->flatSetup)) { 00940 if (!is_array($val)) { 00941 $all = str_replace('{$'.$const.'}',$val,$all); 00942 } 00943 } 00944 return $all; 00945 } 00946 00947 00948 00949 00950 00951 00952 00953 00954 00955 00956 00957 /******************************************************************* 00958 * 00959 * Various API functions, used from elsewhere in the frontend classes 00960 * 00961 *******************************************************************/ 00962 00974 function splitConfArray($conf,$splitCount) { 00975 00976 // Initialize variables: 00977 $splitCount = intval($splitCount); 00978 $conf2 = Array(); 00979 00980 if ($splitCount && is_array($conf)) { 00981 00982 // Initialize output to carry at least the keys: 00983 for ($aKey=0;$aKey<$splitCount;$aKey++) { 00984 $conf2[$aKey] = array(); 00985 } 00986 00987 // Recursive processing of array keys: 00988 foreach($conf as $cKey => $val) { 00989 if (is_array($val)) { 00990 $tempConf = $this->splitConfArray($val,$splitCount); 00991 foreach($tempConf as $aKey => $val) { 00992 $conf2[$aKey][$cKey] = $val; 00993 } 00994 } 00995 } 00996 00997 // Splitting of all values on this level of the TypoScript object tree: 00998 foreach($conf as $cKey => $val) { 00999 if (!is_array($val)) { 01000 if (!strstr($val,'|*|') && !strstr($val,'||')) { 01001 for ($aKey=0;$aKey<$splitCount;$aKey++) { 01002 $conf2[$aKey][$cKey] = $val; 01003 } 01004 } else { 01005 $main = explode ('|*|',$val); 01006 $mainCount = count($main); 01007 01008 $lastC = 0; 01009 $middleC = 0; 01010 $firstC = 0; 01011 01012 if ($main[0]) { 01013 $first = explode('||',$main[0]); 01014 $firstC = count($first); 01015 } 01016 if ($main[1]) { 01017 $middle = explode('||',$main[1]); 01018 $middleC = count($middle); 01019 } 01020 if ($main[2]) { 01021 $last = explode('||',$main[2]); 01022 $lastC = count($last); 01023 $value = $last[0]; 01024 } 01025 01026 for ($aKey=0;$aKey<$splitCount;$aKey++) { 01027 if ($firstC && isset($first[$aKey])) { 01028 $value = $first[$aKey]; 01029 } elseif ($middleC) { 01030 $value = $middle[($aKey-$firstC)%$middleC]; 01031 } 01032 if ($lastC && $lastC>=($splitCount-$aKey)) { 01033 $value = $last[$lastC-($splitCount-$aKey)]; 01034 } 01035 $conf2[$aKey][$cKey] = trim($value); 01036 } 01037 } 01038 } 01039 } 01040 } 01041 return $conf2; 01042 } 01043 01051 function getFileName($fileFromSetup) { 01052 $file = trim($fileFromSetup); 01053 if (!$file) return; 01054 // cache 01055 $hash = md5($file); 01056 if (isset($this->fileCache[$hash])) { 01057 return $this->fileCache[$hash]; 01058 } 01059 01060 if (!strcmp(substr($file,0,4),'EXT:')) { 01061 $newFile=''; 01062 list($extKey,$script)=explode('/',substr($file,4),2); 01063 if ($extKey && t3lib_extMgm::isLoaded($extKey)) { 01064 $extPath=t3lib_extMgm::extPath($extKey); 01065 $newFile=substr($extPath,strlen(PATH_site)).$script; 01066 } 01067 if (!@is_file(PATH_site.$newFile)) { 01068 if ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('Extension media file "'.$newFile.'" was not found!',3); 01069 return; 01070 } else $file=$newFile; 01071 } 01072 01073 // find 01074 if (strstr($file,'/')) { // here it is manual media 01075 if (@is_file($this->getFileName_backPath.$file)) { 01076 $outFile = $file; 01077 $fileInfo = t3lib_div::split_fileref($outFile); 01078 reset($this->allowedPaths); 01079 $OK=0; 01080 while(list(,$val)=each($this->allowedPaths)) { 01081 if (substr($fileInfo['path'],0,strlen($val))==$val){$OK=1; break;} 01082 } 01083 if ($OK) { 01084 $this->fileCache[$hash]=$outFile; 01085 return $outFile; 01086 } elseif ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('"'.$file.'" was not located in the allowed paths: ('.implode(',',$this->allowedPaths).')',3); 01087 } elseif ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('"'.$this->getFileName_backPath.$file.'" is not a file (non-uploads/.. resource, did not exist).',3); 01088 } else { // Here it is uploaded media: 01089 $outFile = $this->extractFromResources($this->setup['resources'],$file); 01090 if ($outFile) { 01091 if (@is_file($this->uplPath.$outFile)) { 01092 $this->fileCache[$hash] = $this->uplPath.$outFile; 01093 return $this->uplPath.$outFile; 01094 } elseif ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('"'.$this->uplPath.$outFile.'" is not a file (did not exist).',3); 01095 } elseif ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('"'.$file.'" is not a file (uploads/.. resource).',3); 01096 } 01097 } 01098 01108 function extractFromResources($res,$file) { 01109 if (t3lib_div::inList($res,$file)) { 01110 $outFile = $file; 01111 } elseif (strstr($file,'*')) { 01112 $fileparts=explode('*',$file); 01113 $c=count($fileparts); 01114 $files = explode(',',$res); 01115 while(list(,$val)=each($files)) { 01116 $test = trim($val); 01117 if (ereg('^'.quotemeta($fileparts[0]).'.*'.quotemeta($fileparts[$c-1]).'$', $test)) { 01118 $outFile = $test; 01119 break; 01120 } 01121 } 01122 } 01123 return $outFile; 01124 } 01125 01136 function checkFile($name,$menuArr) { 01137 reset ($menuArr); 01138 while (list($aKey,)=each($menuArr)) { 01139 $menuArr[$aKey][$name] = $this->getFileName($menuArr[$aKey][$name]); 01140 } 01141 return $menuArr; 01142 } 01143 01153 function printTitle($title,$no_title=0,$titleFirst=0) { 01154 $st = trim($this->setup['sitetitle']) ? $this->setup['sitetitle']:''; 01155 $title = $no_title ? '' : $title; 01156 if ($titleFirst) { 01157 $temp=$st; 01158 $st=$title; 01159 $title=$temp; 01160 } 01161 if ($title && $st) { 01162 return $st.': '.$title; 01163 } else { 01164 return $st.$title; 01165 } 01166 } 01167 01176 function fileContent($fName) { 01177 $incFile = $this->getFileName($fName); 01178 if ($incFile && $fd=fopen($incFile,'rb')) { 01179 $content = ''; 01180 while (!feof($fd)) { 01181 $content.=fread($fd, 5000); 01182 } 01183 fclose( $fd ); 01184 return $content; 01185 } 01186 } 01187 01196 function wrap($content,$wrap) { 01197 if ($wrap) { 01198 $wrapArr = explode('|', $wrap); 01199 return trim($wrapArr[0]).$content.trim($wrapArr[1]); 01200 } else return $content; 01201 } 01202 01210 function removeQueryString($url) { 01211 if (substr($url,-1)=='?') { 01212 return substr($url,0,-1); 01213 } else { 01214 return $url; 01215 } 01216 } 01217 01227 function sortedKeyList($setupArr, $acceptOnlyProperties=FALSE) { 01228 $keyArr = Array(); 01229 01230 reset($setupArr); 01231 while(list($key,)=each($setupArr)) { 01232 $ikey = intval($key); 01233 if (!strcmp($ikey,$key) || $acceptOnlyProperties) { 01234 $keyArr[] = $ikey; 01235 } 01236 } 01237 01238 $keyArr = array_unique($keyArr); 01239 sort($keyArr); 01240 return $keyArr; 01241 } 01242 01243 01244 01245 01246 01247 01248 01249 01250 01251 01252 /******************************************************************* 01253 * 01254 * Functions for creating links 01255 * 01256 *******************************************************************/ 01257 01274 function linkData($page,$oTarget,$no_cache,$script,$overrideArray='',$addParams='',$typeOverride='') { 01275 global $TYPO3_CONF_VARS; 01276 01277 $LD = Array(); 01278 01279 // Overriding some fields in the page record and still preserves the values by adding them as parameters. Little strange function. 01280 if (is_array($overrideArray)) { 01281 foreach($overrideArray as $theKey => $theNewVal) { 01282 $addParams.= '&real_'.$theKey.'='.rawurlencode($page[$theKey]); 01283 $page[$theKey] = $theNewVal; 01284 } 01285 } 01286 01287 // Adding Mount Points, "&MP=", parameter for the current page if any is set: 01288 if (!strstr($addParams,'&MP=')) { 01289 if (trim($GLOBALS['TSFE']->MP_defaults[$page['uid']])) { // Looking for hardcoded defaults: 01290 $addParams.= '&MP='.rawurlencode(trim($GLOBALS['TSFE']->MP_defaults[$page['uid']])); 01291 } elseif ($GLOBALS['TSFE']->config['config']['MP_mapRootPoints']) { // Else look in automatically created map: 01292 $m = $this->getFromMPmap($page['uid']); 01293 if ($m) { 01294 $addParams.= '&MP='.rawurlencode($m); 01295 } 01296 } 01297 } 01298 01299 // Setting ID/alias: 01300 if (!$script) {$script = $GLOBALS['TSFE']->config['mainScript'];} 01301 if ($page['alias']) { 01302 $LD['url'] = $script.'?id='.rawurlencode($page['alias']); 01303 } else { 01304 $LD['url'] = $script.'?id='.$page['uid']; 01305 } 01306 // Setting target 01307 $LD['target'] = trim($page['target']) ? trim($page['target']) : $oTarget; 01308 01309 // typeNum 01310 $typeNum = $this->setup[$LD['target'].'.']['typeNum']; 01311 if (!$typeOverride && intval($GLOBALS['TSFE']->config['config']['forceTypeValue'])) { 01312 $typeOverride = intval($GLOBALS['TSFE']->config['config']['forceTypeValue']); 01313 } 01314 if (strcmp($typeOverride,'')) { $typeNum = $typeOverride; } // Override... 01315 if ($typeNum) { 01316 $LD['type'] = '&type='.intval($typeNum); 01317 } else { 01318 $LD['type'] = ''; 01319 } 01320 $LD['orig_type'] = $LD['type']; // Preserving the type number. Will not be cleared if simulateStaticDocuments. 01321 01322 // noCache 01323 $LD['no_cache'] = (trim($page['no_cache']) || $no_cache) ? '&no_cache=1' : ''; 01324 01325 // linkVars 01326 $LD['linkVars'] = $GLOBALS['TSFE']->linkVars.$addParams; 01327 01328 // If simulateStaticDocuments is enabled: 01329 if ($GLOBALS['TSFE']->config['config']['simulateStaticDocuments']) { 01330 $LD['type'] = ''; 01331 $LD['url'] = ''; 01332 01333 // MD5/base64 method limitation: 01334 $remainLinkVars=''; 01335 $flag_simulateStaticDocuments_pEnc = t3lib_div::inList('md5,base64',$GLOBALS['TSFE']->config['config']['simulateStaticDocuments_pEnc']) && !$LD['no_cache']; 01336 if ($flag_simulateStaticDocuments_pEnc) { 01337 list($LD['linkVars'], $remainLinkVars) = $GLOBALS['TSFE']->simulateStaticDocuments_pEnc_onlyP_proc($LD['linkVars']); 01338 } 01339 01340 $LD['url'].=$GLOBALS['TSFE']->makeSimulFileName( 01341 $page['title'], 01342 $page['alias'] ? $page['alias'] : $page['uid'], 01343 intval($typeNum), 01344 $LD['linkVars'], 01345 $LD['no_cache']?1:0 01346 ); 01347 01348 if ($flag_simulateStaticDocuments_pEnc) { 01349 $LD['linkVars']=$remainLinkVars; 01350 } 01351 if ($GLOBALS['TSFE']->config['config']['simulateStaticDocuments']=='PATH_INFO') { 01352 $LD['url'] = str_replace('.','/',$LD['url']); 01353 $LD['url'] = 'index.php/'.$LD['url'].'/?'; 01354 } else { 01355 $LD['url'].= '.html?'; 01356 } 01357 } 01358 01359 // Add absRefPrefix if exists. 01360 $LD['url'] = $GLOBALS['TSFE']->absRefPrefix.$LD['url']; 01361 01362 // 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. 01363 $LD['sectionIndex'] = $page['sectionIndex_uid'] ? '#'.$page['sectionIndex_uid'] : ''; 01364 01365 // Compile the normal total url 01366 $LD['totalURL']= $this->removeQueryString($LD['url'].$LD['type'].$LD['no_cache'].$LD['linkVars'].$GLOBALS['TSFE']->getMethodUrlIdToken).$LD['sectionIndex']; 01367 01368 // Call post processing function for link rendering: 01369 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tstemplate.php']['linkData-PostProc'])) { 01370 $_params = array( 01371 'LD' => &$LD, 01372 'args' => array('page'=>$page, 'oTarget'=>$oTarget, 'no_cache'=>$no_cache, 'script'=>$script, 'overrideArray'=>$overrideArray, 'addParams'=>$addParams, 'typeOverride'=>$typeOverride), 01373 'typeNum' => $typeNum 01374 ); 01375 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tstemplate.php']['linkData-PostProc'] as $_funcRef) { 01376 t3lib_div::callUserFunction($_funcRef,$_params,$this); 01377 } 01378 } 01379 01380 // Return the LD-array 01381 return $LD; 01382 } 01383 01393 function getFromMPmap($pageId=0) { 01394 01395 // Create map if not found already: 01396 if (!is_array($this->MPmap)) { 01397 $this->MPmap = array(); 01398 01399 $rootPoints = t3lib_div::trimExplode(',', strtolower($GLOBALS['TSFE']->config['config']['MP_mapRootPoints']),1); 01400 foreach($rootPoints as $p) { // Traverse rootpoints: 01401 if ($p == 'root') { 01402 $p = $this->rootLine[0]['uid']; 01403 $initMParray = array(); 01404 if ($this->rootLine[0]['_MOUNT_OL'] && $this->rootLine[0]['_MP_PARAM']) { 01405 $initMParray[] = $this->rootLine[0]['_MP_PARAM']; 01406 } 01407 } 01408 $this->initMPmap_create($p,$initMParray); 01409 } 01410 } 01411 01412 // Finding MP var for Page ID: 01413 if ($pageId) { 01414 if (is_array($this->MPmap[$pageId]) && count($this->MPmap[$pageId])) { 01415 return implode(',',$this->MPmap[$pageId]); 01416 } 01417 } 01418 } 01419 01429 function initMPmap_create($id,$MP_array=array(),$level=0) { 01430 01431 $id = intval($id); 01432 if($id<=0) return; 01433 01434 // First level, check id 01435 if (!$level) { 01436 01437 // Find mount point if any: 01438 $mount_info = $GLOBALS['TSFE']->sys_page->getMountPointInfo($id); 01439 01440 // Overlay mode: 01441 if (is_array($mount_info) && $mount_info['overlay']) { 01442 $MP_array[] = $mount_info['MPvar']; 01443 $id = $mount_info['mount_pid']; 01444 } 01445 01446 // Set mapping information for this level: 01447 $this->MPmap[$id] = $MP_array; 01448 01449 // Normal mode: 01450 if (is_array($mount_info) && !$mount_info['overlay']) { 01451 $MP_array[] = $mount_info['MPvar']; 01452 $id = $mount_info['mount_pid']; 01453 } 01454 } 01455 01456 if ($id && $level<20) { 01457 01458 $nextLevelAcc = array(); 01459 01460 // Select and traverse current level pages: 01461 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 01462 'uid,pid,doktype,mount_pid,mount_pid_ol', 01463 'pages', 01464 'pid='.intval($id).' AND deleted=0 AND doktype!=255 AND doktype!=6' // 255 = Garbage bin, 6 = Backend User Section 01465 ); 01466 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 01467 01468 // Find mount point if any: 01469 $next_id = $row['uid']; 01470 $next_MP_array = $MP_array; 01471 $mount_info = $GLOBALS['TSFE']->sys_page->getMountPointInfo($next_id, $row); 01472 01473 // Overlay mode: 01474 if (is_array($mount_info) && $mount_info['overlay']) { 01475 $next_MP_array[] = $mount_info['MPvar']; 01476 $next_id = $mount_info['mount_pid']; 01477 } 01478 01479 if (!isset($this->MPmap[$next_id])) { 01480 01481 // Set mapping information for this level: 01482 $this->MPmap[$next_id] = $next_MP_array; 01483 01484 // Normal mode: 01485 if (is_array($mount_info) && !$mount_info['overlay']) { 01486 $next_MP_array[] = $mount_info['MPvar']; 01487 $next_id = $mount_info['mount_pid']; 01488 } 01489 01490 // Register recursive call 01491 // (have to do it this way since ALL of the current level should be registered BEFORE the sublevel at any time) 01492 $nextLevelAcc[] = array($next_id,$next_MP_array); 01493 } 01494 } 01495 01496 // Call recursively, if any: 01497 foreach($nextLevelAcc as $pSet) { 01498 $this->initMPmap_create($pSet[0],$pSet[1],$level+1); 01499 } 01500 } 01501 } 01502 } 01503 01504 01505 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tstemplate.php']) { 01506 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tstemplate.php']); 01507 } 01508 ?>