[ Index ]
 

Code source de Typo3 4.1.3

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/t3lib/ -> class.t3lib_tstemplate.php (source)

   1  <?php
   2  /***************************************************************
   3  *  Copyright notice
   4  *
   5  *  (c) 1999-2007 Kasper Skaarhoj (kasperYYYY@typo3.com)
   6  *  All rights reserved
   7  *
   8  *  This script is part of the TYPO3 project. The TYPO3 project is
   9  *  free software; you can redistribute it and/or modify
  10  *  it under the terms of the GNU General Public License as published by
  11  *  the Free Software Foundation; either version 2 of the License, or
  12  *  (at your option) any later version.
  13  *
  14  *  The GNU General Public License can be found at
  15  *  http://www.gnu.org/copyleft/gpl.html.
  16  *  A copy is found in the textfile GPL.txt and important notices to the license
  17  *  from the author is found in LICENSE.txt distributed with these scripts.
  18  *
  19  *
  20  *  This script is distributed in the hope that it will be useful,
  21  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23  *  GNU General Public License for more details.
  24  *
  25  *  This copyright notice MUST APPEAR in all copies of the script!
  26  ***************************************************************/
  27  /**
  28   * Class with template object that is responsible for generating the template
  29   *
  30   * $Id: class.t3lib_tstemplate.php 2001 2007-02-06 07:45:40Z mundaun $
  31   * Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
  32   *
  33   * @author    Kasper Skaarhoj <kasperYYYY@typo3.com>
  34   */
  35  /**
  36   * [CLASS/FUNCTION INDEX of SCRIPT]
  37   *
  38   *
  39   *
  40   *  109: class t3lib_TStemplate
  41   *  211:     function init()
  42   *  249:     function getCurrentPageData()
  43   *  266:     function matching($cc)
  44   *  290:     function start($theRootLine)
  45   *
  46   *              SECTION: Fetching TypoScript code text for the Template Hierarchy
  47   *  406:     function runThroughTemplates($theRootLine,$start_template_uid=0)
  48   *  459:     function processTemplate($row, $idList,$pid,$templateID='',$templateParent='')
  49   *  580:     function includeStaticTypoScriptSources($idList,$templateID,$pid,$row)
  50   *  642:     function addExtensionStatics($idList,$templateID,$pid,$row)
  51   *  675:     function prependStaticExtra($subrow)
  52   *  688:     function versionOL(&$row)
  53   *
  54   *              SECTION: Parsing TypoScript code text from Template Records into PHP array
  55   *  725:     function generateConfig()
  56   *  891:     function procesIncludes()
  57   *  915:     function mergeConstantsFromPageTSconfig($constArray)
  58   *  944:     function flattenSetup($setupArray, $prefix, $resourceFlag)
  59   *  968:     function substituteConstants($all)
  60   *  991:     function substituteConstantsCallBack($matches)
  61   *
  62   *              SECTION: Various API functions, used from elsewhere in the frontend classes
  63   * 1022:     function splitConfArray($conf,$splitCount)
  64   * 1099:     function getFileName($fileFromSetup)
  65   * 1156:     function extractFromResources($res,$file)
  66   * 1184:     function checkFile($name,$menuArr)
  67   * 1201:     function printTitle($title,$no_title=0,$titleFirst=0)
  68   * 1224:     function fileContent($fName)
  69   * 1244:     function wrap($content,$wrap)
  70   * 1258:     function removeQueryString($url)
  71   * 1275:     function sortedKeyList($setupArr, $acceptOnlyProperties=FALSE)
  72   *
  73   *              SECTION: Functions for creating links
  74   * 1322:     function linkData($page,$oTarget,$no_cache,$script,$overrideArray='',$addParams='',$typeOverride='')
  75   * 1449:     function getFromMPmap($pageId=0)
  76   * 1485:     function initMPmap_create($id,$MP_array=array(),$level=0)
  77   *
  78   * TOTAL FUNCTIONS: 28
  79   * (This index is automatically created/updated by the extension "extdeveval")
  80   *
  81   */
  82  
  83  require_once (PATH_t3lib.'class.t3lib_tsparser.php');
  84  require_once (PATH_t3lib.'class.t3lib_matchcondition.php');
  85  
  86  
  87  
  88  
  89  
  90  
  91  
  92  
  93  
  94  
  95  
  96  
  97  
  98  
  99  
 100  
 101  /**
 102   * Template object that is responsible for generating the TypoScript template based on template records.
 103   *
 104   * @author    Kasper Skaarhoj <kasperYYYY@typo3.com>
 105   * @package TYPO3
 106   * @subpackage t3lib
 107   * @see    t3lib_tsparser.php, t3lib_matchcondition.php
 108   */
 109  class t3lib_TStemplate    {
 110  
 111          // Debugging, analysis:
 112      var $tt_track = 1;                    // If set, the global tt-timeobject is used to log the performance.
 113      var $forceTemplateParsing=0;        // If set, the template is always rendered. Used from Admin Panel.
 114  
 115          // Backend Analysis modules settings:
 116      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!
 117      var $matchAll=0;                    // If set, the match-class matches everything! Used for backend modules only. Never frontend!
 118      var $parseEditorCfgField=0;            // If set, the Backend Editor Configuration TypoScript is also parsed (this is not needed for the frontend)
 119      var $backend_info = 0;
 120      var $getFileName_backPath='';        // Set from the backend - used to set an absolute path (PATH_site) so that relative resources are properly found with getFileName()
 121  
 122          // Externally set breakpoints (used by Backend Modules)
 123      var $ext_constants_BRP=0;
 124      var $ext_config_BRP=0;
 125      var $ext_editorcfg_BRP=0;
 126      var $ext_regLinenumbers=FALSE;
 127  
 128          // Constants:
 129      var $uplPath = 'uploads/tf/';
 130      var $tempPath = 'typo3temp/';
 131      var $menuclasses = 'gmenu,tmenu,imgmenu,jsmenu';
 132  
 133          // Set Internally:
 134      var $whereClause = '';                // This MUST be initialized by the init() function
 135      var $debug = 0;
 136      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.
 137      var $currentPageData = '';            // Contains "currentPageData" when rendered/fetched from cache. See getCurrentPageData()
 138      var $simulationHiddenOrTime=0;        // See init(); Set if preview of some kind is enabled.
 139  
 140      var $loaded = 0;                    // Set, if the TypoScript template structure is loaded and OK, see ->start()
 141      var $setup = Array(                    // Default TypoScript Setup code
 142          'styles.' => Array (
 143              'insertContent' => 'CONTENT',
 144              'insertContent.' => Array (
 145                  'table' => 'tt_content',
 146                  'select.' => Array (
 147                      'orderBy' => 'sorting',
 148                      'where' => 'colPos=0',
 149                      'languageField' => 'sys_language_uid'
 150                  )
 151              )
 152          ),
 153          'config.' => Array (
 154              'extTarget' => '_top',
 155              'stat' => 1,
 156              'stat_typeNumList' => '0,1'
 157          )
 158      );
 159      var $flatSetup = Array (
 160      );
 161      var $const = Array (    // Default TypoScript Constants code:
 162          '_clear' => '<img src="clear.gif" width="1" height="1" alt="" />',
 163          '_blackBorderWrap' => '<table border="0" bgcolor="black" cellspacing="0" cellpadding="1"><tr><td> | </td></tr></table>',
 164          '_tableWrap' => '<table border="0" cellspacing="0" cellpadding="0"> | </table>',
 165          '_tableWrap_DEBUG' => '<table border="1" cellspacing="0" cellpadding="0"> | </table>',
 166          '_stdFrameParams' => 'frameborder="no" marginheight="0" marginwidth="0" noresize="noresize"',
 167          '_stdFramesetParams' => 'border="0" framespacing="0" frameborder="no"'
 168      );
 169  
 170  
 171          // For fetching TypoScript code from template hierarchy before parsing it. Each array contains code field values from template records/files:
 172      var $config = array();                // Setup field
 173      var $constants = array();            // Constant field
 174      var $editorcfg = array();            // Backend Editor Configuration field
 175  
 176      var $hierarchyInfo = array();        // For Template Analyser in backend
 177      var $hierarchyInfoToRoot = array();        // For Template Analyser in backend (setup content only)
 178      var $nextLevel=0;                    // Next-level flag (see runThroughTemplates())
 179      var $rootId;                        // The Page UID of the root page
 180      var $rootLine;                        // The rootline from current page to the root page
 181      var $absoluteRootLine;                // Rootline all the way to the root. Set but runThroughTemplates
 182      var $outermostRootlineIndexWithTemplate=0;    // A pointer to the last entry in the rootline where a template was found.
 183      var $rowSum;                        // Array of arrays with title/uid of templates in hierarchy
 184      var $resources='';                    // Resources for the template hierarchy in a comma list
 185      var $sitetitle='';                    // The current site title field.
 186      var $sections;                        // Tracking all conditions found during parsing of TypoScript. Used for the "all" key in currentPageData
 187      var $sectionsMatch;                    // Tracking all matching conditions found
 188  
 189          // Backend: ts_analyzer
 190      var $clearList_const=array();
 191      var $clearList_setup=array();
 192      var $clearList_editorcfg=array();
 193      var $parserErrors=array();
 194      var $setup_constants = array();
 195  
 196          // Other:
 197      var $fileCache = Array();            // Used by getFileName for caching of references to file resources
 198      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.
 199      var $MPmap = '';                    // Contains mapping of Page id numbers to MP variables.
 200  
 201  
 202  
 203  
 204      /**
 205       * Initialize
 206       * MUST be called directly after creating a new template-object
 207       *
 208       * @return    void
 209       * @see tslib_fe::initTemplate()
 210       */
 211  	function init()    {
 212              // $this->whereClause is used only to select templates from sys_template.
 213              // $GLOBALS['SIM_EXEC_TIME'] is used so that we're able to simulate a later time as a test...
 214          $this->whereClause='AND deleted=0 ';
 215          if (!$GLOBALS['TSFE']->showHiddenRecords)    {
 216              $this->whereClause.='AND hidden=0 ';
 217          }
 218          if ($GLOBALS['TSFE']->showHiddenRecords || $GLOBALS['SIM_EXEC_TIME']!=$GLOBALS['EXEC_TIME'])    {    // Set the simulation flag, if simulation is detected!
 219              $this->simulationHiddenOrTime=1;
 220          }
 221          $this->whereClause.= 'AND (starttime<='.$GLOBALS['SIM_EXEC_TIME'].') AND (endtime=0 OR endtime>'.$GLOBALS['SIM_EXEC_TIME'].')';
 222          if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'])    {
 223              $this->menuclasses='tmenu,jsmenu,gmenu';
 224          }
 225  
 226              // Sets the paths from where TypoScript resources are allowed to be used:
 227          $this->allowedPaths = Array ('media/','fileadmin/','uploads/','typo3temp/','t3lib/fonts/',TYPO3_mainDir.'ext/',TYPO3_mainDir.'sysext/','typo3conf/ext/');
 228          if ($GLOBALS['TYPO3_CONF_VARS']['FE']['addAllowedPaths'])    {
 229              $pathArr = t3lib_div::trimExplode(',',$GLOBALS['TYPO3_CONF_VARS']['FE']['addAllowedPaths'],1);
 230              while(list(,$p)=each($pathArr))    {
 231                      // 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.
 232                  $this->allowedPaths[] = $p;
 233              }
 234          }
 235      }
 236  
 237      /**
 238       * Fetches the "currentPageData" array from cache
 239       *
 240       * NOTE about currentPageData:
 241       * It holds information about the TypoScript conditions along with the list of template uid's which is used on the page.
 242       * In the getFromCache function in TSFE, currentPageData is used to evaluate if there is a template and if the matching conditions are alright
 243       * Unfortunately this does not take into account if the templates in the rowSum of currentPageData has changed composition, eg. due to hidden fields or start/end time.
 244       * So if a template is hidden or times out, it'll not be discovered unless the page is regenerated - at least the this->start function must be called, because this will make a new portion of data in currentPageData string
 245       *
 246       * @return    mixed        The array $this->currentPageData if found cached in "cache_pagesection". If the string "none" was returned it means the array must be generated and stored in the cache-table
 247       * @see start(), tslib_fe::getFromCache()
 248       */
 249  	function getCurrentPageData()    {
 250          $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('content', 'cache_pagesection', 'page_id='.intval($GLOBALS['TSFE']->id).' AND mpvar_hash='.t3lib_div::md5int($GLOBALS['TSFE']->MP));
 251          if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 252              $this->currentPageData = unserialize($row['content']);
 253          } else {
 254              $this->currentPageData = 'none';
 255          }
 256          return $this->currentPageData;
 257      }
 258  
 259      /**
 260       * Fetches data about which TypoScript-matches there are at this page. Then it performs a matchingtest.
 261       *
 262       * @param    array        An array with three keys, "all", "rowSum" and "rootLine" - all coming from the $this->currentPageData array
 263       * @return    array        The input array but with a new key added, "match" which contains the items from the "all" key which when passed to tslib_matchCondition returned true.
 264       * @see t3lib_matchCondition, tslib_fe::getFromCache()
 265       */
 266  	function matching($cc)    {
 267          if (is_array($cc['all']))    {
 268              reset($cc['all']);
 269              $matchObj = t3lib_div::makeInstance('t3lib_matchCondition');
 270              $matchObj->altRootLine=$cc['rootLine'];
 271              while(list($key,$pre)=each($cc['all']))    {
 272                  if ($matchObj->match($pre))    {
 273                      $sectionsMatch[$key]=$pre;
 274                  }
 275              }
 276              $cc['match']=$sectionsMatch;
 277          }
 278          return $cc;
 279      }
 280  
 281      /**
 282       * This is all about fetching the right TypoScript template structure. If it's not cached then it must be generated and cached!
 283       * The method traverse the rootline structure from out to in, fetches the hierarchy of template records and based on this either finds the cached TypoScript template structure or parses the template and caches it for next time.
 284       * Sets $this->setup to the parsed TypoScript Template array
 285       *
 286       * @param    array        The rootline of the current page (going ALL the way to tree root)
 287       * @return    void
 288       * @see tslib_fe::getConfigArray()
 289       */
 290  	function start($theRootLine)    {
 291          if (is_array($theRootLine))    {
 292              $setupData='';
 293              $cc=Array();
 294              $hash='';
 295              $this->runThroughTemplates($theRootLine);
 296  
 297                  // Getting the currentPageData if not already found
 298              if (!$this->currentPageData && !$GLOBALS['TSFE']->no_cache)    {
 299                  $this->getCurrentPageData();
 300              }
 301  
 302                  // This is about getting the hash string which is used to fetch the cached TypoScript template.
 303                  // If there was some cached currentPageData that's good (it gives us the hash),
 304                  // 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.
 305              if (is_array($this->currentPageData) &&
 306                  !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!
 307              )    {
 308                      // If currentPageData was actually there, we match the result...
 309                  $cc['all'] = $this->currentPageData['all'];
 310                  $cc['rowSum'] = $this->currentPageData['rowSum'];
 311                  $cc = $this->matching($cc);
 312                  $hash = md5(serialize($cc));
 313              } else {
 314                      // 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
 315                  $rowSumHash = md5('ROWSUM:'.serialize($this->rowSum));
 316                  $result = t3lib_pageSelect::getHash($rowSumHash, 0);
 317                  if ($result)    {
 318                      $cc['all'] = unserialize($result);
 319                      $cc['rowSum'] = $this->rowSum;
 320                      $cc = $this->matching($cc);
 321                      $hash = md5(serialize($cc));
 322                  }
 323              }
 324  
 325              if ($hash)    {
 326                      // Get TypoScript setup array
 327                  $setupData = t3lib_pageSelect::getHash($hash, 0);
 328              }
 329  
 330              if ($hash && $setupData && !$this->forceTemplateParsing)        {
 331                      // If TypoScript setup structure was cached we unserialize it here:
 332                  $this->setup = unserialize($setupData);
 333              } else {
 334                      // Make configuration
 335                  $this->generateConfig();
 336  
 337                      // This stores the template hash thing
 338                  $cc=Array();
 339                  $cc['all']=$this->sections;    // All sections in the template at this point is found
 340                  $cc['rowSum']=$this->rowSum;    // The line of templates is collected
 341                  $cc = $this->matching($cc);
 342  
 343                  $hash = md5(serialize($cc));
 344  
 345                      // This stores the data.
 346                  t3lib_pageSelect::storeHash($hash, serialize($this->setup), 'TS TEMPLATE');
 347  
 348                  if ($this->tt_track)    $GLOBALS['TT']->setTSlogMessage('TS template size, serialized: '.strlen(serialize($this->setup)).' bytes');
 349  
 350                  $rowSumHash = md5('ROWSUM:'.serialize($this->rowSum));
 351                  t3lib_pageSelect::storeHash($rowSumHash, serialize($cc['all']), 'TMPL CONDITIONS - AL');
 352              }
 353                  // Add rootLine
 354              $cc['rootLine'] = $this->rootLine;
 355                  // Make global and save.
 356              $GLOBALS['TSFE']->all=$cc;
 357  
 358              if (!$this->simulationHiddenOrTime && !$GLOBALS['TSFE']->no_cache)    {    // Only save currentPageData, if we're not simulating by hidden/starttime/endtime
 359                  $dbFields = array(
 360                      'content' => serialize($cc),
 361                      'tstamp' => $GLOBALS['EXEC_TIME']
 362                  );
 363                  $mpvar_hash = t3lib_div::md5int($GLOBALS['TSFE']->MP);
 364                  $GLOBALS['TYPO3_DB']->exec_UPDATEquery('cache_pagesection', 'page_id=' . intval($GLOBALS['TSFE']->id) . ' AND mpvar_hash=' . $mpvar_hash, $dbFields);
 365                  if ($GLOBALS['TYPO3_DB']->sql_affected_rows() == 0) {
 366                      $dbFields['page_id'] = intval($GLOBALS['TSFE']->id);
 367                      $dbFields['mpvar_hash'] = $mpvar_hash;
 368                      $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_pagesection', $dbFields);
 369                  }
 370              }
 371                  // If everything OK.
 372              if ($this->rootId && $this->rootLine && $this->setup)    {
 373                  $this->loaded = 1;
 374              }
 375          }
 376      }
 377  
 378  
 379  
 380  
 381  
 382  
 383  
 384  
 385  
 386  
 387  
 388  
 389  
 390  
 391  
 392      /*******************************************************************
 393       *
 394       * Fetching TypoScript code text for the Template Hierarchy
 395       *
 396       *******************************************************************/
 397  
 398      /**
 399       * Traverses the rootLine from the root and out. For each page it checks if there is a template record. If there is a template record, $this->processTemplate() is called.
 400       * Resets and affects internal variables like $this->constants, $this->config, $this->editorcfg and $this->rowSum
 401       * Also creates $this->rootLine which is a root line stopping at the root template (contrary to $GLOBALS['TSFE']->rootLine which goes all the way to the root of the tree
 402       *
 403       * @param    array        The rootline of the current page (going ALL the way to tree root)
 404       * @param    integer        Set specific template record UID to select; this is only for debugging/development/analysis use in backend modules like "Web > Template". For parsing TypoScript templates in the frontend it should be 0 (zero)
 405       * @return    void
 406       * @see start()
 407       */
 408  	function runThroughTemplates($theRootLine,$start_template_uid=0)    {
 409          $this->constants = Array();
 410          $this->config = Array();
 411          $this->editorcfg = Array();
 412          $this->rowSum = Array();
 413          $this->hierarchyInfoToRoot = Array();
 414          $this->absoluteRootLine=$theRootLine;    // Is the TOTAL rootline
 415  
 416          reset ($this->absoluteRootLine);
 417          $c=count($this->absoluteRootLine);
 418          for ($a=0;$a<$c;$a++)    {
 419              if ($this->nextLevel)    {    // If some template loaded before has set a template-id for the next level, then load this template first!
 420                  $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'uid='.intval($this->nextLevel).' '.$this->whereClause);
 421                  $this->nextLevel = 0;
 422                  if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 423                      $this->versionOL($row);
 424                      if (is_array($row))    {
 425                          $this->processTemplate($row,'sys_'.$row['uid'],$this->absoluteRootLine[$a]['uid'],'sys_'.$row['uid']);
 426                          $this->outermostRootlineIndexWithTemplate=$a;
 427                      }
 428                  }
 429                  $GLOBALS['TYPO3_DB']->sql_free_result($res);
 430              }
 431              $addC='';
 432              if ($a==($c-1) && $start_template_uid)    {    // If first loop AND there is set an alternative template uid, use that
 433                  $addC=' AND uid='.intval($start_template_uid);
 434              }
 435  
 436              $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'pid='.intval($this->absoluteRootLine[$a]['uid']).$addC.' '.$this->whereClause,'','sorting',1);
 437              if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
 438                  $this->versionOL($row);
 439                  if (is_array($row))    {
 440                      $this->processTemplate($row,'sys_'.$row['uid'],$this->absoluteRootLine[$a]['uid'],'sys_'.$row['uid']);
 441                      $this->outermostRootlineIndexWithTemplate=$a;
 442                  }
 443              }
 444              $GLOBALS['TYPO3_DB']->sql_free_result($res);
 445              $this->rootLine[] = $this->absoluteRootLine[$a];
 446          }
 447      }
 448  
 449      /**
 450       * Checks if the template ($row) has some included templates and after including them it fills the arrays with the setup
 451       * Builds up $this->rowSum
 452       *
 453       * @param    array        A full TypoScript template record (sys_template/static_template/forged "dummy" record made from static template file)
 454       * @param    string        A list of already processed template ids including the current; The list is on the form "[prefix]_[uid]" where [prefix] is "sys" for "sys_template" records, "static" for "static_template" records and "ext_" for static include files (from extensions). The list is used to check that the recursive inclusion of templates does not go into circles: Simply it is used to NOT include a template record/file which has already BEEN included somewhere in the recursion.
 455       * @param    array        The PID of the input template record
 456       * @param    string        The id of the current template. Same syntax as $idList ids, eg. "sys_123"
 457       * @param    string        Parent template id (during recursive call); Same syntax as $idList ids, eg. "sys_123"
 458       * @return    void
 459       * @see runThroughTemplates()
 460       */
 461  	function processTemplate($row, $idList,$pid,$templateID='',$templateParent='')    {
 462              // Adding basic template record information to rowSum array
 463          $this->rowSum[]=Array($row['uid'],$row['title'],$row['tstamp']);
 464  
 465              // Processing "Clear"-flags
 466          if ($row['clear'])    {
 467              $clConst = $row['clear']&1;
 468              $clConf = $row['clear']&2;
 469              if ($clConst)    {
 470                  $this->constants = Array();
 471                  $this->clearList_const=array();
 472              }
 473              if ($clConf)    {
 474                  $this->config = Array();
 475                  $this->hierarchyInfoToRoot = Array();
 476                  $this->clearList_setup=array();
 477  
 478                  $this->editorcfg = Array();
 479                  $this->clearList_editorcfg=array();
 480              }
 481          }
 482  
 483              // Include static records (static_template) or files (from extensions) (#1/2)
 484          if (!$row['includeStaticAfterBasedOn'])        {        // NORMAL inclusion, The EXACT same code is found below the basedOn inclusion!!!
 485              $this->includeStaticTypoScriptSources($idList,$templateID,$pid,$row);
 486          }
 487  
 488              // Include "Based On" sys_templates:
 489          if (trim($row['basedOn']))    {        // 'basedOn' is a list of templates to include
 490                  // Manually you can put this value in the field and then the based_on ID will be taken from the $_GET var defined by '=....'.
 491                  // 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!
 492                  // 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.
 493              $basedOn_hackFeature = explode('=',$row['basedOn']);
 494              if ($basedOn_hackFeature[0]=='EXTERNAL_BASED_ON_TEMPLATE_ID' && $basedOn_hackFeature[1])        {
 495                  $id = intval(t3lib_div::_GET($basedOn_hackFeature[1]));
 496                  if ($id && !t3lib_div::inList($idList,'sys_'.$id))    {    // if $id is not allready included ...
 497                      $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'uid='.$id.' '.$this->whereClause);
 498                      if ($subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {    // there was a template, then we fetch that
 499                          $this->versionOL($subrow);
 500                          if (is_array($subrow))    {
 501                              $this->processTemplate($subrow,$idList.',sys_'.$id,$pid, 'sys_'.$id,$templateID);
 502                          }
 503                      }
 504                      $GLOBALS['TYPO3_DB']->sql_free_result($res);
 505                  }
 506              } else {    // NORMAL OPERATION:
 507                  $basedOnArr = t3lib_div::intExplode(',',$row['basedOn']);
 508                  while(list(,$id)=each($basedOnArr))    {    // traversing list
 509                      if (!t3lib_div::inList($idList,'sys_'.$id))    {    // if $id is not allready included ...
 510                          $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'uid='.intval($id).' '.$this->whereClause);
 511                          if ($subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {    // there was a template, then we fetch that
 512                              $this->versionOL($subrow);
 513                              if (is_array($subrow))    {
 514                                  $this->processTemplate($subrow,$idList.',sys_'.$id,$pid, 'sys_'.$id,$templateID);
 515                              }
 516                          }
 517                          $GLOBALS['TYPO3_DB']->sql_free_result($res);
 518                      }
 519                  }
 520              }
 521          }
 522  
 523              // Include static records (static_template) or files (from extensions) (#2/2)
 524          if ($row['includeStaticAfterBasedOn'])        {
 525              $this->includeStaticTypoScriptSources($idList,$templateID,$pid,$row);
 526          }
 527  
 528              // Creating hierarchy information; Used by backend analysis tools
 529          $this->hierarchyInfo[] = $this->hierarchyInfoToRoot[] = array(
 530              'root'=>trim($row['root']),
 531              'next'=>$row['nextLevel'],
 532              'clConst'=>$clConst,
 533              'clConf'=>$clConf,
 534              'templateID'=>$templateID,
 535              'templateParent'=>$templateParent,
 536              'title'=>$row['title'],
 537              'uid'=>$row['uid'],
 538              'pid'=>$row['pid'],
 539              'configLines' => substr_count($row['config'], chr(10))+1
 540          );
 541  
 542              // Adding the content of the fields constants (Constants), config (Setup) and editorcfg (Backend Editor Configuration) to the internal arrays.
 543          $this->constants[] = $row['constants'];
 544          $this->config[] = $row['config'];
 545          if ($this->parseEditorCfgField)        $this->editorcfg[] = $row['editorcfg'];
 546  
 547              // For backend analysis (Template Analyser) provide the order of added constants/config/editorcfg template IDs
 548          $this->clearList_const[]=$templateID;
 549          $this->clearList_setup[]=$templateID;
 550          if ($this->parseEditorCfgField)        $this->clearList_editorcfg[]=$templateID;
 551  
 552              // Add resources and sitetitle if found:
 553          if (trim($row['resources']))    {
 554              $this->resources = $row['resources'].','.$this->resources;
 555          }
 556          if (trim($row['sitetitle']))    {
 557              $this->sitetitle = $row['sitetitle'];
 558          }
 559              // If the template record is a Rootlevel record, set the flag and clear the template rootLine (so it starts over from this point)
 560          if (trim($row['root']))    {
 561              $this->rootId = $pid;
 562              $this->rootLine = Array();
 563          }
 564              // If a template is set to be active on the next level set this internal value to point to this UID. (See runThroughTemplates())
 565          if ($row['nextLevel'])    {
 566              $this->nextLevel = $row['nextLevel'];
 567          } else {
 568              $this->nextLevel = 0;
 569          }
 570      }
 571  
 572      /**
 573       * Includes static template records (from static_template table) and static template files (from extensions) for the input template record row.
 574       *
 575       * @param    string        A list of already processed template ids including the current; The list is on the form "[prefix]_[uid]" where [prefix] is "sys" for "sys_template" records, "static" for "static_template" records and "ext_" for static include files (from extensions). The list is used to check that the recursive inclusion of templates does not go into circles: Simply it is used to NOT include a template record/file which has already BEEN included somewhere in the recursion.
 576       * @param    string        The id of the current template. Same syntax as $idList ids, eg. "sys_123"
 577       * @param    array        The PID of the input template record
 578       * @param    array        A full TypoScript template record
 579       * @return    void
 580       * @see processTemplate()
 581       */
 582  	function includeStaticTypoScriptSources($idList,$templateID,$pid,$row)    {
 583              // Static Template Records (static_template): include_static is a list of static templates to include
 584          if (trim($row['include_static']))    {
 585              $include_staticArr = t3lib_div::intExplode(',',$row['include_static']);
 586              reset($include_staticArr);
 587              while(list(,$id)=each($include_staticArr))    {    // traversing list
 588                  if (!t3lib_div::inList($idList,'static_'.$id))    {    // if $id is not allready included ...
 589                      $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'static_template', 'uid='.intval($id));
 590                      if ($subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {    // there was a template, then we fetch that
 591                          $subrow = $this->prependStaticExtra($subrow);
 592                          $this->processTemplate($subrow,$idList.',static_'.$id,$pid,'static_'.$id,$templateID);
 593                      }
 594                      $GLOBALS['TYPO3_DB']->sql_free_result($res);
 595                  }
 596              }
 597          }
 598  
 599              // Static Template Files (Text files from extensions): include_static_file is a list of static files to include (from extensions)
 600          if (trim($row['include_static_file']))    {
 601              $include_static_fileArr = t3lib_div::trimExplode(',',$row['include_static_file'],1);
 602              reset($include_static_fileArr);
 603              while(list(,$ISF_file)=each($include_static_fileArr))    {    // traversing list
 604                  $ISF_file = trim($ISF_file);
 605                  if (substr($ISF_file,0,4)=='EXT:')    {
 606                      list($ISF_extKey,$ISF_localPath) = explode('/',substr($ISF_file,4),2);
 607                      if (strcmp($ISF_extKey,'') && t3lib_extMgm::isLoaded($ISF_extKey) && strcmp($ISF_localPath,''))    {
 608                          $ISF_localPath = ereg_replace('\/$','',$ISF_localPath).'/';
 609                          $ISF_filePath = t3lib_extMgm::extPath($ISF_extKey).$ISF_localPath;
 610                          if (@is_dir($ISF_filePath))    {
 611                              $mExtKey = str_replace('_','',$ISF_extKey.'/'.$ISF_localPath);
 612                              $subrow=array(
 613                                  'constants'=>    @is_file($ISF_filePath.'constants.txt')    ?t3lib_div::getUrl($ISF_filePath.'constants.txt'):'',
 614                                  'config'=>        @is_file($ISF_filePath.'setup.txt')        ?t3lib_div::getUrl($ISF_filePath.'setup.txt'):'',
 615                                  'editorcfg'=>    @is_file($ISF_filePath.'editorcfg.txt')    ?t3lib_div::getUrl($ISF_filePath.'editorcfg.txt'):'',
 616                                  'include_static'=>    @is_file($ISF_filePath.'include_static.txt')?implode(',',array_unique(t3lib_div::intExplode(',',t3lib_div::getUrl($ISF_filePath.'include_static.txt')))):'',
 617                                  'include_static_file'=>    @is_file($ISF_filePath.'include_static_file.txt')?implode(',',array_unique(explode(',',t3lib_div::getUrl($ISF_filePath.'include_static_file.txt')))):'',
 618                                  'title' =>         $ISF_file,
 619                                  'uid' =>         $mExtKey
 620                              );
 621                              $subrow = $this->prependStaticExtra($subrow);
 622  
 623                              $this->processTemplate($subrow,$idList.',ext_'.$mExtKey,$pid, 'ext_'.$mExtKey,$templateID);
 624                          }
 625                      }
 626                  }
 627              }
 628          }
 629  
 630          $this->addExtensionStatics($idList,$templateID,$pid,$row);
 631      }
 632  
 633      /**
 634       * Adds the default TypoScript files for extensions if any.
 635       *
 636       * @param    string        A list of already processed template ids including the current; The list is on the form "[prefix]_[uid]" where [prefix] is "sys" for "sys_template" records, "static" for "static_template" records and "ext_" for static include files (from extensions). The list is used to check that the recursive inclusion of templates does not go into circles: Simply it is used to NOT include a template record/file which has already BEEN included somewhere in the recursion.
 637       * @param    string        The id of the current template. Same syntax as $idList ids, eg. "sys_123"
 638       * @param    array        The PID of the input template record
 639       * @param    array        A full TypoScript template record
 640       * @return    void
 641       * @access private
 642       * @see includeStaticTypoScriptSources()
 643       */
 644  	function addExtensionStatics($idList,$templateID,$pid,$row) {
 645          global $TYPO3_LOADED_EXT;
 646  
 647          if ($row['static_file_mode']==1 || ($row['static_file_mode']==0 && substr($templateID,0,4)=='sys_' && $row['root']))    {
 648              reset($TYPO3_LOADED_EXT);
 649              while(list($extKey,$files)=each($TYPO3_LOADED_EXT))    {
 650                  if (is_array($files) && ($files['ext_typoscript_constants.txt'] || $files['ext_typoscript_setup.txt'] || $files['ext_typoscript_editorcfg.txt']))    {
 651                      $mExtKey = str_replace('_','',$extKey);
 652                      $subrow=array(
 653                          'constants'=>    $files['ext_typoscript_constants.txt']?t3lib_div::getUrl($files['ext_typoscript_constants.txt']):'',
 654                          'config'=>        $files['ext_typoscript_setup.txt']?t3lib_div::getUrl($files['ext_typoscript_setup.txt']):'',
 655                          'editorcfg'=>        $files['ext_typoscript_editorcfg.txt']?t3lib_div::getUrl($files['ext_typoscript_editorcfg.txt']):'',
 656                          'title' =>         $extKey,
 657                          'uid' =>         $mExtKey
 658                      );
 659                      $subrow = $this->prependStaticExtra($subrow);
 660  
 661                      $this->processTemplate($subrow,$idList.',ext_'.$mExtKey,$pid, 'ext_'.$mExtKey,$templateID);
 662                  }
 663              }
 664          }
 665      }
 666  
 667      /**
 668       * Appends (not prepends) additional TypoScript code to static template records/files as set in TYPO3_CONF_VARS
 669       * For records the "uid" value is the integer of the "static_template" record
 670       * For files the "uid" value is the extension key but with any underscores removed. Possibly with a path if its a static file selected in the template record
 671       *
 672       * @param    array        Static template record/file
 673       * @return    array        Returns the input array where the values for keys "config", "constants" and "editorcfg" may have been modified with prepended code.
 674       * @access private
 675       * @see addExtensionStatics(), includeStaticTypoScriptSources()
 676       */
 677  	function prependStaticExtra($subrow)    {
 678          $subrow['config'].=$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_setup.'][$subrow['uid']];
 679          $subrow['editorcfg'].=$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_editorcfg.'][$subrow['uid']];
 680          $subrow['constants'].=$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_constants.'][$subrow['uid']];
 681          return $subrow;
 682      }
 683  
 684      /**
 685       * Creating versioning overlay of a sys_template record. This will use either frontend or backend overlay functionality depending on environment.
 686       *
 687       * @param    array        Row to overlay.
 688       * @return    void        Row is passed by reference.
 689       */
 690  	function versionOL(&$row)    {
 691          if (is_object($GLOBALS['TSFE']))    {    // Frontend:
 692              $GLOBALS['TSFE']->sys_page->versionOL('sys_template',$row);
 693          } else {    // Backend:
 694              t3lib_BEfunc::workspaceOL('sys_template',$row);
 695          }
 696      }
 697  
 698  
 699  
 700  
 701  
 702  
 703  
 704  
 705  
 706  
 707  
 708  
 709  
 710  
 711  
 712  
 713  
 714      /*******************************************************************
 715       *
 716       * Parsing TypoScript code text from Template Records into PHP array
 717       *
 718       *******************************************************************/
 719  
 720      /**
 721       * Generates the configuration array by replacing constants and parsing the whole thing.
 722       * Depends on $this->config and $this->constants to be set prior to this! (done by processTemplate/runThroughTemplates)
 723       *
 724       * @return    void
 725       * @see t3lib_TSparser, start()
 726       */
 727  	function generateConfig()    {
 728              // Add default TS for all three code types:
 729          array_unshift($this->constants,''.$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_constants']);    // Adding default TS/constants
 730          array_unshift($this->config,''.$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_setup']);    // Adding default TS/setup
 731          array_unshift($this->editorcfg,''.$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_editorcfg']);    // Adding default TS/editorcfg
 732  
 733              // Parse the TypoScript code text for include-instructions!
 734          $this->procesIncludes();
 735  
 736              // These vars are also set lateron...
 737          $this->setup['resources']= $this->resources;
 738          $this->setup['sitetitle']= $this->sitetitle;
 739  
 740  
 741  
 742          // ****************************
 743          // Parse TypoScript Constants
 744          // ****************************
 745  
 746              // Initialize parser and match-condition classes:
 747          $constants = t3lib_div::makeInstance('t3lib_TSparser');
 748          $constants->breakPointLN=intval($this->ext_constants_BRP);
 749          $constants->setup = $this->const;
 750          $constants->setup = $this->mergeConstantsFromPageTSconfig($constants->setup);
 751          $matchObj = t3lib_div::makeInstance('t3lib_matchCondition');
 752          $matchObj->matchAlternative = $this->matchAlternative;
 753          $matchObj->matchAll = $this->matchAll;        // Matches ALL conditions in TypoScript
 754  
 755              // Traverse constants text fields and parse them
 756          foreach($this->constants as $str)    {
 757              $constants->parse($str,$matchObj);
 758          }
 759  
 760              // Read out parse errors if any
 761          $this->parserErrors['constants']=$constants->errors;
 762  
 763              // 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)
 764          $this->flatSetup = Array();
 765          $this->flattenSetup($constants->setup,'','');
 766  
 767  
 768  
 769          // ***********************************************
 770          // Parse TypoScript Setup (here called "config")
 771          // ***********************************************
 772              // Initialize parser and match-condition classes:
 773          $config = t3lib_div::makeInstance('t3lib_TSparser');
 774          $config->breakPointLN = intval($this->ext_config_BRP);
 775          $config->regLinenumbers = $this->ext_regLinenumbers;
 776          $config->setup = $this->setup;
 777  
 778              // Transfer information about conditions found in "Constants" and which of them returned true.
 779          $config->sections = $constants->sections;
 780          $config->sectionsMatch = $constants->sectionsMatch;
 781  
 782              // Traverse setup text fields and concatenate them into one, single string separated by a [GLOBAL] condition
 783          $all='';
 784          foreach($this->config as $str)    {
 785              $all.="\n[GLOBAL]\n".$str;
 786          }
 787  
 788              // Substitute constants in the Setup code:
 789          if ($this->tt_track)    $GLOBALS['TT']->push('Substitute Constants ('.count($this->flatSetup).')');
 790          $all = $this->substituteConstants($all);
 791          if ($this->tt_track)    $GLOBALS['TT']->pull();
 792  
 793              // Searching for possible unsubstituted constants left (only for information)
 794          if (strstr($all,'{$'))    {
 795              $findConst = explode('{$',$all);
 796              $theConstList=Array();
 797              next($findConst);
 798              while(list(,$constVal)=each($findConst))    {
 799                  $constLen=t3lib_div::intInRange(strcspn($constVal,'}'),0,50);
 800                  $theConstList[]='{$'.substr($constVal,0,$constLen+1);
 801              }
 802              if ($this->tt_track)    $GLOBALS['TT']->setTSlogMessage(implode(',',$theConstList).': Constants may remain un-substituted!!',2);
 803          }
 804  
 805              // Logging the textual size of the TypoScript Setup field text with all constants substituted:
 806          if ($this->tt_track)    $GLOBALS['TT']->setTSlogMessage('TypoScript template size as textfile: '.strlen($all).' bytes');
 807  
 808              // Finally parse the Setup field TypoScript code (where constants are now substituted)
 809          $config->parse($all,$matchObj);
 810  
 811              // Read out parse errors if any
 812          $this->parserErrors['config']=$config->errors;
 813  
 814              // Transfer the TypoScript array from the parser object to the internal $this->setup array:
 815          $this->setup = $config->setup;
 816          if ($this->backend_info)    {
 817              $this->setup_constants = $constants->setup;        // Used for backend purposes only
 818          }
 819  
 820  
 821  
 822  
 823          // **************************************************
 824          // Parse Backend Editor Configuration (backend only)
 825          // **************************************************
 826          if ($this->parseEditorCfgField)    {
 827              $editorcfg = t3lib_div::makeInstance('t3lib_TSparser');
 828              $editorcfg->breakPointLN=intval($this->ext_editorcfg_BRP);
 829              $editorcfg->setup = array();    // Empty as a start...
 830  
 831              $all = implode("\n[GLOBAL]\n",$this->editorcfg);
 832  
 833                  // substitute constants in config
 834              $all = $this->substituteConstants($all);
 835  
 836                  // parse Config
 837              $matchObj->matchAll=1;    // This should make sure that conditions are disabled. For now they are NOT active for the backend.
 838              $editorcfg->parse($all,$matchObj);
 839              $this->parserErrors['editorcfg']=$editorcfg->errors;
 840              $this->setup_editorcfg = $editorcfg->setup;
 841          }
 842  
 843  
 844  
 845  
 846  
 847          // ****************************************************************
 848          // Final processing of the $this->setup TypoScript Template array
 849          // Basically: This is unsetting/setting of certain reserved keys.
 850          // ****************************************************************
 851  
 852              // 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!
 853          unset($this->setup['resources']);
 854          unset($this->setup['resources.']);
 855          $this->setup['resources']= implode(',',t3lib_div::trimExplode(',',$this->resources,1));
 856  
 857          unset($this->setup['sitetitle']);
 858          unset($this->setup['sitetitle.']);
 859          $this->setup['sitetitle']= $this->sitetitle;
 860  
 861              // Unsetting some vars...
 862          unset($this->setup['types.']);
 863          unset($this->setup['types']);
 864          if (is_array($this->setup)) {
 865              reset ($this->setup);
 866              while(list($theKey,)=each($this->setup))    {
 867                  if ($this->setup[$theKey]=='PAGE')    {
 868                      $tN = $this->setup[$theKey.'.']['typeNum'];
 869                      if (isset($tN))    {
 870                          $this->setup['types.'][$tN] = $theKey;
 871                      } 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
 872                          $this->setup['types.'][0] = $theKey;
 873                      }
 874                  }
 875              }
 876          }
 877          unset($this->setup['styles.']);
 878          unset($this->setup['temp.']);
 879          unset($constants);
 880  
 881              // Storing the conditions found/matched information:
 882          $this->sections = $config->sections;
 883          $this->sectionsMatch = $config->sectionsMatch;
 884      }
 885  
 886      /**
 887       * Searching TypoScript code text (for constants, config (Setup) and editorcfg) for include instructions and does the inclusion if needed.
 888       * Modifies
 889       *
 890       * @return    void
 891       * @see t3lib_TSparser, generateConfig()
 892       */
 893  	function procesIncludes()    {
 894          reset($this->constants);
 895          while(list($k)=each($this->constants))    {
 896              $this->constants[$k]=t3lib_TSparser::checkIncludeLines($this->constants[$k]);
 897          }
 898  
 899          reset($this->config);
 900          while(list($k)=each($this->config))    {
 901              $this->config[$k]=t3lib_TSparser::checkIncludeLines($this->config[$k]);
 902          }
 903  
 904          reset($this->editorcfg);
 905          while(list($k)=each($this->editorcfg))    {
 906              $this->editorcfg[$k]=t3lib_TSparser::checkIncludeLines($this->editorcfg[$k]);
 907          }
 908      }
 909  
 910      /**
 911       * Loads Page TSconfig until the outermost template record and parses the configuration - if TSFE.constants object path is found it is merged with the default data in here!
 912       *
 913       * @param    array        Constants array, default input.
 914       * @return    array        Constants array, modified
 915       * @todo    Apply caching to the parsed Page TSconfig. This is done in the other similar functions for both frontend and backend. However, since this functions works for BOTH frontend and backend we will have to either write our own local caching function or (more likely) detect if we are in FE or BE and use caching functions accordingly. Not having caching affects mostly the backend modules inside the "Template" module since the overhead in the frontend is only seen when TypoScript templates are parsed anyways (after which point they are cached anyways...)
 916       */
 917  	function mergeConstantsFromPageTSconfig($constArray)    {
 918          $TSdataArray = array();
 919          $TSdataArray[]=$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'];    // Setting default configuration:
 920  
 921          for ($a=0;$a<=$this->outermostRootlineIndexWithTemplate;$a++)    {
 922              $TSdataArray[]=$this->absoluteRootLine[$a]['TSconfig'];
 923          }
 924              // Parsing the user TS (or getting from cache)
 925          $TSdataArray = t3lib_TSparser::checkIncludeLines_array($TSdataArray);
 926          $userTS = implode(chr(10).'[GLOBAL]'.chr(10),$TSdataArray);
 927  
 928          $parseObj = t3lib_div::makeInstance('t3lib_TSparser');
 929          $parseObj->parse($userTS);
 930  
 931          if (is_array($parseObj->setup['TSFE.']['constants.']))    {
 932              $constArray = t3lib_div::array_merge_recursive_overrule($constArray,$parseObj->setup['TSFE.']['constants.']);
 933          }
 934          return $constArray;
 935      }
 936  
 937      /**
 938       * This flattens a hierarchical TypoScript array to $this->flatSetup
 939       *
 940       * @param    array        TypoScript array
 941       * @param    string        Prefix to the object path. Used for recursive calls to this function.
 942       * @param    boolean        If set, then the constant value will be resolved as a TypoScript "resource" data type. Also used internally during recursive calls so that all subproperties for properties named "file." will be resolved as resources.
 943       * @return    void
 944       * @see generateConfig()
 945       */
 946  	function flattenSetup($setupArray, $prefix, $resourceFlag)    {
 947          if (is_array($setupArray))    {
 948              reset($setupArray);
 949              while(list($key,$val)=each($setupArray))    {
 950                  if ($prefix || substr($key,0,16)!='TSConstantEditor')    {        // We don't want 'TSConstantEditor' in the flattend setup on the first level (190201)
 951                      if (is_array($val))    {
 952                          $this->flattenSetup($val,$prefix.$key, ($key=='file.'));
 953                      } elseif ($resourceFlag) {
 954                          $this->flatSetup[$prefix.$key] = $this->getFileName($val);
 955                      } else {
 956                          $this->flatSetup[$prefix.$key] = $val;
 957                      }
 958                  }
 959              }
 960          }
 961      }
 962  
 963      /**
 964       * Substitutes the constants from $this->flatSetup in the text string $all
 965       *
 966       * @param    string        TypoScript code text string
 967       * @return    string        The processed string with all constants found in $this->flatSetup as key/value pairs substituted.
 968       * @see generateConfig(), flattenSetup()
 969       */
 970  	function substituteConstants($all)    {
 971          if ($this->tt_track)    $GLOBALS['TT']->setTSlogMessage('Constants to substitute: '.count($this->flatSetup));
 972  
 973          $noChange = false;
 974          // recursive substitution of constants (up to 10 nested levels)
 975          for ($i = 0; $i < 10 && !$noChange; $i++) {
 976              $old_all = $all;
 977              $all = preg_replace_callback('/\{\$(.[^}]*)\}/', array($this, 'substituteConstantsCallBack'), $all);
 978              if ($old_all == $all) {
 979                  $noChange = true;
 980              }
 981          }
 982  
 983          return $all;
 984      }
 985  
 986      /**
 987       * Call back method for preg_replace_callback in substituteConstants
 988       *
 989       * @param    array        Regular expression matches
 990       * @return    string        Replacement
 991       * @see substituteConstants()
 992       */
 993  	function substituteConstantsCallBack($matches) {
 994          // replace {$CONST} if found in $this->flatSetup, else leave unchanged
 995          return isset($this->flatSetup[$matches[1]]) && !is_array($this->flatSetup[$matches[1]]) ? $this->flatSetup[$matches[1]] : $matches[0];
 996      }
 997  
 998  
 999  
1000  
1001  
1002  
1003  
1004  
1005  
1006  
1007      /*******************************************************************
1008       *
1009       * Various API functions, used from elsewhere in the frontend classes
1010       *
1011       *******************************************************************/
1012  
1013      /**
1014       * Implementation of the "optionSplit" feature in TypoScript (used eg. for MENU objects)
1015       * What it does is to split the incoming TypoScript array so that the values are exploded by certain strings ("||" and "|*|") and each part distributed into individual TypoScript arrays with a similar structure, but individualized values.
1016       * The concept is known as "optionSplit" and is rather advanced to handle but quite powerful, in particular for creating menus in TYPO3.
1017       *
1018       * @param    array        A TypoScript array
1019       * @param    integer        The number of items for which to generated individual TypoScript arrays
1020       * @return    array        The individualized TypoScript array.
1021       * @see tslib_cObj::IMGTEXT(), tslib_menu::procesItemStates()
1022       * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=289&cHash=6604390b37
1023       */
1024  	function splitConfArray($conf,$splitCount)    {
1025  
1026              // Initialize variables:
1027          $splitCount = intval($splitCount);
1028          $conf2 = Array();
1029  
1030          if ($splitCount && is_array($conf))    {
1031  
1032                  // Initialize output to carry at least the keys:
1033              for ($aKey=0;$aKey<$splitCount;$aKey++)    {
1034                  $conf2[$aKey] = array();
1035              }
1036  
1037                  // Recursive processing of array keys:
1038              foreach($conf as $cKey => $val)    {
1039                  if (is_array($val))    {
1040                      $tempConf = $this->splitConfArray($val,$splitCount);
1041                      foreach($tempConf as $aKey => $val)    {
1042                          $conf2[$aKey][$cKey] = $val;
1043                      }
1044                  }
1045              }
1046  
1047                  // Splitting of all values on this level of the TypoScript object tree:
1048              foreach($conf as $cKey => $val)    {
1049                  if (!is_array($val))    {
1050                      if (!strstr($val,'|*|') && !strstr($val,'||'))    {
1051                          for ($aKey=0;$aKey<$splitCount;$aKey++)    {
1052                              $conf2[$aKey][$cKey] = $val;
1053                          }
1054                      } else {
1055                          $main = explode ('|*|',$val);
1056                          $mainCount = count($main);
1057  
1058                          $lastC = 0;
1059                          $middleC = 0;
1060                          $firstC = 0;
1061  
1062                          if ($main[0])    {
1063                              $first = explode('||',$main[0]);
1064                              $firstC = count($first);
1065                          }
1066                          if ($main[1])    {
1067                              $middle = explode('||',$main[1]);
1068                              $middleC = count($middle);
1069                          }
1070                          if ($main[2])    {
1071                              $last = explode('||',$main[2]);
1072                              $lastC = count($last);
1073                              $value = $last[0];
1074                          }
1075  
1076                          for ($aKey=0;$aKey<$splitCount;$aKey++)    {
1077                              if ($firstC && isset($first[$aKey])) {
1078                                  $value = $first[$aKey];
1079                              } elseif ($middleC) {
1080                                  $value = $middle[($aKey-$firstC)%$middleC];
1081                              }
1082                              if ($lastC && $lastC>=($splitCount-$aKey))    {
1083                                  $value = $last[$lastC-($splitCount-$aKey)];
1084                              }
1085                              $conf2[$aKey][$cKey] = trim($value);
1086                          }
1087                      }
1088                  }
1089              }
1090          }
1091          return $conf2;
1092      }
1093  
1094      /**
1095       * Returns the reference to a 'resource' in TypoScript.
1096       * This could be from the filesystem if '/' is found in the value $fileFromSetup, else from the resource-list
1097       *
1098       * @param    string        TypoScript "resource" data type value.
1099       * @return    string        Resulting filename, if any.
1100       */
1101  	function getFileName($fileFromSetup)    {
1102          $file = trim($fileFromSetup);
1103          if (!$file)    {
1104              return;
1105          } elseif (strstr($file,'../'))    {
1106              if ($this->tt_track)    $GLOBALS['TT']->setTSlogMessage('File path "'.$file.'" contained illegal string "../"!',3);
1107              return;
1108          }
1109              // cache
1110          $hash = md5($file);
1111          if (isset($this->fileCache[$hash]))    {
1112              return $this->fileCache[$hash];
1113          }
1114  
1115          if (!strcmp(substr($file,0,4),'EXT:'))    {
1116              $newFile='';
1117              list($extKey,$script)=explode('/',substr($file,4),2);
1118              if ($extKey && t3lib_extMgm::isLoaded($extKey))    {
1119                  $extPath=t3lib_extMgm::extPath($extKey);
1120                  $newFile=substr($extPath,strlen(PATH_site)).$script;
1121              }
1122              if (!@is_file(PATH_site.$newFile))    {
1123                  if ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('Extension media file "'.$newFile.'" was not found!',3);
1124                  return;
1125              } else $file=$newFile;
1126          }
1127  
1128              // find
1129          if (strstr($file,'/')) {    // here it is manual media
1130              if(!strcmp(substr($file,0,6),'media/')) $file = 'typo3/sysext/cms/tslib/'.$file;
1131              if (@is_file($this->getFileName_backPath.$file))    {
1132                  $outFile = $file;
1133                  $fileInfo = t3lib_div::split_fileref($outFile);
1134                  reset($this->allowedPaths);
1135                  $OK=0;
1136                  while(list(,$val)=each($this->allowedPaths))    {
1137                      if (substr($fileInfo['path'],0,strlen($val))==$val){$OK=1; break;}
1138                  }
1139                  if ($OK)    {
1140                      $this->fileCache[$hash]=$outFile;
1141                      return $outFile;
1142                  } elseif ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('"'.$file.'" was not located in the allowed paths: ('.implode(',',$this->allowedPaths).')',3);
1143              } elseif ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('"'.$this->getFileName_backPath.$file.'" is not a file (non-uploads/.. resource, did not exist).',3);
1144          } else {        // Here it is uploaded media:
1145              $outFile = $this->extractFromResources($this->setup['resources'],$file);
1146              if ($outFile)    {
1147                   if (@is_file($this->uplPath.$outFile))    {
1148                      $this->fileCache[$hash] = $this->uplPath.$outFile;
1149                      return $this->uplPath.$outFile;
1150                  } elseif ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('"'.$this->uplPath.$outFile.'" is not a file (did not exist).',3);
1151              } elseif ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('"'.$file.'" is not a file (uploads/.. resource).',3);
1152          }
1153      }
1154  
1155      /**
1156       * Searches for the TypoScript resource filename in the list of resource filenames.
1157       *
1158       * @param    string        The resource file name list (from $this->setup['resources'])
1159       * @param    string        The resource value to match
1160       * @return    string        If found, this will be the resource filename that matched. Typically this file is found in "uploads/tf/"
1161       * @access private
1162       * @see getFileName()
1163       */
1164  	function extractFromResources($res,$file)    {
1165          if (t3lib_div::inList($res,$file))    {
1166              $outFile = $file;
1167          } elseif (strstr($file,'*')) {
1168              $fileparts=explode('*',$file);
1169              $c=count($fileparts);
1170              $files = explode(',',$res);
1171              while(list(,$val)=each($files))    {
1172                  $test = trim($val);
1173                  if (ereg('^'.quotemeta($fileparts[0]).'.*'.quotemeta($fileparts[$c-1]).'$', $test))    {
1174                      $outFile = $test;
1175                      break;
1176                  }
1177              }
1178          }
1179          return $outFile;
1180      }
1181  
1182      /**
1183       * CheckFile runs through the $menuArr and checks every file-reference in $name
1184       * (Not used anywhere)
1185       *
1186       * @param    string        Property name in the menu array
1187       * @param    array        Menu array to traverse
1188       * @return    array        Modified menu array
1189       * @deprecated
1190       * @internal
1191       */
1192  	function checkFile($name,$menuArr)    {
1193          reset ($menuArr);
1194          while (list($aKey,)=each($menuArr))    {
1195              $menuArr[$aKey][$name] = $this->getFileName($menuArr[$aKey][$name]);
1196          }
1197          return $menuArr;
1198      }
1199  
1200      /**
1201       * Compiles the content for the page <title> tag.
1202       *
1203       * @param    string        The input title string, typically the "title" field of a page's record.
1204       * @param    boolean        If set, then only the site title is outputted (from $this->setup['sitetitle'])
1205       * @param    boolean        If set, then "sitetitle" and $title is swapped
1206       * @return    string        The page title on the form "[sitetitle]: [input-title]". Not htmlspecialchar()'ed.
1207       * @see tslib_fe::tempPageCacheContent(), TSpagegen::renderContentWithHeader()
1208       */
1209  	function printTitle($title,$no_title=0,$titleFirst=0)    {
1210          $st = trim($this->setup['sitetitle']) ? $this->setup['sitetitle']:'';
1211          $title = $no_title ? '' : $title;
1212          if ($titleFirst)    {
1213              $temp=$st;
1214              $st=$title;
1215              $title=$temp;
1216          }
1217          if ($title && $st)    {
1218              return $st.': '.$title;
1219          } else {
1220              return $st.$title;
1221          }
1222      }
1223  
1224      /**
1225       * Reads the fileContent of $fName and returns it.
1226       * Similar to t3lib_div::getUrl()
1227       *
1228       * @param    string        Absolute filepath to record
1229       * @return    string        The content returned
1230       * @see tslib_cObj::fileResource(), tslib_cObj::MULTIMEDIA(), t3lib_div::getUrl()
1231       */
1232  	function fileContent($fName)    {
1233          $incFile = $this->getFileName($fName);
1234          if ($incFile)    {
1235              return @file_get_contents($incFile);
1236          }
1237      }
1238  
1239      /**
1240       * Ordinary "wrapping" function. Used in the tslib_menu class and extension classes instead of the similar function in tslib_cObj
1241       *
1242       * @param    string        The content to wrap
1243       * @param    string        The wrap value, eg. "<b> | </b>"
1244       * @return    string        Wrapped input string
1245       * @see tslib_menu, tslib_cObj::wrap()
1246       */
1247  	function wrap($content,$wrap)    {
1248          if ($wrap)    {
1249              $wrapArr = explode('|', $wrap);
1250              return trim($wrapArr[0]).$content.trim($wrapArr[1]);
1251          } else return $content;
1252      }
1253  
1254      /**
1255       * Removes the "?" of input string IF the "?" is the last character.
1256       *
1257       * @param    string        Input string
1258       * @return    string        Output string, free of "?" in the end, if any such character.
1259       * @see linkData(), tslib_frameset::frameParams()
1260       */
1261  	function removeQueryString($url)    {
1262          if (substr($url,-1)=='?')    {
1263              return substr($url,0,-1);
1264          } else {
1265              return $url;
1266          }
1267      }
1268  
1269      /**
1270       * Takes a TypoScript array as input and returns an array which contains all integer properties found which had a value (not only properties). The output array will be sorted numerically.
1271       * Call it like t3lib_TStemplate::sortedKeyList()
1272       *
1273       * @param    array        TypoScript array with numerical array in
1274       * @param    boolean        If set, then a value is not required - the properties alone will be enough.
1275       * @return    array        An array with all integer properties listed in numeric order.
1276       * @see tslib_cObj::cObjGet(), tslib_gifBuilder, tslib_imgmenu::makeImageMap()
1277       */
1278  	function sortedKeyList($setupArr, $acceptOnlyProperties=FALSE)    {
1279          $keyArr = Array();
1280  
1281          reset($setupArr);
1282          while(list($key,)=each($setupArr))    {
1283              $ikey = intval($key);
1284              if (!strcmp($ikey,$key) || $acceptOnlyProperties)    {
1285                  $keyArr[] = $ikey;
1286              }
1287          }
1288  
1289          $keyArr = array_unique($keyArr);
1290          sort($keyArr);
1291          return $keyArr;
1292      }
1293  
1294  
1295  
1296  
1297  
1298  
1299  
1300  
1301  
1302  
1303      /*******************************************************************
1304       *
1305       * Functions for creating links
1306       *
1307       *******************************************************************/
1308  
1309      /**
1310       * The mother of all functions creating links/URLs etc in a TypoScript environment.
1311       * See the references below.
1312       * Basically this function takes care of issues such as type,id,alias and Mount Points, simulate static documents, M5/B6 encoded parameters etc.
1313       * It is important to pass all links created through this function since this is the guarantee that globally configured settings for link creating are observed and that your applications will conform to the various/many configuration options in TypoScript Templates regarding this.
1314       *
1315       * @param    array        The page record of the page to which we are creating a link. Needed due to fields like uid, alias, target, no_cache, title and sectionIndex_uid.
1316       * @param    string        Default target string to use IF not $page['target'] is set.
1317       * @param    boolean        If set, then the "&no_cache=1" parameter is included in the URL.
1318       * @param    string        Alternative script name if you don't want to use $GLOBALS['TSFE']->config['mainScript'] (normally set to "index.php")
1319       * @param    array        Array with overriding values for the $page array.
1320       * @param    string        Additional URL parameters to set in the URL. Syntax is "&foo=bar&foo2=bar2" etc. Also used internally to add parameters if needed.
1321       * @param    string        If you set this value to something else than a blank string, then the typeNumber used in the link will be forced to this value. Normally the typeNum is based on the target set OR on $GLOBALS['TSFE']->config['config']['forceTypeValue'] if found.
1322       * @return    array        Contains keys like "totalURL", "url", "sectionIndex", "linkVars", "no_cache", "type", "target" of which "totalURL" is normally the value you would use while the other keys contains various parts that was used to construct "totalURL"
1323       * @see tslib_frameset::frameParams(), tslib_cObj::typoLink(), tslib_cObj::SEARCHRESULT(), TSpagegen::pagegenInit(), tslib_menu::link()
1324       */
1325  	function linkData($page,$oTarget,$no_cache,$script,$overrideArray='',$addParams='',$typeOverride='')    {
1326          global $TYPO3_CONF_VARS;
1327  
1328          $LD = Array();
1329  
1330              // Overriding some fields in the page record and still preserves the values by adding them as parameters. Little strange function.
1331          if (is_array($overrideArray))    {
1332              foreach($overrideArray as $theKey => $theNewVal)    {
1333                  $addParams.= '&real_'.$theKey.'='.rawurlencode($page[$theKey]);
1334                  $page[$theKey] = $theNewVal;
1335              }
1336          }
1337  
1338              // Adding Mount Points, "&MP=", parameter for the current page if any is set:
1339          if (!strstr($addParams,'&MP='))    {
1340              if (trim($GLOBALS['TSFE']->MP_defaults[$page['uid']]))    {    // Looking for hardcoded defaults:
1341                  $addParams.= '&MP='.rawurlencode(trim($GLOBALS['TSFE']->MP_defaults[$page['uid']]));
1342              } elseif ($GLOBALS['TSFE']->config['config']['MP_mapRootPoints']) {        // Else look in automatically created map:
1343                  $m = $this->getFromMPmap($page['uid']);
1344                  if ($m)    {
1345                      $addParams.= '&MP='.rawurlencode($m);
1346                  }
1347              }
1348          }
1349  
1350              // Setting ID/alias:
1351          if (!$script)    {$script = $GLOBALS['TSFE']->config['mainScript'];}
1352          if ($page['alias'])    {
1353              $LD['url'] = $script.'?id='.rawurlencode($page['alias']);
1354          } else {
1355              $LD['url'] = $script.'?id='.$page['uid'];
1356          }
1357              // Setting target
1358          $LD['target'] = trim($page['target']) ? trim($page['target']) : $oTarget;
1359  
1360              // typeNum
1361          $typeNum = $this->setup[$LD['target'].'.']['typeNum'];
1362          if (!t3lib_div::testInt($typeOverride) && intval($GLOBALS['TSFE']->config['config']['forceTypeValue']))    {
1363              $typeOverride = intval($GLOBALS['TSFE']->config['config']['forceTypeValue']);
1364          }
1365          if (strcmp($typeOverride,''))    { $typeNum = $typeOverride; }    // Override...
1366          if ($typeNum)    {
1367              $LD['type'] = '&type='.intval($typeNum);
1368          } else {
1369              $LD['type'] = '';
1370          }
1371          $LD['orig_type'] = $LD['type'];        // Preserving the type number. Will not be cleared if simulateStaticDocuments.
1372  
1373              // noCache
1374          $LD['no_cache'] = (trim($page['no_cache']) || $no_cache) ? '&no_cache=1' : '';
1375  
1376              // linkVars
1377          if ($GLOBALS['TSFE']->config['config']['uniqueLinkVars']) {
1378              if ($addParams) {
1379                  $LD['linkVars'] = t3lib_div::implodeArrayForUrl('',t3lib_div::explodeUrl2Array($GLOBALS['TSFE']->linkVars.$addParams));
1380              } else {
1381                  $LD['linkVars'] = $GLOBALS['TSFE']->linkVars;
1382              }
1383          } else {
1384              $LD['linkVars'] = $GLOBALS['TSFE']->linkVars.$addParams;
1385          }
1386  
1387              // If simulateStaticDocuments is enabled:
1388          if ($GLOBALS['TSFE']->config['config']['simulateStaticDocuments'])    {
1389              $LD['type'] = '';
1390              $LD['url'] = '';
1391  
1392                  // MD5/base64 method limitation:
1393              $remainLinkVars='';
1394              $flag_simulateStaticDocuments_pEnc = t3lib_div::inList('md5,base64',$GLOBALS['TSFE']->config['config']['simulateStaticDocuments_pEnc']) && !$LD['no_cache'];
1395              if ($flag_simulateStaticDocuments_pEnc)    {
1396                  list($LD['linkVars'], $remainLinkVars) = $GLOBALS['TSFE']->simulateStaticDocuments_pEnc_onlyP_proc($LD['linkVars']);
1397              }
1398  
1399              $LD['url'].=$GLOBALS['TSFE']->makeSimulFileName(
1400                              $page['title'],
1401                              $page['alias'] ? $page['alias'] : $page['uid'],
1402                              intval($typeNum),
1403                              $LD['linkVars'],
1404                              $LD['no_cache'] ? true : false
1405                          );
1406  
1407              if ($flag_simulateStaticDocuments_pEnc)    {
1408                  $LD['linkVars']=$remainLinkVars;
1409              }
1410              if ($GLOBALS['TSFE']->config['config']['simulateStaticDocuments']=='PATH_INFO')    {
1411                  $LD['url'] = str_replace('.','/',$LD['url']);
1412                  $LD['url'] = 'index.php/'.$LD['url'].'/?';
1413              } else {
1414                  $LD['url'].= '.html?';
1415              }
1416          }
1417  
1418              // Add absRefPrefix if exists.
1419          $LD['url'] = $GLOBALS['TSFE']->absRefPrefix.$LD['url'];
1420  
1421              // 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.
1422          $LD['sectionIndex'] = $page['sectionIndex_uid'] ? '#c'.$page['sectionIndex_uid'] : '';
1423  
1424              // Compile the normal total url
1425          $LD['totalURL']= $this->removeQueryString($LD['url'].$LD['type'].$LD['no_cache'].$LD['linkVars'].$GLOBALS['TSFE']->getMethodUrlIdToken).$LD['sectionIndex'];
1426  
1427              // Call post processing function for link rendering:
1428          if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tstemplate.php']['linkData-PostProc']))    {
1429              $_params = array(
1430                              'LD' => &$LD,
1431                              'args' => array('page'=>$page, 'oTarget'=>$oTarget, 'no_cache'=>$no_cache, 'script'=>$script, 'overrideArray'=>$overrideArray, 'addParams'=>$addParams, 'typeOverride'=>$typeOverride),
1432                              'typeNum' => $typeNum
1433                          );
1434              foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tstemplate.php']['linkData-PostProc'] as $_funcRef)    {
1435                  t3lib_div::callUserFunction($_funcRef,$_params,$this);
1436              }
1437          }
1438  
1439              // Return the LD-array
1440          return $LD;
1441      }
1442  
1443      /**
1444       * Initializes the automatically created MPmap coming from the "config.MP_mapRootPoints" setting
1445       * Can be called many times with overhead only the first time since then the map is generated and cached in memory.
1446       *
1447       * @param    integer        Page id to return MPvar value for.
1448       * @return    void
1449       * @see initMPmap_create()
1450       * @todo Implement some caching of the result between hits. (more than just the memory caching used here)
1451       */
1452  	function getFromMPmap($pageId=0)    {
1453  
1454              // Create map if not found already:
1455          if (!is_array($this->MPmap))    {
1456              $this->MPmap = array();
1457  
1458              $rootPoints = t3lib_div::trimExplode(',', strtolower($GLOBALS['TSFE']->config['config']['MP_mapRootPoints']),1);
1459              foreach($rootPoints as $p)    {    // Traverse rootpoints:
1460                  if ($p == 'root')    {
1461                      $p = $this->rootLine[0]['uid'];
1462                      $initMParray = array();
1463                      if ($this->rootLine[0]['_MOUNT_OL'] && $this->rootLine[0]['_MP_PARAM'])    {
1464                          $initMParray[] = $this->rootLine[0]['_MP_PARAM'];
1465                      }
1466                  }
1467                  $this->initMPmap_create($p,$initMParray);
1468              }
1469          }
1470  
1471              // Finding MP var for Page ID:
1472          if ($pageId)    {
1473              if (is_array($this->MPmap[$pageId]) && count($this->MPmap[$pageId]))    {
1474                  return implode(',',$this->MPmap[$pageId]);
1475              }
1476          }
1477      }
1478  
1479      /**
1480       * Creating MPmap for a certain ID root point.
1481       *
1482       * @param    integer        Root id from which to start map creation.
1483       * @param    array        MP_array passed from root page.
1484       * @param    integer        Recursion brake. Incremented for each recursive call. 20 is the limit.
1485       * @return    void
1486       * @see getFromMPvar()
1487       */
1488  	function initMPmap_create($id,$MP_array=array(),$level=0)    {
1489  
1490          $id = intval($id);
1491          if($id<=0)    return;
1492  
1493              // First level, check id
1494          if (!$level)    {
1495  
1496                  // Find mount point if any:
1497              $mount_info = $GLOBALS['TSFE']->sys_page->getMountPointInfo($id);
1498  
1499                  // Overlay mode:
1500              if (is_array($mount_info) && $mount_info['overlay'])    {
1501                  $MP_array[] = $mount_info['MPvar'];
1502                  $id = $mount_info['mount_pid'];
1503              }
1504  
1505                  // Set mapping information for this level:
1506              $this->MPmap[$id] = $MP_array;
1507  
1508                  // Normal mode:
1509              if (is_array($mount_info) && !$mount_info['overlay'])    {
1510                  $MP_array[] = $mount_info['MPvar'];
1511                  $id = $mount_info['mount_pid'];
1512              }
1513          }
1514  
1515          if ($id && $level<20)    {
1516  
1517              $nextLevelAcc = array();
1518  
1519                  // Select and traverse current level pages:
1520              $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1521                          'uid,pid,doktype,mount_pid,mount_pid_ol',
1522                          'pages',
1523                          'pid='.intval($id).' AND deleted=0 AND doktype!=255 AND doktype!=6'    // 255 = Garbage bin, 6 = Backend User Section
1524                      );
1525              while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))    {
1526  
1527                      // Find mount point if any:
1528                  $next_id = $row['uid'];
1529                  $next_MP_array = $MP_array;
1530                  $mount_info = $GLOBALS['TSFE']->sys_page->getMountPointInfo($next_id, $row);
1531  
1532                      // Overlay mode:
1533                  if (is_array($mount_info) && $mount_info['overlay'])    {
1534                      $next_MP_array[] = $mount_info['MPvar'];
1535                      $next_id = $mount_info['mount_pid'];
1536                  }
1537  
1538                  if (!isset($this->MPmap[$next_id]))    {
1539  
1540                          // Set mapping information for this level:
1541                      $this->MPmap[$next_id] = $next_MP_array;
1542  
1543                          // Normal mode:
1544                      if (is_array($mount_info) && !$mount_info['overlay'])    {
1545                          $next_MP_array[] = $mount_info['MPvar'];
1546                          $next_id = $mount_info['mount_pid'];
1547                      }
1548  
1549                          // Register recursive call
1550                          // (have to do it this way since ALL of the current level should be registered BEFORE the sublevel at any time)
1551                      $nextLevelAcc[] = array($next_id,$next_MP_array);
1552                  }
1553              }
1554  
1555                  // Call recursively, if any:
1556              foreach($nextLevelAcc as $pSet)    {
1557                  $this->initMPmap_create($pSet[0],$pSet[1],$level+1);
1558              }
1559          }
1560      }
1561  }
1562  
1563  
1564  if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tstemplate.php'])    {
1565      include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tstemplate.php']);
1566  }
1567  ?>


Généré le : Sun Nov 25 17:13:16 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics