TEMPORARY (remove when solved): Disable output of deprecation messages until error...
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_tstemplate.php
index 6700dd8..8101d0e 100755 (executable)
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2004 Kasper Skaarhoj (kasper@typo3.com)
+*  (c) 1999-2008 Kasper Skaarhoj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
  * $Id$
  * Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
  *
- * @author     Kasper Skaarhoj <kasper@typo3.com>
+ * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
  */
 /**
  * [CLASS/FUNCTION INDEX of SCRIPT]
  *
  *
  *
- *  107: class t3lib_TStemplate
- *  207:     function init()
- *  245:     function getCurrentPageData()
- *  262:     function matching($cc)
- *  286:     function start($theRootLine)
+ *  109: class t3lib_TStemplate
+ *  211:     function init()
+ *  249:     function getCurrentPageData()
+ *  266:     function matching($cc)
+ *  290:     function start($theRootLine)
  *
  *              SECTION: Fetching TypoScript code text for the Template Hierarchy
- *  401:     function runThroughTemplates($theRootLine,$start_template_uid=0)
- *  447:     function processTemplate($row, $idList,$pid,$templateID='',$templateParent='')
- *  560:     function includeStaticTypoScriptSources($idList,$templateID,$pid,$row)
- *  621:     function addExtensionStatics($idList,$templateID,$pid,$row)
- *  654:     function prependStaticExtra($subrow)
+ *  406:     function runThroughTemplates($theRootLine,$start_template_uid=0)
+ *  459:     function processTemplate($row, $idList,$pid,$templateID='',$templateParent='')
+ *  580:     function includeStaticTypoScriptSources($idList,$templateID,$pid,$row)
+ *  642:     function addExtensionStatics($idList,$templateID,$pid,$row)
+ *  675:     function prependStaticExtra($subrow)
+ *  688:     function versionOL(&$row)
  *
  *              SECTION: Parsing TypoScript code text from Template Records into PHP array
- *  690:     function generateConfig()
- *  853:     function procesIncludes()
- *  877:     function mergeConstantsFromPageTSconfig($constArray)
- *  906:     function flattenSetup($setupArray, $prefix, $resourceFlag)
- *  930:     function substituteConstants($all)
+ *  725:     function generateConfig()
+ *  891:     function procesIncludes()
+ *  915:     function mergeConstantsFromPageTSconfig($constArray)
+ *  944:     function flattenSetup($setupArray, $prefix, $resourceFlag)
+ *  968:     function substituteConstants($all)
+ *  991:     function substituteConstantsCallBack($matches)
  *
  *              SECTION: Various API functions, used from elsewhere in the frontend classes
- *  968:     function splitConfArray($conf,$splitCount)
- * 1045:     function getFileName($fileFromSetup)
- * 1102:     function extractFromResources($res,$file)
- * 1130:     function checkFile($name,$menuArr)
- * 1147:     function printTitle($title,$no_title=0,$titleFirst=0)
- * 1170:     function fileContent($fName)
- * 1190:     function wrap($content,$wrap)
- * 1204:     function removeQueryString($url)
- * 1220:     function sortedKeyList($setupArr)
+ * 1022:     function splitConfArray($conf,$splitCount)
+ * 1099:     function getFileName($fileFromSetup)
+ * 1156:     function extractFromResources($res,$file)
+ * 1184:     function checkFile($name,$menuArr)
+ * 1201:     function printTitle($title,$no_title=0,$titleFirst=0)
+ * 1224:     function fileContent($fName)
+ * 1244:     function wrap($content,$wrap)
+ * 1258:     function removeQueryString($url)
+ * 1275:     function sortedKeyList($setupArr, $acceptOnlyProperties=FALSE)
  *
  *              SECTION: Functions for creating links
- * 1264:     function linkData($page,$oTarget,$no_cache,$script,$overrideArray='',$addParams='',$typeOverride='')
- * 1383:     function getFromMPmap($pageId=0)
- * 1419:     function initMPmap_create($id,$MP_array=array(),$level=0)
+ * 1322:     function linkData($page,$oTarget,$no_cache,$script,$overrideArray='',$addParams='',$typeOverride='')
+ * 1449:     function getFromMPmap($pageId=0)
+ * 1485:     function initMPmap_create($id,$MP_array=array(),$level=0)
  *
- * TOTAL FUNCTIONS: 26
+ * TOTAL FUNCTIONS: 28
  * (This index is automatically created/updated by the extension "extdeveval")
  *
  */
@@ -99,7 +101,7 @@ require_once (PATH_t3lib.'class.t3lib_matchcondition.php');
 /**
  * Template object that is responsible for generating the TypoScript template based on template records.
  *
- * @author     Kasper Skaarhoj <kasper@typo3.com>
+ * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage t3lib
  * @see        t3lib_tsparser.php, t3lib_matchcondition.php
@@ -121,6 +123,8 @@ class t3lib_TStemplate      {
        var $ext_constants_BRP=0;
        var $ext_config_BRP=0;
        var $ext_editorcfg_BRP=0;
+       var $ext_regLinenumbers=false;
+       var $ext_regComments=false;
 
                // Constants:
        var $uplPath = 'uploads/tf/';
@@ -131,7 +135,6 @@ class t3lib_TStemplate      {
        var $whereClause = '';                          // This MUST be initialized by the init() function
        var $debug = 0;
        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.
-       var $currentPageData = '';                      // Contains "currentPageData" when rendered/fetched from cache. See getCurrentPageData()
        var $simulationHiddenOrTime=0;          // See init(); Set if preview of some kind is enabled.
 
        var $loaded = 0;                                        // Set, if the TypoScript template structure is loaded and OK, see ->start()
@@ -150,7 +153,8 @@ class t3lib_TStemplate      {
                'config.' => Array (
                        'extTarget' => '_top',
                        'stat' => 1,
-                       'stat_typeNumList' => '0,1'
+                       'stat_typeNumList' => '0,1',
+                       'uniqueLinkVars' => 1
                )
        );
        var $flatSetup = Array (
@@ -171,6 +175,7 @@ class t3lib_TStemplate      {
        var $editorcfg = array();                       // Backend Editor Configuration field
 
        var $hierarchyInfo = array();           // For Template Analyser in backend
+       var $hierarchyInfoToRoot = array();             // For Template Analyser in backend (setup content only)
        var $nextLevel=0;                                       // Next-level flag (see runThroughTemplates())
        var $rootId;                                            // The Page UID of the root page
        var $rootLine;                                          // The rootline from current page to the root page
@@ -205,25 +210,35 @@ class t3lib_TStemplate    {
         * @see tslib_fe::initTemplate()
         */
        function init() {
-                       // $this->whereClause is used only to select templates from sys_template.
-                       // $GLOBALS['SIM_EXEC_TIME'] is used so that we're able to simulate a later time as a test...
+                       // $this->whereClause is used only to select templates from sys_template.
+                       // $GLOBALS['SIM_ACCESS_TIME'] is used so that we're able to simulate a later time as a test...
                $this->whereClause='AND deleted=0 ';
                if (!$GLOBALS['TSFE']->showHiddenRecords)       {
                        $this->whereClause.='AND hidden=0 ';
                }
-               if ($GLOBALS['TSFE']->showHiddenRecords || $GLOBALS['SIM_EXEC_TIME']!=$GLOBALS['EXEC_TIME'])    {       // Set the simulation flag, if simulation is detected!
+               if ($GLOBALS['TSFE']->showHiddenRecords || $GLOBALS['SIM_ACCESS_TIME']!=$GLOBALS['ACCESS_TIME'])        {       // Set the simulation flag, if simulation is detected!
                        $this->simulationHiddenOrTime=1;
                }
-               $this->whereClause.= 'AND (starttime<='.$GLOBALS['SIM_EXEC_TIME'].') AND (endtime=0 OR endtime>'.$GLOBALS['SIM_EXEC_TIME'].')';
+               $this->whereClause.= 'AND (starttime<='.$GLOBALS['SIM_ACCESS_TIME'].') AND (endtime=0 OR endtime>'.$GLOBALS['SIM_ACCESS_TIME'].')';
                if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'])       {
                        $this->menuclasses='tmenu,jsmenu,gmenu';
                }
 
                        // Sets the paths from where TypoScript resources are allowed to be used:
-               $this->allowedPaths = Array ('media/','fileadmin/','uploads/','typo3temp/','t3lib/fonts/',TYPO3_mainDir.'ext/',TYPO3_mainDir.'sysext/','typo3conf/ext/');
+               $this->allowedPaths = Array(
+                       'media/',
+                       'fileadmin/',
+                       'uploads/',
+                       'typo3temp/',
+                       't3lib/fonts/',
+                       TYPO3_mainDir . 'ext/',
+                       TYPO3_mainDir . 'sysext/',
+                       TYPO3_mainDir . 'contrib/',
+                       'typo3conf/ext/'
+               );
                if ($GLOBALS['TYPO3_CONF_VARS']['FE']['addAllowedPaths'])       {
-                       $pathArr = t3lib_div::trimExplode(',',$GLOBALS['TYPO3_CONF_VARS']['FE']['addAllowedPaths'],1);
-                       while(list(,$p)=each($pathArr)) {
+                       $pathArr = t3lib_div::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['addAllowedPaths'], true);
+                       foreach ($pathArr as $p) {
                                        // 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.
                                $this->allowedPaths[] = $p;
                        }
@@ -234,37 +249,47 @@ class t3lib_TStemplate    {
         * Fetches the "currentPageData" array from cache
         *
         * NOTE about currentPageData:
-        * It holds information about the TypoScript conditions along with the list of template uid's which is used on the page.
-        * In the getFromCache function in TSFE, currentPageData is used to evaluate if there is a template and if the matching conditions are alright
-        * 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.
-        * 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
+        * It holds information about the TypoScript conditions along with the list
+        * of template uid's which is used on the page. In the getFromCache function
+        * in TSFE, currentPageData is used to evaluate if there is a template and
+        * if the matching conditions are alright. 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. 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.
         *
-        * @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
-        * @see start(), t3lib_fe::getFromCache()
+        * @return      array           Returns the unmatched array $currentPageData if found cached in "cache_pagesection". Otherwise false is returned which means that the array must be generated and stored in the cache-table
+        * @see start(), tslib_fe::getFromCache()
         */
-       function getCurrentPageData()   {
-               $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('content', 'cache_pagesection', 'page_id='.intval($GLOBALS['TSFE']->id).' AND mpvar_hash='.t3lib_div::md5int($GLOBALS['TSFE']->MP));
-               if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
-                       $this->currentPageData = unserialize($row['content']);
-               } else {
-                       $this->currentPageData = 'none';
+       function getCurrentPageData() {
+               $currentPageData = false;
+               $pageSectionCache = $GLOBALS['typo3CacheManager']->getCache('cache_pagesection');
+               /* @var $pageSectionCache t3lib_cache_AbstractCache */
+
+               $cacheEntry = $pageSectionCache->get(
+                       intval($GLOBALS['TSFE']->id) . '_' . t3lib_div::md5int($GLOBALS['TSFE']->MP)
+               );
+
+               if ($cacheEntry) {
+                       $currentPageData = unserialize($cacheEntry);
                }
-               return $this->currentPageData;
+
+               return $currentPageData;        // 2008-02-03 / Stucki: Notice that $this->currentPageData is not used anymore!
        }
 
        /**
         * Fetches data about which TypoScript-matches there are at this page. Then it performs a matchingtest.
         *
-        * @param       array           An array with three keys, "all", "rowSum" and "rootLine" - all coming from the $this->currentPageData array
+        * @param       array           An array with three keys, "all", "rowSum" and "rootLine" - all coming from the "currentPageData" array
         * @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.
-        * @see t3lib_matchCondition, t3lib_fe::getFromCache()
+        * @see t3lib_matchCondition, tslib_fe::getFromCache()
         */
        function matching($cc)  {
                if (is_array($cc['all']))       {
-                       reset($cc['all']);
                        $matchObj = t3lib_div::makeInstance('t3lib_matchCondition');
                        $matchObj->altRootLine=$cc['rootLine'];
-                       while(list($key,$pre)=each($cc['all'])) {
+                       foreach ($cc['all'] as $key => $pre) {
                                if ($matchObj->match($pre))     {
                                        $sectionsMatch[$key]=$pre;
                                }
@@ -276,54 +301,73 @@ class t3lib_TStemplate    {
 
        /**
         * This is all about fetching the right TypoScript template structure. If it's not cached then it must be generated and cached!
-        * 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.
-        * Sets $this->setup to the parsed TypoScript Template array
+        * The method traverses 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.
+        * Sets $this->setup to the parsed TypoScript template array
         *
         * @param       array           The rootline of the current page (going ALL the way to tree root)
         * @return      void
         * @see tslib_fe::getConfigArray()
         */
        function start($theRootLine)    {
-               if (is_array($theRootLine))     {
-                       $setupData='';
-                       $cc=Array();
-                       $hash='';
+               if (is_array($theRootLine)) {
+                       $setupData = '';
+                       $hash = '';
+
+                               // Flag that indicates that the existing data in cache_pagesection
+                               // could be used (this is the case if $TSFE->all is set, and the
+                               // rowSum still matches). Based on this we decide if cache_pagesection
+                               // needs to be updated...
+                       $isCached = false;
+
                        $this->runThroughTemplates($theRootLine);
 
-                               // Getting the currentPageData if not already found
-                       if (!$this->currentPageData)    {
-                               $this->getCurrentPageData();
+                       if ($GLOBALS['TSFE']->all) {
+                               $cc = $GLOBALS['TSFE']->all;
+
+                                       // The two rowSums must NOT be different from each other - which they will be if start/endtime or hidden has changed!
+                               if (strcmp(serialize($this->rowSum),serialize($cc['rowSum']))) {
+                                       unset($cc);     // If the two rowSums differ, we need to re-make the current page data and therefore clear the existing values.
+                               } else {
+                                               // If $TSFE->all contains valid data, we don't need to update cache_pagesection (because this data was fetched from there already)
+                                       if (!strcmp(serialize($this->rootLine), serialize($cc['rootLine']))) {
+                                               $isCached = true;
+                                       }
+                                               // When the data is serialized below (ROWSUM hash), it must not contain the rootline by concept. So this must be removed (and added again later)...
+                                       unset($cc['rootLine']);
+                               }
                        }
 
                                // This is about getting the hash string which is used to fetch the cached TypoScript template.
-                               // If there was some cached currentPageData that's good (it gives us the hash),
-                               // 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.
-                       if (is_array($this->currentPageData) &&
-                               !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!
-                       )       {
-                                       // If currentPageData was actually there, we match the result...
-                               $cc['all'] = $this->currentPageData['all'];
-                               $cc['rowSum'] = $this->currentPageData['rowSum'];
-                               $cc = $this->matching($cc);
+                               // If there was some cached currentPageData ($cc) then that's good (it gives us the hash).
+                       if (is_array($cc)) {
+                                       // If currentPageData was actually there, we match the result (if this wasn't done already in $TSFE->getFromCache()...)
+                               if (!$cc['match']) {
+                                               // TODO: check if this can ever be the case - otherwise remove
+                                       $cc = $this->matching($cc);
+                                       ksort($cc);
+                               }
                                $hash = md5(serialize($cc));
                        } else {
-                                       // 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
+                                       // If currentPageData was not there, we first find $rowSum (freshly generated). After that we try to see, if it is stored with a list of all conditions. If so we match the result.
                                $rowSumHash = md5('ROWSUM:'.serialize($this->rowSum));
-                               $result = t3lib_pageSelect::getHash($rowSumHash, 0);
-                               if ($result)    {
+                               $result = t3lib_pageSelect::getHash($rowSumHash);
+
+                               if ($result) {
+                                       $cc = array();
                                        $cc['all'] = unserialize($result);
                                        $cc['rowSum'] = $this->rowSum;
                                        $cc = $this->matching($cc);
+                                       ksort($cc);
                                        $hash = md5(serialize($cc));
                                }
                        }
 
-                       if ($hash)      {
+                       if ($hash) {
                                        // Get TypoScript setup array
-                               $setupData = t3lib_pageSelect::getHash($hash, 0);
+                               $setupData = t3lib_pageSelect::getHash($hash);
                        }
 
-                       if ($hash && $setupData && !$this->forceTemplateParsing)                {
+                       if ($setupData && !$this->forceTemplateParsing) {
                                        // If TypoScript setup structure was cached we unserialize it here:
                                $this->setup = unserialize($setupData);
                        } else {
@@ -331,35 +375,47 @@ class t3lib_TStemplate    {
                                $this->generateConfig();
 
                                        // This stores the template hash thing
-                               $cc=Array();
-                               $cc['all']=$this->sections;     // All sections in the template at this point is found
-                               $cc['rowSum']=$this->rowSum;    // The line of templates is collected
+                               $cc = array();
+                               $cc['all'] = $this->sections;   // All sections in the template at this point is found
+                               $cc['rowSum'] = $this->rowSum;  // The line of templates is collected
                                $cc = $this->matching($cc);
+                               ksort($cc);
 
                                $hash = md5(serialize($cc));
 
                                        // This stores the data.
-                               t3lib_pageSelect::storeHash($hash, serialize($this->setup), 'TS TEMPLATE');
+                               t3lib_pageSelect::storeHash($hash, serialize($this->setup), 'TS_TEMPLATE');
 
                                if ($this->tt_track)    $GLOBALS['TT']->setTSlogMessage('TS template size, serialized: '.strlen(serialize($this->setup)).' bytes');
 
                                $rowSumHash = md5('ROWSUM:'.serialize($this->rowSum));
-                               t3lib_pageSelect::storeHash($rowSumHash, serialize($cc['all']), 'TMPL CONDITIONS - ALL');
+                               t3lib_pageSelect::storeHash($rowSumHash, serialize($cc['all']), 'TMPL_CONDITIONS_ALL');
                        }
                                // Add rootLine
                        $cc['rootLine'] = $this->rootLine;
-                               // Make global and save.
-                       $GLOBALS['TSFE']->all=$cc;
-
-                       if (!$this->simulationHiddenOrTime)     {       // Only save currentPageData, if we're not simulating by hidden/starttime/endtime
-                               $insertFields = array(
-                                       'page_id' => intval($GLOBALS['TSFE']->id),
-                                       'mpvar_hash' => t3lib_div::md5int($GLOBALS['TSFE']->MP),
-                                       'content' => serialize($cc),
-                                       'tstamp' => $GLOBALS['EXEC_TIME']
+                       ksort($cc);
+
+                               // Make global and save
+                       $GLOBALS['TSFE']->all = $cc;
+
+                               // Matching must be executed for every request, so this must never be part of the pagesection cache!
+                       unset($cc['match']);
+
+                       if (!$isCached && !$this->simulationHiddenOrTime && !$GLOBALS['TSFE']->no_cache) {      // Only save the data if we're not simulating by hidden/starttime/endtime
+                               $pageSectionCache = $GLOBALS['typo3CacheManager']->getCache('cache_pagesection');
+                               /* @var $pageSectionCache t3lib_cache_AbstractCache */
+
+                               $mpvarHash = t3lib_div::md5int($GLOBALS['TSFE']->MP);
+
+                               $pageSectionCache->set(
+                                       intval($GLOBALS['TSFE']->id) . '_' . $mpvarHash,
+                                       serialize($cc),
+                                       array(
+                                               'pageId_' . intval($GLOBALS['TSFE']->id),
+                                               'mpvarHash_' . $mpvarHash
+                                       )
                                );
-                               $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pagesection', 'page_id='.intval($GLOBALS['TSFE']->id).' AND mpvar_hash='.t3lib_div::md5int($GLOBALS['TSFE']->MP));
-                               $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_pagesection', $insertFields);
+
                        }
                                // If everything OK.
                        if ($this->rootId && $this->rootLine && $this->setup)   {
@@ -403,6 +459,7 @@ class t3lib_TStemplate      {
                $this->config = Array();
                $this->editorcfg = Array();
                $this->rowSum = Array();
+               $this->hierarchyInfoToRoot = Array();
                $this->absoluteRootLine=$theRootLine;   // Is the TOTAL rootline
 
                reset ($this->absoluteRootLine);
@@ -412,8 +469,11 @@ class t3lib_TStemplate     {
                                $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'uid='.intval($this->nextLevel).' '.$this->whereClause);
                                $this->nextLevel = 0;
                                if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
-                                       $this->processTemplate($row,'sys_'.$row['uid'],$this->absoluteRootLine[$a]['uid'],'sys_'.$row['uid']);
-                                       $this->outermostRootlineIndexWithTemplate=$a;
+                                       $this->versionOL($row);
+                                       if (is_array($row))     {
+                                               $this->processTemplate($row,'sys_'.$row['uid'],$this->absoluteRootLine[$a]['uid'],'sys_'.$row['uid']);
+                                               $this->outermostRootlineIndexWithTemplate=$a;
+                                       }
                                }
                                $GLOBALS['TYPO3_DB']->sql_free_result($res);
                        }
@@ -424,8 +484,11 @@ class t3lib_TStemplate     {
 
                        $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'pid='.intval($this->absoluteRootLine[$a]['uid']).$addC.' '.$this->whereClause,'','sorting',1);
                        if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
-                               $this->processTemplate($row,'sys_'.$row['uid'],$this->absoluteRootLine[$a]['uid'],'sys_'.$row['uid']);
-                               $this->outermostRootlineIndexWithTemplate=$a;
+                               $this->versionOL($row);
+                               if (is_array($row))     {
+                                       $this->processTemplate($row,'sys_'.$row['uid'],$this->absoluteRootLine[$a]['uid'],'sys_'.$row['uid']);
+                                       $this->outermostRootlineIndexWithTemplate=$a;
+                               }
                        }
                        $GLOBALS['TYPO3_DB']->sql_free_result($res);
                        $this->rootLine[] = $this->absoluteRootLine[$a];
@@ -458,6 +521,7 @@ class t3lib_TStemplate      {
                        }
                        if ($clConf)    {
                                $this->config = Array();
+                               $this->hierarchyInfoToRoot = Array();
                                $this->clearList_setup=array();
 
                                $this->editorcfg = Array();
@@ -472,7 +536,7 @@ class t3lib_TStemplate      {
 
                        // Include "Based On" sys_templates:
                if (trim($row['basedOn']))      {               // 'basedOn' is a list of templates to include
-                               // Manually you can put this value in the field and then the based_on ID will be taken from the HTTP_GET_VARS var defined by '=....'.
+                               // Manually you can put this value in the field and then the based_on ID will be taken from the $_GET var defined by '=....'.
                                // 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!
                                // 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.
                        $basedOn_hackFeature = explode('=',$row['basedOn']);
@@ -481,17 +545,23 @@ class t3lib_TStemplate    {
                                if ($id && !t3lib_div::inList($idList,'sys_'.$id))      {       // if $id is not allready included ...
                                        $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'uid='.$id.' '.$this->whereClause);
                                        if ($subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {       // there was a template, then we fetch that
-                                               $this->processTemplate($subrow,$idList.',sys_'.$id,$pid, 'sys_'.$id,$templateID);
+                                               $this->versionOL($subrow);
+                                               if (is_array($subrow))  {
+                                                       $this->processTemplate($subrow,$idList.',sys_'.$id,$pid, 'sys_'.$id,$templateID);
+                                               }
                                        }
                                        $GLOBALS['TYPO3_DB']->sql_free_result($res);
                                }
                        } else {        // NORMAL OPERATION:
-                               $basedOnArr = t3lib_div::intExplode(',',$row['basedOn']);
-                               while(list(,$id)=each($basedOnArr))     {       // traversing list
+                               $basedOnArr = t3lib_div::intExplode(',', $row['basedOn']);
+                               foreach ($basedOnArr as $id) { // traversing list
                                        if (!t3lib_div::inList($idList,'sys_'.$id))     {       // if $id is not allready included ...
                                                $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_template', 'uid='.intval($id).' '.$this->whereClause);
                                                if ($subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {       // there was a template, then we fetch that
-                                                       $this->processTemplate($subrow,$idList.',sys_'.$id,$pid, 'sys_'.$id,$templateID);
+                                                       $this->versionOL($subrow);
+                                                       if (is_array($subrow))  {
+                                                               $this->processTemplate($subrow,$idList.',sys_'.$id,$pid, 'sys_'.$id,$templateID);
+                                                       }
                                                }
                                                $GLOBALS['TYPO3_DB']->sql_free_result($res);
                                        }
@@ -505,7 +575,7 @@ class t3lib_TStemplate      {
                }
 
                        // Creating hierarchy information; Used by backend analysis tools
-               $this->hierarchyInfo[] = array(
+               $this->hierarchyInfo[] = $this->hierarchyInfoToRoot[] = array(
                        'root'=>trim($row['root']),
                        'next'=>$row['nextLevel'],
                        'clConst'=>$clConst,
@@ -514,7 +584,8 @@ class t3lib_TStemplate      {
                        'templateParent'=>$templateParent,
                        'title'=>$row['title'],
                        'uid'=>$row['uid'],
-                       'pid'=>$row['pid']
+                       'pid'=>$row['pid'],
+                       'configLines' => substr_count($row['config'], chr(10))+1
                );
 
                        // Adding the content of the fields constants (Constants), config (Setup) and editorcfg (Backend Editor Configuration) to the internal arrays.
@@ -560,9 +631,8 @@ class t3lib_TStemplate      {
        function includeStaticTypoScriptSources($idList,$templateID,$pid,$row)  {
                        // Static Template Records (static_template): include_static is a list of static templates to include
                if (trim($row['include_static']))       {
-                       $include_staticArr = t3lib_div::intExplode(',',$row['include_static']);
-                       reset($include_staticArr);
-                       while(list(,$id)=each($include_staticArr))      {       // traversing list
+                       $include_staticArr = t3lib_div::intExplode(',', $row['include_static']);
+                       foreach ($include_staticArr as $id) { // traversing list
                                if (!t3lib_div::inList($idList,'static_'.$id))  {       // if $id is not allready included ...
                                        $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'static_template', 'uid='.intval($id));
                                        if ($subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {       // there was a template, then we fetch that
@@ -576,10 +646,8 @@ class t3lib_TStemplate     {
 
                        // Static Template Files (Text files from extensions): include_static_file is a list of static files to include (from extensions)
                if (trim($row['include_static_file']))  {
-                       $include_static_fileArr = t3lib_div::trimExplode(',',$row['include_static_file'],1);
-                       reset($include_static_fileArr);
-                       while(list(,$ISF_file)=each($include_static_fileArr))   {       // traversing list
-                               $ISF_file = trim($ISF_file);
+                       $include_static_fileArr = t3lib_div::trimExplode(',', $row['include_static_file'], true);
+                       foreach ($include_static_fileArr as $ISF_file) { // traversing list
                                if (substr($ISF_file,0,4)=='EXT:')      {
                                        list($ISF_extKey,$ISF_localPath) = explode('/',substr($ISF_file,4),2);
                                        if (strcmp($ISF_extKey,'') && t3lib_extMgm::isLoaded($ISF_extKey) && strcmp($ISF_localPath,'')) {
@@ -592,6 +660,7 @@ class t3lib_TStemplate      {
                                                                'config'=>              @is_file($ISF_filePath.'setup.txt')             ?t3lib_div::getUrl($ISF_filePath.'setup.txt'):'',
                                                                'editorcfg'=>   @is_file($ISF_filePath.'editorcfg.txt') ?t3lib_div::getUrl($ISF_filePath.'editorcfg.txt'):'',
                                                                'include_static'=>      @is_file($ISF_filePath.'include_static.txt')?implode(',',array_unique(t3lib_div::intExplode(',',t3lib_div::getUrl($ISF_filePath.'include_static.txt')))):'',
+                                                               'include_static_file'=> @is_file($ISF_filePath.'include_static_file.txt')?implode(',',array_unique(explode(',',t3lib_div::getUrl($ISF_filePath.'include_static_file.txt')))):'',
                                                                'title' =>              $ISF_file,
                                                                'uid' =>                $mExtKey
                                                        );
@@ -622,8 +691,7 @@ class t3lib_TStemplate      {
                global $TYPO3_LOADED_EXT;
 
                if ($row['static_file_mode']==1 || ($row['static_file_mode']==0 && substr($templateID,0,4)=='sys_' && $row['root']))    {
-                       reset($TYPO3_LOADED_EXT);
-                       while(list($extKey,$files)=each($TYPO3_LOADED_EXT))     {
+                       foreach ($TYPO3_LOADED_EXT as $extKey => $files) {
                                if (is_array($files) && ($files['ext_typoscript_constants.txt'] || $files['ext_typoscript_setup.txt'] || $files['ext_typoscript_editorcfg.txt']))       {
                                        $mExtKey = str_replace('_','',$extKey);
                                        $subrow=array(
@@ -658,6 +726,20 @@ class t3lib_TStemplate     {
                return $subrow;
        }
 
+       /**
+        * Creating versioning overlay of a sys_template record. This will use either frontend or backend overlay functionality depending on environment.
+        *
+        * @param       array           Row to overlay.
+        * @return      void            Row is passed by reference.
+        */
+       function versionOL(&$row)       {
+               if (is_object($GLOBALS['TSFE']))        {       // Frontend:
+                       $GLOBALS['TSFE']->sys_page->versionOL('sys_template',$row);
+               } else {        // Backend:
+                       t3lib_BEfunc::workspaceOL('sys_template',$row);
+               }
+       }
+
 
 
 
@@ -734,7 +816,9 @@ class t3lib_TStemplate      {
                // ***********************************************
                        // Initialize parser and match-condition classes:
                $config = t3lib_div::makeInstance('t3lib_TSparser');
-               $config->breakPointLN=intval($this->ext_config_BRP);
+               $config->breakPointLN = intval($this->ext_config_BRP);
+               $config->regLinenumbers = $this->ext_regLinenumbers;
+               $config->regComments = $this->ext_regComments;
                $config->setup = $this->setup;
 
                        // Transfer information about conditions found in "Constants" and which of them returned true.
@@ -754,14 +838,14 @@ class t3lib_TStemplate    {
 
                        // Searching for possible unsubstituted constants left (only for information)
                if (strstr($all,'{$'))  {
-                       $findConst = explode('{$',$all);
-                       $theConstList=Array();
-                       next($findConst);
-                       while(list(,$constVal)=each($findConst))        {
+                       $theConstList = array();
+                       $findConst = explode('{$', $all);
+                       array_shift($findConst);
+                       foreach ($findConst as $constVal) {
                                $constLen=t3lib_div::intInRange(strcspn($constVal,'}'),0,50);
                                $theConstList[]='{$'.substr($constVal,0,$constLen+1);
                        }
-                       if ($this->tt_track)    $GLOBALS['TT']->setTSlogMessage(implode($theConstList,',').': Constants may remain un-substituted!!',2);
+                       if ($this->tt_track)    $GLOBALS['TT']->setTSlogMessage(implode(', ',$theConstList).': Constants may remain un-substituted!!',2);
                }
 
                        // Logging the textual size of the TypoScript Setup field text with all constants substituted:
@@ -824,12 +908,15 @@ class t3lib_TStemplate    {
                unset($this->setup['types.']);
                unset($this->setup['types']);
                if (is_array($this->setup)) {
-                       reset ($this->setup);
-                       while(list($theKey,)=each($this->setup))        {
-                               if ($this->setup[$theKey]=='PAGE')      {
-                                       $tN = $this->setup[$theKey.'.']['typeNum'];
-                                       if (isset($tN)) {
-                                               $this->setup['types.'][$tN] = $theKey;
+                       foreach ($this->setup as $key => $value) {
+                               if ($value=='PAGE')     {
+                                               // Set the typeNum of the current page object:
+                                       if (isset($this->setup[$key.'.']['typeNum'])) {
+                                               $typeNum = $this->setup[$key.'.']['typeNum'];
+                                               $this->setup['types.'][$typeNum] = $key;
+                                               // If there is no type 0 yet and typeNum was not set, we use the current object as the default
+                                       } elseif(!isset($this->setup['types.'][0]) || !$this->setup['types.'][0]) {
+                                               $this->setup['types.'][0] = $key;
                                        }
                                }
                        }
@@ -850,20 +937,17 @@ class t3lib_TStemplate    {
         * @return      void
         * @see t3lib_TSparser, generateConfig()
         */
-       function procesIncludes()       {
-               reset($this->constants);
-               while(list($k)=each($this->constants))  {
-                       $this->constants[$k]=t3lib_TSparser::checkIncludeLines($this->constants[$k]);
+       function procesIncludes() {
+               foreach ($this->constants as &$value) {
+                       $value = t3lib_TSparser::checkIncludeLines($value);
                }
 
-               reset($this->config);
-               while(list($k)=each($this->config))     {
-                       $this->config[$k]=t3lib_TSparser::checkIncludeLines($this->config[$k]);
+               foreach ($this->config as &$value) {
+                       $value = t3lib_TSparser::checkIncludeLines($value);
                }
 
-               reset($this->editorcfg);
-               while(list($k)=each($this->editorcfg))  {
-                       $this->editorcfg[$k]=t3lib_TSparser::checkIncludeLines($this->editorcfg[$k]);
+               foreach ($this->editorcfg as &$value) {
+                       $value = t3lib_TSparser::checkIncludeLines($value);
                }
        }
 
@@ -883,7 +967,7 @@ class t3lib_TStemplate      {
                }
                        // Parsing the user TS (or getting from cache)
                $TSdataArray = t3lib_TSparser::checkIncludeLines_array($TSdataArray);
-               $userTS = implode($TSdataArray,chr(10).'[GLOBAL]'.chr(10));
+               $userTS = implode(chr(10).'[GLOBAL]'.chr(10),$TSdataArray);
 
                $parseObj = t3lib_div::makeInstance('t3lib_TSparser');
                $parseObj->parse($userTS);
@@ -905,8 +989,7 @@ class t3lib_TStemplate      {
         */
        function flattenSetup($setupArray, $prefix, $resourceFlag)      {
                if (is_array($setupArray))      {
-                       reset($setupArray);
-                       while(list($key,$val)=each($setupArray))        {
+                       foreach ($setupArray as $key => $val) {
                                if ($prefix || substr($key,0,16)!='TSConstantEditor')   {               // We don't want 'TSConstantEditor' in the flattend setup on the first level (190201)
                                        if (is_array($val))     {
                                                $this->flattenSetup($val,$prefix.$key, ($key=='file.'));
@@ -929,15 +1012,31 @@ class t3lib_TStemplate   {
         */
        function substituteConstants($all)      {
                if ($this->tt_track)    $GLOBALS['TT']->setTSlogMessage('Constants to substitute: '.count($this->flatSetup));
-               reset($this->flatSetup);
-               while (list($const,$val)=each($this->flatSetup))        {
-                       if (!is_array($val))    {
-                               $all = str_replace('{$'.$const.'}',$val,$all);
+
+               $noChange = false;
+               // recursive substitution of constants (up to 10 nested levels)
+               for ($i = 0; $i < 10 && !$noChange; $i++) {
+                       $old_all = $all;
+                       $all = preg_replace_callback('/\{\$(.[^}]*)\}/', array($this, 'substituteConstantsCallBack'), $all);
+                       if ($old_all == $all) {
+                               $noChange = true;
                        }
                }
+
                return $all;
        }
 
+       /**
+        * Call back method for preg_replace_callback in substituteConstants
+        *
+        * @param       array           Regular expression matches
+        * @return      string          Replacement
+        * @see substituteConstants()
+        */
+       function substituteConstantsCallBack($matches) {
+               // replace {$CONST} if found in $this->flatSetup, else leave unchanged
+               return isset($this->flatSetup[$matches[1]]) && !is_array($this->flatSetup[$matches[1]]) ? $this->flatSetup[$matches[1]] : $matches[0];
+       }
 
 
 
@@ -1044,7 +1143,12 @@ class t3lib_TStemplate   {
         */
        function getFileName($fileFromSetup)    {
                $file = trim($fileFromSetup);
-               if (!$file)     return;
+               if (!$file)     {
+                       return;
+               } elseif (strstr($file,'../'))  {
+                       if ($this->tt_track)    $GLOBALS['TT']->setTSlogMessage('File path "'.$file.'" contained illegal string "../"!',3);
+                       return;
+               }
                        // cache
                $hash = md5($file);
                if (isset($this->fileCache[$hash]))     {
@@ -1066,18 +1170,21 @@ class t3lib_TStemplate  {
 
                        // find
                if (strstr($file,'/')) {        // here it is manual media
+                       if(!strcmp(substr($file,0,6),'media/')) $file = 'typo3/sysext/cms/tslib/'.$file;
                        if (@is_file($this->getFileName_backPath.$file))        {
                                $outFile = $file;
                                $fileInfo = t3lib_div::split_fileref($outFile);
-                               reset($this->allowedPaths);
                                $OK=0;
-                               while(list(,$val)=each($this->allowedPaths))    {
-                                       if (substr($fileInfo['path'],0,strlen($val))==$val){$OK=1; break;}
+                               foreach ($this->allowedPaths as $val) {
+                                       if (substr($fileInfo['path'], 0, strlen($val))==$val) {
+                                               $OK=1;
+                                               break;
+                                       }
                                }
                                if ($OK)        {
                                        $this->fileCache[$hash]=$outFile;
                                        return $outFile;
-                               } elseif ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('"'.$file.'" was not located in the allowed paths: ('.implode($this->allowedPaths,',').')',3);
+                               } elseif ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('"'.$file.'" was not located in the allowed paths: ('.implode(',',$this->allowedPaths).')',3);
                        } elseif ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('"'.$this->getFileName_backPath.$file.'" is not a file (non-uploads/.. resource, did not exist).',3);
                } else {                // Here it is uploaded media:
                        $outFile = $this->extractFromResources($this->setup['resources'],$file);
@@ -1105,11 +1212,10 @@ class t3lib_TStemplate  {
                } elseif (strstr($file,'*')) {
                        $fileparts=explode('*',$file);
                        $c=count($fileparts);
-                       $files = explode(',',$res);
-                       while(list(,$val)=each($files)) {
-                               $test = trim($val);
-                               if (ereg('^'.quotemeta($fileparts[0]).'.*'.quotemeta($fileparts[$c-1]).'$', $test))     {
-                                       $outFile = $test;
+                       $files = t3lib_div::trimExplode(',', $res);
+                       foreach ($files as $file) {
+                               if (ereg('^'.quotemeta($fileparts[0]).'.*'.quotemeta($fileparts[$c-1]).'$', $file)) {
+                                       $outFile = $file;
                                        break;
                                }
                        }
@@ -1124,7 +1230,7 @@ class t3lib_TStemplate    {
         * @param       string          Property name in the menu array
         * @param       array           Menu array to traverse
         * @return      array           Modified menu array
-        * @depreciated
+        * @deprecated since TYPO3 3.6
         * @internal
         */
        function checkFile($name,$menuArr)      {
@@ -1161,7 +1267,7 @@ class t3lib_TStemplate    {
 
        /**
         * Reads the fileContent of $fName and returns it.
-        * The same as t3lib_div::getUrl()
+        * Similar to t3lib_div::getUrl()
         *
         * @param       string          Absolute filepath to record
         * @return      string          The content returned
@@ -1169,13 +1275,8 @@ class t3lib_TStemplate   {
         */
        function fileContent($fName)    {
                $incFile = $this->getFileName($fName);
-               if ($incFile && $fd=fopen($incFile,'rb'))       {
-                       $content = '';
-                       while (!feof($fd))      {
-                               $content.=fread($fd, 5000);
-                       }
-                       fclose( $fd );
-                       return $content;
+               if ($incFile)   {
+                       return @file_get_contents($incFile);
                }
        }
 
@@ -1214,23 +1315,40 @@ class t3lib_TStemplate  {
         * Call it like t3lib_TStemplate::sortedKeyList()
         *
         * @param       array           TypoScript array with numerical array in
+        * @param       boolean         If set, then a value is not required - the properties alone will be enough.
         * @return      array           An array with all integer properties listed in numeric order.
         * @see tslib_cObj::cObjGet(), tslib_gifBuilder, tslib_imgmenu::makeImageMap()
         */
-       function sortedKeyList($setupArr)       {
-               $keyArr=Array();
-               reset($setupArr);
-               while(list($key,)=each($setupArr))      {
-                       $ikey=intval($key);
-                       if (!strcmp($ikey,$key))        {
-                               $keyArr[]=$ikey;
+       function sortedKeyList($setupArr, $acceptOnlyProperties=false) {
+               $keyArr = array();
+               $setupArrKeys = array_keys($setupArr);
+               foreach ($setupArrKeys as $key) {
+                       if ($acceptOnlyProperties || t3lib_div::testInt($key)) {
+                               $keyArr[] = $key;
                        }
                }
+               $keyArr = array_unique($keyArr);
                sort($keyArr);
                return $keyArr;
        }
 
 
+       /**
+        * Returns the level of the given page in the rootline - Multiple pages can be given by separating the UIDs by comma.
+        *
+        * @param       string          A list of UIDs for which the rootline-level should get returned
+        * @return      integer The level in the rootline. If more than one page was given the lowest level will get returned.
+        */
+       function getRootlineLevel($list)        {
+               $idx = 0;
+               foreach($this->rootLine as $page)       {
+                       if (t3lib_div::inList($list, $page['uid'])) {
+                               return $idx;
+                       }
+                       $idx++;
+               }
+               return false;
+       }
 
 
 
@@ -1248,7 +1366,7 @@ class t3lib_TStemplate    {
        /**
         * The mother of all functions creating links/URLs etc in a TypoScript environment.
         * See the references below.
-        * Basically this function takes care of issues such as type,id,alias and Mount Points, simulate static documents, M5/B6 encoded parameters etc.
+        * Basically this function takes care of issues such as type,id,alias and Mount Points, URL rewriting (through hooks), M5/B6 encoded parameters etc.
         * 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.
         *
         * @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.
@@ -1298,7 +1416,7 @@ class t3lib_TStemplate    {
 
                        // typeNum
                $typeNum = $this->setup[$LD['target'].'.']['typeNum'];
-               if (!$typeOverride && intval($GLOBALS['TSFE']->config['config']['forceTypeValue']))     {
+               if (!t3lib_div::testInt($typeOverride) && intval($GLOBALS['TSFE']->config['config']['forceTypeValue'])) {
                        $typeOverride = intval($GLOBALS['TSFE']->config['config']['forceTypeValue']);
                }
                if (strcmp($typeOverride,''))   { $typeNum = $typeOverride; }   // Override...
@@ -1307,50 +1425,27 @@ class t3lib_TStemplate  {
                } else {
                        $LD['type'] = '';
                }
-               $LD['orig_type'] = $LD['type'];         // Preserving the type number. Will not be cleared if simulateStaticDocuments.
+               $LD['orig_type'] = $LD['type'];         // Preserving the type number.
 
                        // noCache
                $LD['no_cache'] = (trim($page['no_cache']) || $no_cache) ? '&no_cache=1' : '';
 
                        // linkVars
-               $LD['linkVars'] = $GLOBALS['TSFE']->linkVars.$addParams;
-
-                       // If simulateStaticDocuments is enabled:
-               if ($GLOBALS['TSFE']->config['config']['simulateStaticDocuments'])      {
-                       $LD['type'] = '';
-                       $LD['url'] = '';
-
-                               // MD5/base64 method limitation:
-                       $remainLinkVars='';
-                       $flag_simulateStaticDocuments_pEnc = t3lib_div::inList('md5,base64',$GLOBALS['TSFE']->config['config']['simulateStaticDocuments_pEnc']) && !$LD['no_cache'];
-                       if ($flag_simulateStaticDocuments_pEnc) {
-                               list($LD['linkVars'], $remainLinkVars) = $GLOBALS['TSFE']->simulateStaticDocuments_pEnc_onlyP_proc($LD['linkVars']);
-                       }
-
-                       $LD['url'].=$GLOBALS['TSFE']->makeSimulFileName(
-                                                       $page['title'],
-                                                       $page['alias'] ? $page['alias'] : $page['uid'],
-                                                       intval($typeNum),
-                                                       $LD['linkVars'],
-                                                       $LD['no_cache']?1:0
-                                               );
-
-                       if ($flag_simulateStaticDocuments_pEnc) {
-                               $LD['linkVars']=$remainLinkVars;
-                       }
-                       if ($GLOBALS['TSFE']->config['config']['simulateStaticDocuments']=='PATH_INFO') {
-                               $LD['url'] = str_replace('.','/',$LD['url']);
-                               $LD['url'] = 'index.php/'.$LD['url'].'/?';
+               if ($GLOBALS['TSFE']->config['config']['uniqueLinkVars']) {
+                       if ($addParams) {
+                               $LD['linkVars'] = t3lib_div::implodeArrayForUrl('',t3lib_div::explodeUrl2Array($GLOBALS['TSFE']->linkVars.$addParams));
                        } else {
-                               $LD['url'].= '.html?';
+                               $LD['linkVars'] = $GLOBALS['TSFE']->linkVars;
                        }
+               } else {
+                       $LD['linkVars'] = $GLOBALS['TSFE']->linkVars.$addParams;
                }
 
                        // Add absRefPrefix if exists.
                $LD['url'] = $GLOBALS['TSFE']->absRefPrefix.$LD['url'];
 
                        // 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.
-               $LD['sectionIndex'] = $page['sectionIndex_uid'] ? '#'.$page['sectionIndex_uid'] : '';
+               $LD['sectionIndex'] = $page['sectionIndex_uid'] ? '#c'.$page['sectionIndex_uid'] : '';
 
                        // Compile the normal total url
                $LD['totalURL']= $this->removeQueryString($LD['url'].$LD['type'].$LD['no_cache'].$LD['linkVars'].$GLOBALS['TSFE']->getMethodUrlIdToken).$LD['sectionIndex'];
@@ -1362,7 +1457,7 @@ class t3lib_TStemplate    {
                                                        'args' => array('page'=>$page, 'oTarget'=>$oTarget, 'no_cache'=>$no_cache, 'script'=>$script, 'overrideArray'=>$overrideArray, 'addParams'=>$addParams, 'typeOverride'=>$typeOverride),
                                                        'typeNum' => $typeNum
                                                );
-                       foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tstemplate.php']['linkData-PostProc'] as $_funcRef)   {
+                       foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tstemplate.php']['linkData-PostProc'] as $_funcRef)  {
                                t3lib_div::callUserFunction($_funcRef,$_params,$this);
                        }
                }
@@ -1495,4 +1590,5 @@ class t3lib_TStemplate    {
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tstemplate.php'])       {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tstemplate.php']);
 }
-?>
\ No newline at end of file
+
+?>