[BUGFIX] Unset stdWrap of select.pidInList
[Packages/TYPO3.CMS.git] / typo3 / sysext / cms / tslib / class.tslib_menu.php
old mode 100755 (executable)
new mode 100644 (file)
index c67566c..5dbe704
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2007 Kasper Skaarhoj (kasperYYYY@typo3.com)
+*  (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
  * The main class, tslib_menu, is also extended by other external PHP scripts such as the GMENU_LAYERS and GMENU_FOLDOUT scripts which creates pop-up menus.
  * Notice that extension classes (like "tslib_tmenu") must have their suffix (here "tmenu") listed in $this->tmpl->menuclasses - otherwise they cannot be instantiated.
  *
- * $Id$
- * Revised for TYPO3 3.6 June/2003 by Kasper Skaarhoj
+ * Revised for TYPO3 3.6 June/2003 by Kasper Skårhøj
  * XHTML compliant
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
- */
-/**
- * [CLASS/FUNCTION INDEX of SCRIPT]
- *
- *
- *
- *  145: class tslib_menu
- *  191:     function start(&$tmpl,&$sys_page,$id,$conf,$menuNumber,$objSuffix='')
- *  324:     function makeMenu()
- *  865:     function includeMakeMenu($conf,$altSortField)
- *  881:     function filterMenuPages(&$data,$banUidArray,$spacer)
- *  937:     function procesItemStates($splitCount)
- * 1147:     function link($key,$altTarget='',$typeOverride='')
- * 1212:     function changeLinksForAccessRestrictedPages(&$LD, $page, $mainTarget, $typeOverride)
- * 1233:     function subMenu($uid, $objSuffix='')
- * 1278:     function isNext($uid, $MPvar='')
- * 1299:     function isActive($uid, $MPvar='')
- * 1320:     function isCurrent($uid, $MPvar='')
- * 1335:     function isSubMenu($uid)
- * 1360:     function isItemState($kind,$key)
- * 1400:     function accessKey($title)
- * 1426:     function userProcess($mConfKey,$passVar)
- * 1441:     function setATagParts()
- * 1454:     function getPageTitle($title,$nav_title)
- * 1466:     function getMPvar($key)
- * 1481:     function getDoktypeExcludeWhere()
- * 1491:     function getBannedUids()
- *
- *
- * 1530: class tslib_tmenu extends tslib_menu
- * 1539:     function generate()
- * 1555:     function writeMenu()
- * 1699:     function getBeforeAfter($pref)
- * 1729:     function addJScolorShiftFunction()
- * 1751:     function extProc_init()
- * 1762:     function extProc_RO($key)
- * 1773:     function extProc_beforeLinking($key)
- * 1785:     function extProc_afterLinking($key)
- * 1802:     function extProc_beforeAllWrap($item,$key)
- * 1813:     function extProc_finish()
- *
- *
- * 1849: class tslib_gmenu extends tslib_menu
- * 1858:     function generate()
- * 1896:     function makeGifs($conf, $resKey)
- * 2101:     function findLargestDims($conf,$items,$Hobjs,$Wobjs,$minDim,$maxDim)
- * 2173:     function writeMenu()
- * 2294:     function extProc_init()
- * 2305:     function extProc_RO($key)
- * 2316:     function extProc_beforeLinking($key)
- * 2329:     function extProc_afterLinking($key)
- * 2346:     function extProc_beforeAllWrap($item,$key)
- * 2357:     function extProc_finish()
- *
- *
- * 2391: class tslib_imgmenu extends tslib_menu
- * 2400:     function generate()
- * 2418:     function makeImageMap($conf)
- * 2604:     function writeMenu()
- *
- *
- * 2647: class tslib_jsmenu extends tslib_menu
- * 2654:     function generate()
- * 2662:     function writeMenu()
- * 2723:     function generate_level($levels,$count,$pid,$menuItemArray='',$MP_array=array())
- *
- * TOTAL FUNCTIONS: 46
- * (This index is automatically created/updated by the extension "extdeveval")
- *
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  */
 
 
  * $menu->makeMenu();
  * $content.=$menu->writeMenu();
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage tslib
  * @see tslib_cObj::HMENU()
@@ -146,7 +76,7 @@ class tslib_menu {
        var $menuNumber = 1;                            // tells you which menu-number this is. This is important when getting data from the setup
        var $entryLevel = 0;                            // 0 = rootFolder
        var $spacerIDList = '199';                      // The doktype-number that defines a spacer
-       var $doktypeExcludeList = '5,6';                        // doktypes that define which should not be included in a menu
+       var $doktypeExcludeList = '6';                  // doktypes that define which should not be included in a menu
        var $alwaysActivePIDlist=array();
        var $imgNamePrefix = 'img';
        var $imgNameNotRandom=0;
@@ -203,7 +133,7 @@ class tslib_menu {
         * @param       array           The TypoScript configuration for the HMENU cObject
         * @param       integer         Menu number; 1,2,3. Should probably be '1'
         * @param       string          Submenu Object suffix. This offers submenus a way to use alternative configuration for specific positions in the menu; By default "1 = TMENU" would use "1." for the TMENU configuration, but if this string is set to eg. "a" then "1a." would be used for configuration instead (while "1 = " is still used for the overall object definition of "TMENU")
-        * @return      boolean         Returns true on success
+        * @return      boolean         Returns TRUE on success
         * @see tslib_cObj::HMENU()
         */
        function start(&$tmpl,&$sys_page,$id,$conf,$menuNumber,$objSuffix='')   {
@@ -219,6 +149,7 @@ class tslib_menu {
                        case 'xhtml_strict':
                        case 'xhtml_11':
                        case 'xhtml_2':
+                       case 'html5':
                                $this->nameAttribute = 'id';
                                break;
                        default:
@@ -228,11 +159,14 @@ class tslib_menu {
 
                        // Sets the internal vars. $tmpl MUST be the template-object. $sys_page MUST be the sys_page object
                if ($this->conf[$this->menuNumber.$objSuffix] && is_object($tmpl) && is_object($sys_page))      {
-                       $this->tmpl = &$tmpl;
-                       $this->sys_page = &$sys_page;
+                       $this->tmpl = $tmpl;
+                       $this->sys_page = $sys_page;
 
                                // alwaysActivePIDlist initialized:
-                       if (trim($this->conf['alwaysActivePIDlist']))   {
+                       if (trim($this->conf['alwaysActivePIDlist']) || isset($this->conf['alwaysActivePIDlist.'])) {
+                               if (isset($this->conf['alwaysActivePIDlist.'])) {
+                                       $this->conf['alwaysActivePIDlist'] = $this->parent_cObj->stdWrap($this->conf['alwaysActivePIDlist'], $this->conf['alwaysActivePIDlist.']);
+                               }
                                $this->alwaysActivePIDlist = t3lib_div::intExplode(',', $this->conf['alwaysActivePIDlist']);
                        }
 
@@ -240,15 +174,13 @@ class tslib_menu {
                        if($this->conf['excludeDoktypes']) {
                                $this->doktypeExcludeList = $GLOBALS['TYPO3_DB']->cleanIntList($this->conf['excludeDoktypes']);
                        }
-                       if($this->conf['includeNotInMenu']) {
-                               $exclDoktypeArr = t3lib_div::trimExplode(',',$this->doktypeExcludeList,1);
-                               $exclDoktypeArr = t3lib_div::removeArrayEntryByValue($exclDoktypeArr,'5');
-                               $this->doktypeExcludeList = implode(',',$exclDoktypeArr);
-                       }
-
                                // EntryLevel
-                       $this->entryLevel = tslib_cObj::getKey ($conf['entryLevel'],$this->tmpl->rootLine);
-
+                       $this->entryLevel = tslib_cObj::getKey (
+                               isset($conf['entryLevel.'])
+                               ? $this->parent_cObj->stdWrap($conf['entryLevel'], $conf['entryLevel.'])
+                               : $conf['entryLevel'],
+                               $this->tmpl->rootLine
+                       );
                                // Set parent page: If $id not stated with start() then the base-id will be found from rootLine[$this->entryLevel]
                        if ($id)        {       // Called as the next level in a menu. It is assumed that $this->MP_array is set from parent menu.
                                $this->id = intval($id);
@@ -272,7 +204,7 @@ class tslib_menu {
                                }
                        }
 
-                               // Return false if no page ID was set (thus no menu of subpages can be made).
+                               // Return FALSE if no page ID was set (thus no menu of subpages can be made).
                        if ($this->id<=0)       {
                                return FALSE;
                        }
@@ -305,15 +237,38 @@ class tslib_menu {
                                }
                        }
 
+                       // Set $directoryLevel so the following evalution of the nextActive will not return
+                       // an invalid value if .special=directory was set
+                       $directoryLevel = 0;
+                       if ($this->conf['special'] == 'directory')      {
+                               $value = isset($this->conf['special.']['value.'])
+                                       ? $this->parent_cObj->stdWrap($this->conf['special.']['value'], $this->conf['special.']['value.'])
+                                       : $this->conf['special.']['value'];
+                               if ($value=='') {
+                                       $value=$GLOBALS['TSFE']->page['uid'];
+                               }
+                               $directoryLevel = intval($GLOBALS['TSFE']->tmpl->getRootlineLevel($value));
+                       }
+
                                // Setting "nextActive": This is the page uid + MPvar of the NEXT page in rootline. Used to expand the menu if we are in the right branch of the tree
-                               // Notice: The automatic expansion of a menu is designed to work only when no "special" modes are used.
-                       if (is_array($this->tmpl->rootLine[$this->entryLevel+$this->menuNumber]))       {
+                               // Notice: The automatic expansion of a menu is designed to work only when no "special" modes (except "directory") are used.
+                       $startLevel = $directoryLevel ? $directoryLevel : $this->entryLevel;
+                       $currentLevel = $startLevel + $this->menuNumber;
+                       if (is_array($this->tmpl->rootLine[$currentLevel])) {
                                $nextMParray = $this->MP_array;
-                               if ($this->tmpl->rootLine[$this->entryLevel+$this->menuNumber]['_MOUNT_OL'])    {       // In overlay mode, add next level MPvars as well:
-                                       $nextMParray[] = $this->tmpl->rootLine[$this->entryLevel+$this->menuNumber]['_MP_PARAM'];
+                               if (!count($nextMParray) && !$this->tmpl->rootLine[$currentLevel]['_MOUNT_OL'] && $currentLevel > 0) {
+                                               // Make sure to slide-down any mount point information (_MP_PARAM) to children records in the rootline
+                                               // otherwise automatic expansion will not work
+                                       $parentRecord = $this->tmpl->rootLine[$currentLevel - 1];
+                                       if (isset($parentRecord['_MP_PARAM'])) {
+                                               $nextMParray[] = $parentRecord['_MP_PARAM'];
+                                       }
+                               }
+
+                               if ($this->tmpl->rootLine[$currentLevel]['_MOUNT_OL']) {        // In overlay mode, add next level MPvars as well:
+                                       $nextMParray[] = $this->tmpl->rootLine[$currentLevel]['_MP_PARAM'];
                                }
-                               $this->nextActive = $this->tmpl->rootLine[$this->entryLevel+$this->menuNumber]['uid'].
-                                                                               (count($nextMParray)?':'.implode(',',$nextMParray):'');
+                               $this->nextActive = $this->tmpl->rootLine[$currentLevel]['uid'] . (count($nextMParray) ? ':' . implode(',', $nextMParray) : '');
                        } else {
                                $this->nextActive = '';
                        }
@@ -354,7 +309,9 @@ class tslib_menu {
                        $altSortFieldValue = trim($this->mconf['alternativeSortingField']);
                        $altSortField = $altSortFieldValue ? $altSortFieldValue : 'sorting';
                        if ($this->menuNumber==1 && $this->conf['special'])     {               // ... only for the FIRST level of a HMENU
-                               $value = $this->conf['special.']['value'];
+                               $value = isset($this->conf['special.']['value.'])
+                                       ? $this->parent_cObj->stdWrap($this->conf['special.']['value'], $this->conf['special.']['value.'])
+                                       : $this->conf['special.']['value'];
 
                                switch($this->conf['special'])  {
                                        case 'userdefined':
@@ -393,7 +350,7 @@ class tslib_menu {
                                                        }
 
                                                        if ($this->conf['addQueryString'])      {
-                                                               $getVars = $this->parent_cObj->getQueryArguments($this->conf['addQueryString.'],array('L'=>$sUid),true);
+                                                               $getVars = $this->parent_cObj->getQueryArguments($this->conf['addQueryString.'],array('L'=>$sUid),TRUE);
                                                        } else {
                                                                $getVars = '&L='.$sUid;
                                                        }
@@ -431,7 +388,7 @@ class tslib_menu {
                                                        }
 
                                                                // Get sub-pages:
-                                                       $res = $GLOBALS['TSFE']->cObj->exec_getQuery('pages',Array('pidInList'=>$id,'orderBy'=>$altSortField));
+                                                       $res = $this->parent_cObj->exec_getQuery('pages',Array('pidInList'=>$id,'orderBy'=>$altSortField));
                                                        while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {
                                                                $GLOBALS['TSFE']->sys_page->versionOL('pages',$row);
 
@@ -484,6 +441,11 @@ class tslib_menu {
                                                                $row = $loadDB->results['pages'][$val['id']];
                                                        }
 
+                                                               //Add versioning overlay for current page (to respect workspaces)
+                                                       if (is_array($row)) {
+                                                               $this->sys_page->versionOL('pages', $row, TRUE);
+                                                       }
+
                                                                // Add external MP params, then the row:
                                                        if (is_array($row))     {
                                                                if ($MP)        $row['_MP_PARAM'] = $MP.($row['_MP_PARAM'] ? ','.$row['_MP_PARAM'] : '');
@@ -496,12 +458,12 @@ class tslib_menu {
                                                        $value=$GLOBALS['TSFE']->page['uid'];
                                                }
                                                $items=t3lib_div::intExplode(',',$value);
-                                               if (t3lib_div::testInt($this->conf['special.']['depth']))       {
-                                                       $depth = t3lib_div::intInRange($this->conf['special.']['depth'],1,20);          // Tree depth
+                                               if (t3lib_utility_Math::canBeInterpretedAsInteger($this->conf['special.']['depth']))    {
+                                                       $depth = t3lib_utility_Math::forceIntegerInRange($this->conf['special.']['depth'],1,20);                // Tree depth
                                                } else {
                                                        $depth=20;
                                                }
-                                               $limit = t3lib_div::intInRange($this->conf['special.']['limit'],0,100); // max number of items
+                                               $limit = t3lib_utility_Math::forceIntegerInRange($this->conf['special.']['limit'],0,100);       // max number of items
                                                $maxAge = intval(tslib_cObj::calc($this->conf['special.']['maxAge']));
                                                if (!$limit)    $limit=10;
                                                $mode = $this->conf['special.']['mode'];        // *'auto', 'manual', 'tstamp'
@@ -509,7 +471,7 @@ class tslib_menu {
                                                $id_list_arr = Array();
 
                                                foreach($items as $id)  {
-                                                       $bA = t3lib_div::intInRange($this->conf['special.']['beginAtLevel'],0,100);
+                                                       $bA = t3lib_utility_Math::forceIntegerInRange($this->conf['special.']['beginAtLevel'],0,100);
                                                        $id_list_arr[] = tslib_cObj::getTreeList(-1*$id,$depth-1+$bA,$bA-1);
                                                }
                                                $id_list = implode(',',$id_list_arr);
@@ -539,10 +501,10 @@ class tslib_menu {
                                                        $extraWhere.= ' AND pages.no_search=0';
                                                }
                                                if ($maxAge>0)  {
-                                                       $extraWhere.=' AND '.$sortField.'>'.($GLOBALS['SIM_EXEC_TIME']-$maxAge);
+                                                       $extraWhere.=' AND '.$sortField.'>'.($GLOBALS['SIM_ACCESS_TIME']-$maxAge);
                                                }
 
-                                               $res = $GLOBALS['TSFE']->cObj->exec_getQuery('pages',Array('pidInList'=>'0', 'uidInList'=>$id_list, 'where'=>$sortField.'>=0'.$extraWhere, 'orderBy'=>($altSortFieldValue ? $altSortFieldValue : $sortField.' desc'),'max'=>$limit));
+                                               $res = $this->parent_cObj->exec_getQuery('pages',Array('pidInList'=>'0', 'uidInList'=>$id_list, 'where'=>$sortField.'>=0'.$extraWhere, 'orderBy'=>($altSortFieldValue ? $altSortFieldValue : $sortField.' desc'),'max'=>$limit));
                                                while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {
                                                        $GLOBALS['TSFE']->sys_page->versionOL('pages',$row);
                                                        if (is_array($row))     {
@@ -556,13 +518,15 @@ class tslib_menu {
                                                        $value=$GLOBALS['TSFE']->page['uid'];
                                                }
                                                if ($this->conf['special.']['setKeywords'] || $this->conf['special.']['setKeywords.']) {
-                                                       $kw = $this->parent_cObj->stdWrap($this->conf['special.']['setKeywords'], $this->conf['special.']['setKeywords.']);
-                                               } else {
-                                                       $value_rec=$this->sys_page->getPage($value);    // The page record of the 'value'.
+                                                       $kw = isset($this->conf['special.']['setKeywords.'])
+                                                               ? $this->parent_cObj->stdWrap($this->conf['special.']['setKeywords'], $this->conf['special.']['setKeywords.'])
+                                                               : $this->conf['special.']['setKeywords'];
+                                               } else {
+                                                       $value_rec=$this->sys_page->getPage($value);    // The page record of the 'value'.
 
                                                        $kfieldSrc = $this->conf['special.']['keywordsField.']['sourceField'] ? $this->conf['special.']['keywordsField.']['sourceField'] : 'keywords';
                                                        $kw = trim(tslib_cObj::keywords($value_rec[$kfieldSrc]));               // keywords.
-                                               }
+                                               }
 
                                                $mode = $this->conf['special.']['mode'];        // *'auto', 'manual', 'tstamp'
                                                switch($mode)   {
@@ -585,18 +549,23 @@ class tslib_menu {
                                                }
 
                                                        // depth, limit, extra where
-                                               if (t3lib_div::testInt($this->conf['special.']['depth']))       {
-                                                       $depth = t3lib_div::intInRange($this->conf['special.']['depth'],0,20);          // Tree depth
+                                               if (t3lib_utility_Math::canBeInterpretedAsInteger($this->conf['special.']['depth']))    {
+                                                       $depth = t3lib_utility_Math::forceIntegerInRange($this->conf['special.']['depth'],0,20);                // Tree depth
                                                } else {
                                                        $depth=20;
                                                }
-                                               $limit = t3lib_div::intInRange($this->conf['special.']['limit'],0,100); // max number of items
-                                               $extraWhere = ' AND pages.uid!='.$value.($this->conf['includeNotInMenu'] ? '' : ' AND pages.nav_hide=0').$this->getDoktypeExcludeWhere();
+                                               $limit = t3lib_utility_Math::forceIntegerInRange($this->conf['special.']['limit'],0,100);       // max number of items
+                                               $extraWhere = ' AND pages.uid<>'.$value.($this->conf['includeNotInMenu'] ? '' : ' AND pages.nav_hide=0').$this->getDoktypeExcludeWhere();
                                                if ($this->conf['special.']['excludeNoSearchPages']) {
                                                        $extraWhere.= ' AND pages.no_search=0';
                                                }
                                                        // start point
-                                               $eLevel = tslib_cObj::getKey (intval($this->conf['special.']['entryLevel']),$this->tmpl->rootLine);
+                                               $eLevel = tslib_cObj::getKey(
+                                                       isset($this->conf['special.']['entryLevel.'])
+                                                               ? $this->parent_cObj->stdWrap($this->conf['special.']['entryLevel'], $this->conf['special.']['entryLevel.'])
+                                                               : $this->conf['special.']['entryLevel'],
+                                                       $this->tmpl->rootLine
+                                               );
                                                $startUid = intval($this->tmpl->rootLine[$eLevel]['uid']);
 
                                                        // which field is for keywords
@@ -607,7 +576,7 @@ class tslib_menu {
 
                                                        // If there are keywords and the startuid is present.
                                                if ($kw && $startUid)   {
-                                                       $bA = t3lib_div::intInRange($this->conf['special.']['beginAtLevel'],0,100);
+                                                       $bA = t3lib_utility_Math::forceIntegerInRange($this->conf['special.']['beginAtLevel'],0,100);
                                                        $id_list=tslib_cObj::getTreeList(-1*$startUid,$depth-1+$bA,$bA-1);
 
                                                        $kwArr = explode(',',$kw);
@@ -617,7 +586,7 @@ class tslib_menu {
                                                                        $keyWordsWhereArr[] = $kfield.' LIKE \'%'.$GLOBALS['TYPO3_DB']->quoteStr($word, 'pages').'%\'';
                                                                }
                                                        }
-                                                       $res = $GLOBALS['TSFE']->cObj->exec_getQuery('pages',Array('pidInList'=>'0', 'uidInList'=>$id_list, 'where'=>'('.implode(' OR ',$keyWordsWhereArr).')'.$extraWhere, 'orderBy'=>($altSortFieldValue ? $altSortFieldValue : $sortField.' desc'),'max'=>$limit));
+                                                       $res = $this->parent_cObj->exec_getQuery('pages',Array('pidInList'=>'0', 'uidInList'=>$id_list, 'where'=>'('.implode(' OR ',$keyWordsWhereArr).')'.$extraWhere, 'orderBy'=>($altSortFieldValue ? $altSortFieldValue : $sortField.' desc'),'max'=>$limit));
                                                        while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {
                                                                $GLOBALS['TSFE']->sys_page->versionOL('pages',$row);
                                                                if (is_array($row))     {
@@ -627,9 +596,14 @@ class tslib_menu {
                                                }
                                        break;
                                        case 'rootline':
-                                               $begin_end = explode('|',$this->conf['special.']['range']);
-                                               if (!t3lib_div::testInt($begin_end[0])) {intval($begin_end[0]);}
-                                               if (!t3lib_div::testInt($begin_end[1])) {$begin_end[1]=-1;}
+                                               $range = isset($this->conf['special.']['range.'])
+                                                       ? $this->parent_cObj->stdWrap($this->conf['special.']['range'], $this->conf['special.']['range.'])
+                                                       : $this->conf['special.']['range'];
+                                               $begin_end = explode('|', $range);
+                                               $begin_end[0] = intval($begin_end[0]);
+                                               if (!t3lib_utility_Math::canBeInterpretedAsInteger($begin_end[1])) {
+                                                       $begin_end[1] = -1;
+                                               }
 
                                                $beginKey = tslib_cObj::getKey ($begin_end[0],$this->tmpl->rootLine);
                                                $endKey = tslib_cObj::getKey ($begin_end[1],$this->tmpl->rootLine);
@@ -655,7 +629,12 @@ class tslib_menu {
                                                                // For normal mount points, set the variable for next level.
                                                        if ($v_rl['_MP_PARAM'] && !$v_rl['_MOUNT_OL'])  {
                                                                $rl_MParray[] = $v_rl['_MP_PARAM'];
+                                                       }
                                                }
+                                                       // Reverse order of elements (e.g. "1,2,3,4" gets "4,3,2,1"):
+                                               if (isset($this->conf['special.']['reverseOrder']) && $this->conf['special.']['reverseOrder']) {
+                                                       $temp = array_reverse($temp);
+                                                       $rl_MParray = array_reverse($rl_MParray);
                                                }
                                        break;
                                        case 'browse':
@@ -677,8 +656,7 @@ class tslib_menu {
                                                        $prevnext_menu = $this->sys_page->getMenu($value_rec['pid'],'*',$altSortField);
                                                        $lastKey=0;
                                                        $nextActive=0;
-                                                       reset($prevnext_menu);
-                                                       while(list($k_b,$v_b)=each($prevnext_menu))     {
+                                                       foreach ($prevnext_menu as $k_b => $v_b) {
                                                                if ($nextActive)        {
                                                                        $recArr['next']=$v_b;
                                                                        $nextActive=0;
@@ -701,8 +679,7 @@ class tslib_menu {
                                                                $prevnextsection_menu = $this->sys_page->getMenu($recArr['index']['uid'],'*',$altSortField);
                                                                $lastKey=0;
                                                                $nextActive=0;
-                                                               reset($prevnextsection_menu);
-                                                               while(list($k_b,$v_b)=each($prevnextsection_menu))      {
+                                                               foreach ($prevnextsection_menu as $k_b => $v_b) {
                                                                        if ($nextActive)        {
                                                                                $sectionRec_temp = $this->sys_page->getMenu($v_b['uid'],'*',$altSortField);
                                                                                if (count($sectionRec_temp))    {
@@ -739,7 +716,7 @@ class tslib_menu {
 
                                                        $items = explode('|',$this->conf['special.']['items']);
                                                        $c=0;
-                                                       while(list($k_b,$v_b)=each($items))     {
+                                                       foreach ($items as $k_b => $v_b) {
                                                                $v_b=strtolower(trim($v_b));
                                                                if (intval($this->conf['special.'][$v_b.'.']['uid']))   {
                                                                        $recArr[$v_b] = $this->sys_page->getPage(intval($this->conf['special.'][$v_b.'.']['uid']));     // fetches the page in case of a hardcoded pid in template
@@ -749,9 +726,9 @@ class tslib_menu {
                                                                        if ($this->conf['special.'][$v_b.'.']['target'])        {
                                                                                $temp[$c]['target']=$this->conf['special.'][$v_b.'.']['target'];
                                                                        }
-                                                                       if (is_array($this->conf['special.'][$v_b.'.']['fields.']))     {
-                                                                               reset($this->conf['special.'][$v_b.'.']['fields.']);
-                                                                               while(list($fk,$val)=each($this->conf['special.'][$v_b.'.']['fields.']))        {
+                                                                       $tmpSpecialFields = $this->conf['special.'][$v_b.'.']['fields.'];
+                                                                       if (is_array($tmpSpecialFields)) {
+                                                                               foreach ($tmpSpecialFields as $fk => $val) {
                                                                                        $temp[$c][$fk]=$val;
                                                                                }
                                                                        }
@@ -761,61 +738,51 @@ class tslib_menu {
                                                }
                                        break;
                                }
+                               if ($this->mconf['sectionIndex']) {
+                                       $sectionIndexes = array();
+
+                                       foreach ($temp as $page) {
+                                               $sectionIndexes = $sectionIndexes + $this->sectionIndex($altSortField, $page['uid']);
+                                       }
+
+                                       $temp = $sectionIndexes;
+                               }
                        } elseif (is_array($this->alternativeMenuTempArray))    {       // Setting $temp array if not level 1.
                                $temp = $this->alternativeMenuTempArray;
                        } elseif ($this->mconf['sectionIndex']) {
-                               if ($GLOBALS['TSFE']->sys_language_uid && count($this->sys_page->getPageOverlay($this->id)))    {
-                                       $sys_language_uid = intval($GLOBALS['TSFE']->sys_language_uid);
-                               } else $sys_language_uid=0;
-
-                               $selectSetup = Array(
-                                       'pidInList'=>$this->id,
-                                       'orderBy'=>$altSortField,
-                                       'where' => 'colPos=0 AND sys_language_uid='.$sys_language_uid,
-                                       'andWhere' => 'sectionIndex!=0'
-                                       );
-                               switch($this->mconf['sectionIndex.']['type'])   {
-                                       case 'all':
-                                               unset($selectSetup['andWhere']);
-                                       break;
-                                       case 'header':
-                                               $selectSetup['andWhere']='header_layout!=100 AND header!=""';
-                                       break;
-                               }
-                               $basePageRow=$this->sys_page->getPage($this->id);
-                               if (is_array($basePageRow))     {
-                                       $res = $GLOBALS['TSFE']->cObj->exec_getQuery('tt_content',      $selectSetup);
-                                       while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {
-                                               $GLOBALS['TSFE']->sys_page->versionOL('tt_content',$row);
-
-                                               if (is_array($row))     {
-                                                       $temp[$row['uid']] = $basePageRow;
-                                                       $temp[$row['uid']]['title'] = $row['header'];
-                                                       $temp[$row['uid']]['nav_title'] = $row['header'];
-                                                       $temp[$row['uid']]['subtitle'] = $row['subheader'];
-                                                       $temp[$row['uid']]['starttime'] = $row['starttime'];
-                                                       $temp[$row['uid']]['endtime'] = $row['endtime'];
-                                                       $temp[$row['uid']]['fe_group'] = $row['fe_group'];
-                                                       $temp[$row['uid']]['media'] = $row['media'];
-
-                                                       $temp[$row['uid']]['header_layout'] = $row['header_layout'];
-                                                       $temp[$row['uid']]['bodytext'] = $row['bodytext'];
-                                                       $temp[$row['uid']]['image'] = $row['image'];
-
-                                                       $temp[$row['uid']]['sectionIndex_uid'] = $row['uid'];
-                                               }
-                                       }
-                               }
+                               $temp = $this->sectionIndex($altSortField);
                        } else {        // Default:
                                $temp = $this->sys_page->getMenu($this->id,'*',$altSortField);          // gets the menu
                        }
 
                        $c=0;
                        $c_b=0;
+
                        $minItems = intval($this->mconf['minItems'] ? $this->mconf['minItems'] : $this->conf['minItems']);
                        $maxItems = intval($this->mconf['maxItems'] ? $this->mconf['maxItems'] : $this->conf['maxItems']);
                        $begin = tslib_cObj::calc($this->mconf['begin'] ? $this->mconf['begin'] : $this->conf['begin']);
 
+                       $minItemsConf = isset($this->mconf['minItems.'])
+                                       ? $this->mconf['minItems.']
+                                       : (isset($this->conf['minItems.']) ? $this->conf['minItems.'] : NULL);
+                       $minItems = is_array($minItemsConf)
+                                       ? $this->parent_cObj->stdWrap($minItems, $minItemsConf)
+                                       : $minItems;
+
+                       $maxItemsConf = isset($this->mconf['maxItems.'])
+                                       ? $this->mconf['maxItems.']
+                                       : (isset($this->conf['maxItems.']) ? $this->conf['maxItems.'] : NULL);
+                       $maxItems = is_array($maxItemsConf)
+                                       ? $this->parent_cObj->stdWrap($maxItems, $maxItemsConf)
+                                       : $maxItems;
+
+                       $beginConf = isset($this->mconf['begin.'])
+                                       ? $this->mconf['begin.']
+                                       : (isset($this->conf['begin.']) ? $this->conf['begin.'] : NULL);
+                       $begin = is_array($beginConf)
+                                       ? $this->parent_cObj->stdWrap($begin, $beginConf)
+                                       : $begin;
+
                        $banUidArray = $this->getBannedUids();
 
                                // Fill in the menuArr with elements that should go into the menu:
@@ -845,13 +812,14 @@ class tslib_menu {
                                        $c++;
                                }
                        }
-                               // Setting number of menu items
-                       $GLOBALS['TSFE']->register['count_menuItems'] = count($this->menuArr);
                                //      Passing the menuArr through a user defined function:
                        if ($this->mconf['itemArrayProcFunc'])  {
                                if (!is_array($this->parentMenuArr)) {$this->parentMenuArr=array();}
                                $this->menuArr = $this->userProcess('itemArrayProcFunc',$this->menuArr);
                        }
+                               // Setting number of menu items
+                       $GLOBALS['TSFE']->register['count_menuItems'] = count($this->menuArr);
+
                        $this->hash = md5(serialize($this->menuArr).serialize($this->mconf).serialize($this->tmpl->rootLine).serialize($this->MP_array));
 
                                // Get the cache timeout:
@@ -860,10 +828,11 @@ class tslib_menu {
                        } else {
                                $cacheTimeout = $GLOBALS['TSFE']->get_cache_timeout();
                        }
-                       $serData = $this->sys_page->getHash($this->hash, $cacheTimeout);
+
+                       $serData = $this->sys_page->getHash($this->hash);
                        if (!$serData)  {
                                $this->generate();
-                               $this->sys_page->storeHash($this->hash, serialize($this->result),'MENUDATA');
+                               $this->sys_page->storeHash($this->hash, serialize($this->result), 'MENUDATA', $cacheTimeout);
                        } else {
                                $this->result = unserialize($serData);
                        }
@@ -877,33 +846,31 @@ class tslib_menu {
        }
 
        /**
-        * Includes the PHP script defined for the HMENU special type "userdefined".
-        * This script is supposed to populate the array $menuItemsArray with a set of page records comprising the menu.
-        * The "userdefined" type is deprecated since "userfunction" has arrived since and is a better choice for many reasons (like using classes/functions for rendering the menu)
-        *
-        * @param       array           TypoScript parameters for "special.". In particular the property "file" is reserved and specifies the file to include. Seems like any other property can be used freely by the script.
-        * @param       string          The sorting field. Can be used from the script in the $incFile.
-        * @return      array           An array with the menu items
-        * @access private
-        */
-       function includeMakeMenu($conf,$altSortField)   {
-               $incFile = $GLOBALS['TSFE']->tmpl->getFileName($conf['file']);
-               if ($incFile && $GLOBALS['TSFE']->checkFileInclude($incFile))   {
-                       include($incFile);
-               }
-               return is_array($menuItemsArray) ? $menuItemsArray : array();
-       }
-
-       /**
         * Checks if a page is OK to include in the final menu item array. Pages can be excluded if the doktype is wrong, if they are hidden in navigation, have a uid in the list of banned uids etc.
         *
         * @param       array           Array of menu items
         * @param       array           Array of page uids which are to be excluded
         * @param       boolean         If set, then the page is a spacer.
-        * @return      boolean         Returns true if the page can be safely included.
+        * @return      boolean         Returns TRUE if the page can be safely included.
         */
        function filterMenuPages(&$data,$banUidArray,$spacer)   {
 
+               $includePage = TRUE;
+               if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/tslib/class.tslib_menu.php']['filterMenuPages'])) {
+                       foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/tslib/class.tslib_menu.php']['filterMenuPages'] as $classRef) {
+                               $hookObject = t3lib_div::getUserObj($classRef);
+
+                               if (!($hookObject instanceof tslib_menu_filterMenuPagesHook)) {
+                                       throw new UnexpectedValueException('$hookObject must implement interface tslib_menu_filterMenuPagesHook', 1269877402);
+                               }
+
+                               $includePage = $includePage && $hookObject->processFilter($data, $banUidArray, $spacer, $this);
+                       }
+               }
+               if (!$includePage) {
+                       return FALSE;
+               }
+
                if ($data['_SAFE'])     return TRUE;
 
                $uid = $data['uid'];
@@ -925,7 +892,7 @@ class tslib_menu {
                                                                }
                                                        }
 
-                                                               // Continue if token is true:
+                                                               // Continue if token is TRUE:
                                                        if ($tok)       {
 
                                                                        // Checking if "&L" should be modified so links to non-accessible pages will not happen.
@@ -971,11 +938,10 @@ class tslib_menu {
                }
 
                        // Prepare IFSUB settings, overriding normal settings
-                       // IFSUB is true if there exist submenu items to the current item
+                       // IFSUB is TRUE if there exist submenu items to the current item
                if ($this->mconf['IFSUB'])      {
                        $IFSUBinit = 0; // Flag: If $IFSUB is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {
+                       foreach ($NOconf as $key => $val) {
                                if ($this->isItemState('IFSUB',$key))   {
                                        if (!$IFSUBinit)        {       // if this is the first IFSUB element, we must generate IFSUB.
                                                $IFSUBconf = $this->tmpl->splitConfArray($this->mconf['IFSUB.'],$splitCount);
@@ -994,8 +960,7 @@ class tslib_menu {
                        // Prepare active settings, overriding normal settings
                if ($this->mconf['ACT'])        {
                        $ACTinit = 0;   // Flag: If $ACT is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {       // Find active
+                       foreach ($NOconf as $key => $val) {     // Find active
                                if ($this->isItemState('ACT',$key))     {
                                        if (!$ACTinit)  {       // if this is the first 'active', we must generate ACT.
                                                $ACTconf = $this->tmpl->splitConfArray($this->mconf['ACT.'],$splitCount);
@@ -1013,11 +978,10 @@ class tslib_menu {
                        }
                }
                        // Prepare ACT (active)/IFSUB settings, overriding normal settings
-                       // ACTIFSUB is true if there exist submenu items to the current item and the current item is active
+                       // ACTIFSUB is TRUE if there exist submenu items to the current item and the current item is active
                if ($this->mconf['ACTIFSUB'])   {
                        $ACTIFSUBinit = 0;      // Flag: If $ACTIFSUB is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {       // Find active
+                       foreach ($NOconf as $key => $val) {     // Find active
                                if ($this->isItemState('ACTIFSUB',$key))        {
                                        if (!$ACTIFSUBinit)     {       // if this is the first 'active', we must generate ACTIFSUB.
                                                $ACTIFSUBconf = $this->tmpl->splitConfArray($this->mconf['ACTIFSUB.'],$splitCount);
@@ -1035,11 +999,10 @@ class tslib_menu {
                        }
                }
                        // Prepare CUR (current) settings, overriding normal settings
-                       // CUR is true if the current page equals the item here!
+                       // CUR is TRUE if the current page equals the item here!
                if ($this->mconf['CUR'])        {
                        $CURinit = 0;   // Flag: If $CUR is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {
+                       foreach ($NOconf as $key => $val) {
                                if ($this->isItemState('CUR',$key))     {
                                        if (!$CURinit)  {       // if this is the first 'current', we must generate CUR. Basically this control is just inherited from the other implementations as current would only exist one time and thats it (unless you use special-features of HMENU)
                                                $CURconf = $this->tmpl->splitConfArray($this->mconf['CUR.'],$splitCount);
@@ -1056,11 +1019,10 @@ class tslib_menu {
                        }
                }
                        // Prepare CUR (current)/IFSUB settings, overriding normal settings
-                       // CURIFSUB is true if there exist submenu items to the current item and the current page equals the item here!
+                       // CURIFSUB is TRUE if there exist submenu items to the current item and the current page equals the item here!
                if ($this->mconf['CURIFSUB'])   {
                        $CURIFSUBinit = 0;      // Flag: If $CURIFSUB is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {
+                       foreach ($NOconf as $key => $val) {
                                if ($this->isItemState('CURIFSUB',$key))        {
                                        if (!$CURIFSUBinit)     {       // if this is the first 'current', we must generate CURIFSUB.
                                                $CURIFSUBconf = $this->tmpl->splitConfArray($this->mconf['CURIFSUB.'],$splitCount);
@@ -1080,8 +1042,7 @@ class tslib_menu {
                        // Prepare active settings, overriding normal settings
                if ($this->mconf['USR'])        {
                        $USRinit = 0;   // Flag: If $USR is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {       // Find active
+                       foreach ($NOconf as $key => $val) {     // Find active
                                if ($this->isItemState('USR',$key))     {
                                        if (!$USRinit)  {       // if this is the first active, we must generate USR.
                                                $USRconf = $this->tmpl->splitConfArray($this->mconf['USR.'],$splitCount);
@@ -1101,8 +1062,7 @@ class tslib_menu {
                        // Prepare spacer settings, overriding normal settings
                if ($this->mconf['SPC'])        {
                        $SPCinit = 0;   // Flag: If $SPC is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {       // Find spacers
+                       foreach ($NOconf as $key => $val) {     // Find spacers
                                if ($this->isItemState('SPC',$key))     {
                                        if (!$SPCinit)  {       // if this is the first spacer, we must generate SPC.
                                                $SPCconf = $this->tmpl->splitConfArray($this->mconf['SPC.'],$splitCount);
@@ -1115,8 +1075,7 @@ class tslib_menu {
                        // Prepare Userdefined settings
                if ($this->mconf['USERDEF1'])   {
                        $USERDEF1init = 0;      // Flag: If $USERDEF1 is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {       // Find active
+                       foreach ($NOconf as $key => $val) {     // Find active
                                if ($this->isItemState('USERDEF1',$key))        {
                                        if (!$USERDEF1init)     {       // if this is the first active, we must generate USERDEF1.
                                                $USERDEF1conf = $this->tmpl->splitConfArray($this->mconf['USERDEF1.'],$splitCount);
@@ -1136,8 +1095,7 @@ class tslib_menu {
                        // Prepare Userdefined settings
                if ($this->mconf['USERDEF2'])   {
                        $USERDEF2init = 0;      // Flag: If $USERDEF2 is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {       // Find active
+                       foreach ($NOconf as $key => $val) {     // Find active
                                if ($this->isItemState('USERDEF2',$key))        {
                                        if (!$USERDEF2init)     {       // if this is the first active, we must generate USERDEF2.
                                                $USERDEF2conf = $this->tmpl->splitConfArray($this->mconf['USERDEF2.'],$splitCount);
@@ -1186,23 +1144,56 @@ class tslib_menu {
                }
 
                        // Setting main target:
-               $mainTarget = $altTarget ? $altTarget : $this->mconf['target'];
+               if ($altTarget) {
+                       $mainTarget = $altTarget;
+               } elseif ($this->mconf['target.']) {
+                       $mainTarget = $this->parent_cObj->stdWrap($this->mconf['target'], $this->mconf['target.']);
+               } else {
+                       $mainTarget = $this->mconf['target'];
+               }
 
                        // Creating link:
                if ($this->mconf['collapse'] && $this->isActive($this->menuArr[$key]['uid'], $this->getMPvar($key)))    {
                        $thePage = $this->sys_page->getPage($this->menuArr[$key]['pid']);
-                       $LD = $this->tmpl->linkData($thePage,$mainTarget,'','',$overrideArray, $this->mconf['addParams'].$MP_params.$this->menuArr[$key]['_ADD_GETVARS'], $typeOverride);
+                       $LD = $this->menuTypoLink($thePage,$mainTarget,'','',$overrideArray, $this->mconf['addParams'].$MP_params.$this->menuArr[$key]['_ADD_GETVARS'], $typeOverride);
                } else {
-                       $LD = $this->tmpl->linkData($this->menuArr[$key],$mainTarget,'','',$overrideArray, $this->mconf['addParams'].$MP_params.$this->I['val']['additionalParams'].$this->menuArr[$key]['_ADD_GETVARS'], $typeOverride);
+                       $LD = $this->menuTypoLink($this->menuArr[$key],$mainTarget,'','',$overrideArray, $this->mconf['addParams'].$MP_params.$this->I['val']['additionalParams'].$this->menuArr[$key]['_ADD_GETVARS'], $typeOverride);
                }
 
                        // Override URL if using "External URL" as doktype with a valid e-mail address:
-               if ($this->menuArr[$key]['doktype'] == 3 && $this->menuArr[$key]['urltype'] == 3 && t3lib_div::validEmail($this->menuArr[$key]['url'])) {
+               if ($this->menuArr[$key]['doktype'] == t3lib_pageSelect::DOKTYPE_LINK && $this->menuArr[$key]['urltype'] == 3 && t3lib_div::validEmail($this->menuArr[$key]['url'])) {
                                // Create mailto-link using tslib_cObj::typolink (concerning spamProtectEmailAddresses):
                        $LD['totalURL'] = $this->parent_cObj->typoLink_URL(array('parameter' => $this->menuArr[$key]['url']));
                        $LD['target'] = '';
                }
 
+                       // Override url if current page is a shortcut
+               if ($this->menuArr[$key]['doktype'] == t3lib_pageSelect::DOKTYPE_SHORTCUT
+                       && $this->menuArr[$key]['shortcut_mode'] != t3lib_pageSelect::SHORTCUT_MODE_RANDOM_SUBPAGE) {
+
+                       $shortcut = NULL;
+                       try {
+                               $shortcut = $GLOBALS['TSFE']->getPageShortcut(
+                                       $this->menuArr[$key]['shortcut'],
+                                       $this->menuArr[$key]['shortcut_mode'],
+                                       $this->menuArr[$key]['uid']
+                               );
+                       } catch (Exception $ex) {
+                               // shortcut configuration is wrong and Exception is thrown
+                               // this will be catched with the next is_array() check
+                       }
+
+                       if (!is_array($shortcut)) {
+                               return array();
+                       }
+
+                               // Only setting url, not target
+                       $LD['totalURL'] = $this->parent_cObj->typoLink_URL(array(
+                               'parameter' => $shortcut['uid'],
+                               'additionalParams' => $this->mconf['addParams'] . $MP_params . $this->I['val']['additionalParams'] . $this->menuArr[$key]['_ADD_GETVARS'],
+                       ));
+               }
+
                        // Manipulation in case of access restricted pages:
                $this->changeLinksForAccessRestrictedPages($LD,$this->menuArr[$key],$mainTarget,$typeOverride);
 
@@ -1222,6 +1213,31 @@ class tslib_menu {
                        $GLOBALS['TSFE']->setJS('openPic');
                }
 
+                       // look for type and popup
+                       // following settings are valid in field target:
+                       // 230                                                          will add type=230 to the link
+                       // 230 500x600                                          will add type=230 to the link and open in popup window with 500x600 pixels
+                       // 230 _blank                                           will add type=230 to the link and open with target "_blank"
+                       // 230x450:resizable=0,location=1       will open in popup window with 500x600 pixels with settings "resizable=0,location=1"
+               $matches = array();
+               $targetIsType = $LD['target'] && (string) intval($LD['target']) == trim($LD['target']) ? intval($LD['target']) : FALSE;
+               if (preg_match('/([0-9]+[\s])?(([0-9]+)x([0-9]+))?(:.+)?/s', $LD['target'], $matches) || $targetIsType) {
+                               // has type?
+                       if(intval($matches[1]) || $targetIsType) {
+                               $LD['totalURL'] = $this->parent_cObj->URLqMark(
+                                       $LD['totalURL'],
+                                       '&type=' . ($targetIsType ? $targetIsType : intval($matches[1]))
+                               );
+                               $LD['target'] = $targetIsType ?  '' : trim(substr($LD['target'], strlen($matches[1]) + 1));
+                       }
+                               // open in popup window?
+                       if ($matches[3] && $matches[4]) {
+                               $JSparamWH = 'width=' . $matches[3] . ',height=' . $matches[4] . ($matches[5] ? ',' . substr($matches[5], 1) : '');
+                               $onClick = 'vHWin=window.open(\'' . $LD['totalURL'] . '\',\'FEopenLink\',\'' . $JSparamWH . '\');vHWin.focus();return false;';
+                               $LD['target'] = '';
+                       }
+               }
+
                        // out:
                $list = array();
                $list['HREF'] = strlen($LD['totalURL']) ? $LD['totalURL'] : $GLOBALS['TSFE']->baseUrl;  // Added this check: What it does is to enter the baseUrl (if set, which it should for "realurl" based sites) as URL if the calculated value is empty. The problem is that no link is generated with a blank URL and blank URLs might appear when the realurl encoding is used and a link to the frontpage is generated.
@@ -1249,7 +1265,7 @@ class tslib_menu {
                        $addParams = $this->mconf['showAccessRestrictedPages.']['addParams'];
                        $addParams = str_replace('###RETURN_URL###',rawurlencode($LD['totalURL']),$addParams);
                        $addParams = str_replace('###PAGE_ID###',$page['uid'],$addParams);
-                       $LD = $this->tmpl->linkData($thePage,$mainTarget,'','','', $addParams, $typeOverride);
+                       $LD = $this->menuTypoLink($thePage,$mainTarget,'','','', $addParams, $typeOverride);
                }
        }
 
@@ -1273,6 +1289,11 @@ class tslib_menu {
                $cls = strtolower($this->conf[($this->menuNumber+1).$objSuffix]);
                $subLevelClass = ($cls && t3lib_div::inList($this->tmpl->menuclasses,$cls)) ? $cls : '';
 
+                       // stdWrap for expAll
+               if (isset($this->mconf['expAll.'])) {
+                       $this->mconf['expAll'] = $this->parent_cObj->stdWrap($this->mconf['expAll'], $this->mconf['expAll.']);
+               }
+
                if ($subLevelClass && ($this->mconf['expAll'] || $this->isNext($uid, $this->getMPvar($this->I['key'])) || is_array($altArray)) && !$this->mconf['sectionIndex'])        {
                        $submenu = t3lib_div::makeInstance('tslib_'.$subLevelClass);
                        $submenu->entryLevel = $this->entryLevel+1;
@@ -1283,7 +1304,7 @@ class tslib_menu {
                        }
 
                                // especially scripts that build the submenu needs the parent data
-                       $submenu->parent_cObj = &$this->parent_cObj;
+                       $submenu->parent_cObj = $this->parent_cObj;
                        $submenu->parentMenuArr = $this->menuArr;
 
                                // Setting alternativeMenuTempArray (will be effective only if an array)
@@ -1293,17 +1314,25 @@ class tslib_menu {
 
                        if ($submenu->start($this->tmpl, $this->sys_page, $uid, $this->conf, $this->menuNumber+1, $objSuffix))  {
                                $submenu->makeMenu();
-                               return $submenu->writeMenu();
+                                       // Memorize the current menu item count
+                               $tempCountMenuObj = $GLOBALS['TSFE']->register['count_MENUOBJ'];
+                                       // Reset the menu item count for the submenu
+                               $GLOBALS['TSFE']->register['count_MENUOBJ'] = 0;
+                               $content = $submenu->writeMenu();
+                                       // Restore the item count now that the submenu has been handled
+                               $GLOBALS['TSFE']->register['count_MENUOBJ'] = $tempCountMenuObj;
+                               $GLOBALS['TSFE']->register['count_menuItems'] = count($this->menuArr);
+                               return $content;
                        }
                }
        }
 
        /**
-        * Returns true if the page with UID $uid is the NEXT page in root line (which means a submenu should be drawn)
+        * Returns TRUE if the page with UID $uid is the NEXT page in root line (which means a submenu should be drawn)
         *
         * @param       integer         Page uid to evaluate.
         * @param       string          MPvar for the current position of item.
-        * @return      boolean         True if page with $uid is active
+        * @return      boolean         TRUE if page with $uid is active
         * @access private
         * @see subMenu()
         */
@@ -1321,11 +1350,11 @@ class tslib_menu {
        }
 
        /**
-        * Returns true if the page with UID $uid is active (in the current rootline)
+        * Returns TRUE if the page with UID $uid is active (in the current rootline)
         *
         * @param       integer         Page uid to evaluate.
         * @param       string          MPvar for the current position of item.
-        * @return      boolean         True if page with $uid is active
+        * @return      boolean         TRUE if page with $uid is active
         * @access private
         */
        function isActive($uid, $MPvar='')      {
@@ -1342,11 +1371,11 @@ class tslib_menu {
        }
 
        /**
-        * Returns true if the page with UID $uid is the CURRENT page (equals $GLOBALS['TSFE']->id)
+        * Returns TRUE if the page with UID $uid is the CURRENT page (equals $GLOBALS['TSFE']->id)
         *
         * @param       integer         Page uid to evaluate.
         * @param       string          MPvar for the current position of item.
-        * @return      boolean         True if page $uid = $GLOBALS['TSFE']->id
+        * @return      boolean         TRUE if page $uid = $GLOBALS['TSFE']->id
         * @access private
         */
        function isCurrent($uid, $MPvar='')     {
@@ -1357,27 +1386,57 @@ class tslib_menu {
        }
 
        /**
-        * Returns true if there is a submenu with items for the page id, $uid
+        * Returns TRUE if there is a submenu with items for the page id, $uid
         * Used by the item states "IFSUB", "ACTIFSUB" and "CURIFSUB" to check if there is a submenu
         *
-        * @param       integer         Page uid for which to search for a submenu
-        * @return      boolean         Returns true if there was a submenu with items found
+        * @param int $uid Page uid for which to search for a submenu
+        * @return boolean Returns TRUE if there was a submenu with items found
         * @access private
         */
-       function isSubMenu($uid)        {
-
-                       // Looking for a mount-pid for this UID since if that exists we should look for a subpages THERE and not in the input $uid;
+       function isSubMenu($uid) {
+                       // Looking for a mount-pid for this UID since if that
+                       // exists we should look for a subpages THERE and not in the input $uid;
                $mount_info = $this->sys_page->getMountPointInfo($uid);
-               if (is_array($mount_info))      {
+               if (is_array($mount_info)) {
                        $uid = $mount_info['mount_pid'];
                }
 
-               $recs = $this->sys_page->getMenu($uid,'uid,pid,doktype,mount_pid,mount_pid_ol,nav_hide,shortcut,shortcut_mode');
-               foreach($recs as $theRec)       {
-                       if (!t3lib_div::inList($this->doktypeExcludeList,$theRec['doktype']) && (!$theRec['nav_hide'] || $this->conf['includeNotInMenu']))      {       // If a menu item seems to be another type than 'Not in menu', then return true (there were items!)
-                               return TRUE;
+               $recs = $this->sys_page->getMenu(
+                       $uid,
+                       'uid,pid,doktype,mount_pid,mount_pid_ol,nav_hide,shortcut,shortcut_mode,l18n_cfg'
+               );
+
+               $hasSubPages = FALSE;
+               foreach ($recs as $theRec) {
+                               // no valid subpage if the document type is excluded from the menu
+                       if (t3lib_div::inList($this->doktypeExcludeList, $theRec['doktype'])) {
+                               continue;
+                       }
+
+                               // no valid subpage if the page is hidden inside menus and
+                               // it wasn't forced to show such entries
+                       if ($theRec['nav_hide'] && !$this->conf['includeNotInMenu']) {
+                               continue;
+                       }
+
+                               // no valid subpage if the default language should be shown and the page settings
+                               // are excluding the visibility of the default language
+                       if (!$GLOBALS['TSFE']->sys_language_uid && t3lib_div::hideIfDefaultLanguage($theRec['l18n_cfg'])) {
+                               continue;
+                       }
+
+                               // no valid subpage if the alternative language should be shown and the page settings
+                               // are requiring a valid overlay but it doesn't exists
+                       $hideIfNotTranslated = t3lib_div::hideIfNotTranslated($theRec['l18n_cfg']);
+                       if ($GLOBALS['TSFE']->sys_language_uid && $hideIfNotTranslated && !$theRec['_PAGES_OVERLAY']) {
+                               continue;
                        }
+
+                       $hasSubPages = TRUE;
+                       break;
                }
+
+               return $hasSubPages;
        }
 
        /**
@@ -1385,7 +1444,7 @@ class tslib_menu {
         *
         * @param       string          The item state to evaluate (SPC, IFSUB, ACT etc... but no xxxRO states of course)
         * @param       integer         Key pointing to menu item from ->menuArr
-        * @return      boolean         True (integer!=0) if match, otherwise false (=0, zero)
+        * @return      boolean         True (integer!=0) if match, otherwise FALSE (=0, zero)
         * @access private
         * @see procesItemStates()
         */
@@ -1460,8 +1519,8 @@ class tslib_menu {
        function userProcess($mConfKey,$passVar)        {
                if ($this->mconf[$mConfKey])    {
                        $funcConf = $this->mconf[$mConfKey.'.'];
-                       $funcConf['parentObj']=&$this;
-                       $passVar = $GLOBALS['TSFE']->cObj->callUserFunction($this->mconf[$mConfKey], $funcConf, $passVar);
+                       $funcConf['parentObj'] = $this;
+                       $passVar = $this->parent_cObj->callUserFunction($this->mconf[$mConfKey], $funcConf, $passVar);
                }
                return $passVar;
        }
@@ -1525,7 +1584,7 @@ class tslib_menu {
        function getBannedUids() {
                $banUidArray = array();
 
-               if (trim($this->conf['excludeUidList']))        {
+               if (trim($this->conf['excludeUidList'])) {
                        $banUidList = str_replace('current', $GLOBALS['TSFE']->page['uid'], $this->conf['excludeUidList']);
                        $banUidArray = t3lib_div::intExplode(',', $banUidList);
                }
@@ -1533,6 +1592,114 @@ class tslib_menu {
                return $banUidArray;
        }
 
+       /**
+        * Calls typolink to create menu item links.
+        *
+        * @param       array           $page   Page record (uid points where to link to)
+        * @param       string          $oTarget        Target frame/window
+        * @param       boolean         $no_cache       TRUE if caching should be disabled
+        * @param       string          $script Alternative script name
+        * @param       array           $overrideArray  Array to override values in $page
+        * @param       string          $addParams      Parameters to add to URL
+        * @param       array           $typeOverride   "type" value
+        * @return      array           See linkData
+        */
+       function menuTypoLink($page, $oTarget, $no_cache, $script, $overrideArray = '', $addParams = '', $typeOverride = '') {
+               $conf = array(
+                       'parameter' => is_array($overrideArray) && $overrideArray['uid'] ? $overrideArray['uid'] : $page['uid'],
+               );
+               if ($typeOverride && t3lib_utility_Math::canBeInterpretedAsInteger($typeOverride)) {
+                       $conf['parameter'] .= ',' . $typeOverride;
+               }
+               if ($addParams) {
+                       $conf['additionalParams'] = $addParams;
+               }
+               if ($no_cache) {
+                       $conf['no_cache'] = TRUE;
+               }
+               if ($oTarget) {
+                       $conf['target'] = $oTarget;
+               }
+               if ($page['sectionIndex_uid']) {
+                       $conf['section'] = $page['sectionIndex_uid'];
+               }
+
+               $this->parent_cObj->typoLink('|', $conf);
+               $LD = $this->parent_cObj->lastTypoLinkLD;
+               $LD['totalURL'] = $this->parent_cObj->lastTypoLinkUrl;
+               return $LD;
+       }
+
+       /**
+        * Generates a list of content objects with sectionIndex enabled
+        * available on a specific page
+        *
+        * Used for menu's with sectionIndex enabled
+        *
+        * @param string $altSortField Alternative sorting field
+        * @param integer $pid The page id to search for sections
+        * @return array
+        */
+       protected function sectionIndex($altSortField, $pid = NULL) {
+               $where = 'colPos=0';
+
+               if (!$pid) {
+                       $pid = $this->id;
+                       if ($GLOBALS['TSFE']->sys_language_uid && count($this->sys_page->getPageOverlay($pid))) {
+                               $where .= ' AND sys_language_uid=' . intval($GLOBALS['TSFE']->sys_language_uid);
+                       } else {
+                               $where .= ' AND sys_language_uid=0';
+                       }
+               }
+
+               $selectSetup = array(
+                       'pidInList' => $pid,
+                       'orderBy' => $altSortField,
+                       'where' => $where,
+                       'andWhere' => 'sectionIndex<>0'
+               );
+               switch ($this->mconf['sectionIndex.']['type']) {
+                       case 'all':
+                               unset($selectSetup['andWhere']);
+                       break;
+                       case 'header':
+                               $selectSetup['andWhere'] .= ' AND header_layout<>100 AND header!=""';
+                       break;
+               }
+               $basePageRow = $this->sys_page->getPage($pid);
+               $result = array();
+               if (is_array($basePageRow)) {
+                       $res = $this->parent_cObj->exec_getQuery('tt_content', $selectSetup);
+
+                       while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
+                               $GLOBALS['TSFE']->sys_page->versionOL('tt_content', $row);
+
+                               if (is_array($row)) {
+                                       $result[$row['uid']] = $basePageRow;
+                                       $result[$row['uid']]['title'] = $row['header'];
+                                       $result[$row['uid']]['nav_title'] = $row['header'];
+                                       $result[$row['uid']]['subtitle'] = $row['subheader'];
+                                       $result[$row['uid']]['starttime'] = $row['starttime'];
+                                       $result[$row['uid']]['endtime'] = $row['endtime'];
+                                       $result[$row['uid']]['fe_group'] = $row['fe_group'];
+                                       $result[$row['uid']]['media'] = $row['media'];
+
+                                       $result[$row['uid']]['header_layout'] = $row['header_layout'];
+                                       $result[$row['uid']]['bodytext'] = $row['bodytext'];
+                                       $result[$row['uid']]['image'] = $row['image'];
+
+                                       $result[$row['uid']]['sectionIndex_uid'] = $row['uid'];
+                               }
+                       }
+
+                       if (is_resource($res)) {
+                               $GLOBALS['TYPO3_DB']->sql_free_result($res);
+                       }
+               }
+
+               return $result;
+       }
+
 }
 
 
@@ -1556,10 +1723,9 @@ class tslib_menu {
 /**
  * Extension class creating text based menus
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage tslib
- * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=387&cHash=73a3116ab8
  */
 class tslib_tmenu extends tslib_menu {
 
@@ -1575,7 +1741,10 @@ class tslib_tmenu extends tslib_menu {
                if ($splitCount)        {
                        list($NOconf) = $this->procesItemStates($splitCount);
                }
-               if ($this->mconf['debugItemConf'])      {echo '<h3>$NOconf:</h3>';      debug($NOconf); }
+               if ($this->mconf['debugItemConf']) {
+                       echo '<h3>$NOconf:</h3>';
+                       debug($NOconf);
+               }
                $this->result = $NOconf;
        }
 
@@ -1596,8 +1765,7 @@ class tslib_tmenu extends tslib_menu {
                        $this->WMsubmenuObjSuffixes = $this->tmpl->splitConfArray(array('sOSuffix'=>$this->mconf['submenuObjSuffixes']),$this->WMmenuItems);
 
                        $this->extProc_init();
-                       reset($this->result);
-                       while (list($key,$val)=each($this->result))     {
+                       foreach ($this->result as $key => $val) {
                                $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ']++;
                                $GLOBALS['TSFE']->register['count_MENUOBJ']++;
 
@@ -1607,7 +1775,9 @@ class tslib_tmenu extends tslib_menu {
                                $this->I['key'] = $key;
                                $this->I['INPfix'] = ($this->imgNameNotRandom ? '' : '_'.$this->INPfixMD5).'_'.$key;
                                $this->I['val'] = $val;
-                               $this->I['title'] = $this->WMcObj->stdWrap($this->getPageTitle($this->menuArr[$key]['title'],$this->menuArr[$key]['nav_title']),$this->I['val']['stdWrap.']);
+                               $this->I['title'] = isset($this->I['val']['stdWrap.'])
+                                       ? $this->WMcObj->stdWrap($this->getPageTitle($this->menuArr[$key]['title'], $this->menuArr[$key]['nav_title']), $this->I['val']['stdWrap.'])
+                                       : $this->getPageTitle($this->menuArr[$key]['title'],$this->menuArr[$key]['nav_title']);
                                $this->I['uid'] = $this->menuArr[$key]['uid'];
                                $this->I['mount_pid'] = $this->menuArr[$key]['mount_pid'];
                                $this->I['pid'] = $this->menuArr[$key]['pid'];
@@ -1622,11 +1792,15 @@ class tslib_tmenu extends tslib_menu {
 
                                        // Make link tag
                                $this->I['val']['ATagParams'] = $this->WMcObj->getATagParams($this->I['val']);
-                               $this->I['val']['additionalParams'] = $this->WMcObj->stdWrap($this->I['val']['additionalParams'],$this->I['val']['additionalParams.']);
+                               if(isset($this->I['val']['additionalParams.'])) {
+                                       $this->I['val']['additionalParams'] = $this->WMcObj->stdWrap($this->I['val']['additionalParams'], $this->I['val']['additionalParams.']);
+                               }
                                $this->I['linkHREF'] = $this->link($key,$this->I['val']['altTarget'],$this->mconf['forceTypeValue']);
 
                                        // Title attribute of links:
-                               $titleAttrValue = $this->WMcObj->stdWrap($this->I['val']['ATagTitle'],$this->I['val']['ATagTitle.']).$this->I['accessKey']['alt'];
+                               $titleAttrValue = isset($this->I['val']['ATagTitle.'])
+                                       ? $this->WMcObj->stdWrap($this->I['val']['ATagTitle'], $this->I['val']['ATagTitle.']) . $this->I['accessKey']['alt']
+                                       : $this->I['val']['ATagTitle'].$this->I['accessKey']['alt'];
                                if (strlen($titleAttrValue))    {
                                        $this->I['linkHREF']['title'] = $titleAttrValue;
                                }
@@ -1668,6 +1842,11 @@ class tslib_tmenu extends tslib_menu {
                                        // Calling extra processing function
                                $this->extProc_beforeLinking($key);
 
+                                       // stdWrap for doNotLinkIt
+                               if (isset($this->I['val']['doNotLinkIt.'])) {
+                                       $this->I['val']['doNotLinkIt'] = $this->WMcObj->stdWrap($this->I['val']['doNotLinkIt'], $this->I['val']['doNotLinkIt.']);
+                               }
+
                                        // Compile link tag
                                if (!$this->I['val']['doNotLinkIt']) {$this->I['val']['doNotLinkIt']=0;}
                                if (!$this->I['spacer'] && $this->I['val']['doNotLinkIt']!=1)   {
@@ -1686,13 +1865,22 @@ class tslib_tmenu extends tslib_menu {
                                        $wrapPartsAfter = explode('|',$this->I['val']['linkWrap']);
                                }
                                if ($this->I['val']['stdWrap2'] || isset($this->I['val']['stdWrap2.'])) {
-                                       $wrapPartsStdWrap = explode($this->I['val']['stdWrap2']?$this->I['val']['stdWrap2']:'|',$this->WMcObj->stdWrap('|',$this->I['val']['stdWrap2.']));
+                                       $stdWrap2 = isset($this->I['val']['stdWrap2.'])
+                                               ? $this->WMcObj->stdWrap('|', $this->I['val']['stdWrap2.'])
+                                               : '|';
+                                       $wrapPartsStdWrap = explode($this->I['val']['stdWrap2'] ? $this->I['val']['stdWrap2'] : '|', $stdWrap2);
                                } else {$wrapPartsStdWrap = array('','');}
 
                                        // Make before, middle and after parts
                                $this->I['parts'] = array();
                                $this->I['parts']['before']=$this->getBeforeAfter('before');
                                $this->I['parts']['stdWrap2_begin']=$wrapPartsStdWrap[0];
+
+                                       // stdWrap for doNotShowLink
+                               if (isset($this->I['val']['doNotShowLink.'])) {
+                                       $this->I['val']['doNotShowLink'] = $this->WMcObj->stdWrap($this->I['val']['doNotShowLink'], $this->I['val']['doNotShowLink.']);
+                               }
+
                                if (!$this->I['val']['doNotShowLink']) {
                                        $this->I['parts']['notATagBeforeWrap_begin'] = $wrapPartsAfter[0];
                                        $this->I['parts']['ATag_begin'] = $this->I['A1'];
@@ -1715,14 +1903,16 @@ class tslib_tmenu extends tslib_menu {
                                $this->I['theItem']= $this->extProc_beforeAllWrap($this->I['theItem'],$key);
 
                                        // allWrap:
-                               $allWrap = $this->WMcObj->stdWrap($this->I['val']['allWrap'],$this->I['val']['allWrap.']);
+                               $allWrap = isset($this->I['val']['allWrap.'])
+                                       ? $this->WMcObj->stdWrap($this->I['val']['allWrap'], $this->I['val']['allWrap.'])
+                                       : $this->I['val']['allWrap'];
                                $this->I['theItem'] = $this->tmpl->wrap($this->I['theItem'],$allWrap);
 
                                if ($this->I['val']['subst_elementUid'])        $this->I['theItem'] = str_replace('{elementUid}',$this->I['uid'],$this->I['theItem']);
 
                                        // allStdWrap:
                                if (is_array($this->I['val']['allStdWrap.']))   {
-                                       $this->I['theItem'] = $this->WMcObj->stdWrap($this->I['theItem'],$this->I['val']['allStdWrap.']);
+                                       $this->I['theItem'] = $this->WMcObj->stdWrap($this->I['theItem'], $this->I['val']['allStdWrap.']);
                                }
 
                                        // Calling extra processing function
@@ -1737,7 +1927,6 @@ class tslib_tmenu extends tslib_menu {
         *
         * @param       string          Can be "before" or "after" and determines which kind of image to create (basically this is the prefix of the TypoScript properties that are read from the ->I['val'] array
         * @return      string          The resulting HTML of the image, if any.
-        * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=388&cHash=a7486044cd
         */
        function getBeforeAfter($pref)  {
                $res = '';
@@ -1749,17 +1938,34 @@ class tslib_tmenu extends tslib_menu {
                                if ($imgROInfo) {
                                        $theName = $this->imgNamePrefix.$this->I['uid'].$this->I['INPfix'].$pref;
                                        $name = ' '.$this->nameAttribute.'="'.$theName.'"';
-                                       $GLOBALS['TSFE']->JSImgCode.= chr(10).$theName.'_n=new Image(); '.$theName.'_n.src = "'.$GLOBALS['TSFE']->absRefPrefix.$imgInfo[3].'"; ';
-                                       $GLOBALS['TSFE']->JSImgCode.= chr(10).$theName.'_h=new Image(); '.$theName.'_h.src = "'.$GLOBALS['TSFE']->absRefPrefix.$imgROInfo[3].'"; ';
+                                       $GLOBALS['TSFE']->JSImgCode.= LF.$theName.'_n=new Image(); '.$theName.'_n.src = "'.$GLOBALS['TSFE']->absRefPrefix.$imgInfo[3].'"; ';
+                                       $GLOBALS['TSFE']->JSImgCode.= LF.$theName.'_h=new Image(); '.$theName.'_h.src = "'.$GLOBALS['TSFE']->absRefPrefix.$imgROInfo[3].'"; ';
                                }
                        }
                        $GLOBALS['TSFE']->imagesOnPage[]=$imgInfo[3];
-                       $res='<img src="'.$GLOBALS['TSFE']->absRefPrefix.$imgInfo[3].'" width="'.$imgInfo[0].'" height="'.$imgInfo[1].'"'.$name.($this->I['val'][$pref.'ImgTagParams']?" ".$this->I['val'][$pref.'ImgTagParams']:'').tslib_cObj::getBorderAttr('border="0"');
-                       if (!strstr($res,'alt="'))      $res.=' alt=""';        // Adding alt attribute if not set.
+                       $res='<img' .
+                               ' src="' . $GLOBALS['TSFE']->absRefPrefix . $imgInfo[3] . '"' .
+                               ' width="' . $imgInfo[0] . '"' .
+                               ' height="' . $imgInfo[1] . '"' .
+                               $name .
+                               ($this->I['val'][$pref.'ImgTagParams'] ? ' ' . $this->I['val'][$pref.'ImgTagParams'] : '') .
+                               tslib_cObj::getBorderAttr(' border="0"');
+                       if (!strstr($res,'alt="')) {
+                               $res .= ' alt=""'; // Adding alt attribute if not set.
+                       }
                        $res.=' />';
-                       if ($this->I['val'][$pref.'ImgLink'])   {$res=$this->I['A1'].$res.$this->I['A2'];}
+                       if ($this->I['val'][$pref.'ImgLink']) {
+                               $res=$this->I['A1'].$res.$this->I['A2'];
+                       }
+               }
+               $processedPref = isset($this->I['val'][$pref . '.'])
+                       ? $this->WMcObj->stdWrap($this->I['val'][$pref], $this->I['val'][$pref . '.'])
+                       : $this->I['val'][$pref];
+               if (isset($this->I['val'][$pref . 'Wrap'])) {
+                       return $this->tmpl->wrap($res . $processedPref, $this->I['val'][$pref . 'Wrap']);
+               } else {
+                       return $res . $processedPref;
                }
-               return $this->tmpl->wrap($res.$this->WMcObj->stdWrap($this->I['val'][$pref],$this->I['val'][$pref.'.']), $this->I['val'][$pref.'Wrap']);
        }
 
        /**
@@ -1776,9 +1982,9 @@ class tslib_tmenu extends tslib_menu {
                                        document.getElementById(id).style.background = color;
                                        return true;
                                } else if (document.layers && document.layers[id]) {
-                               document.layers[id].bgColor = color;
+                                       document.layers[id].bgColor = color;
                                        return true;
-                           }
+                               }
                        }
                ';
        }
@@ -1830,7 +2036,10 @@ class tslib_tmenu extends tslib_menu {
                if (!$this->I['spacer'])        {
                        $this->I['theItem'].= $this->subMenu($this->I['uid'], $this->WMsubmenuObjSuffixes[$key]['sOSuffix']);
                }
-               $this->WMresult.= $this->I['val']['wrapItemAndSub'] ? $this->tmpl->wrap($this->I['theItem'],$this->I['val']['wrapItemAndSub']) : $this->I['theItem'];
+               $part = isset($this->I['val']['wrapItemAndSub.'])
+                       ? $this->WMcObj->stdWrap($this->I['val']['wrapItemAndSub'], $this->I['val']['wrapItemAndSub.'])
+                       : $this->I['val']['wrapItemAndSub'];
+               $this->WMresult.= $part ? $this->tmpl->wrap($this->I['theItem'],$part) : $this->I['theItem'];
        }
 
        /**
@@ -1856,7 +2065,7 @@ class tslib_tmenu extends tslib_menu {
        function extProc_finish()       {
                        // stdWrap:
                if (is_array($this->mconf['stdWrap.'])) {
-                       $this->WMresult = $this->WMcObj->stdWrap($this->WMresult,$this->mconf['stdWrap.']);
+                       $this->WMresult = $this->WMcObj->stdWrap($this->WMresult, $this->mconf['stdWrap.']);
                }
                return $this->tmpl->wrap($this->WMresult,$this->mconf['wrap']).$this->WMextraScript;
        }
@@ -1888,10 +2097,9 @@ class tslib_tmenu extends tslib_menu {
 /**
  * Extension class creating graphic based menus (PNG or GIF files)
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage tslib
- * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=384&cHash=93a7644cba
  */
 class tslib_gmenu extends tslib_menu {
 
@@ -1916,13 +2124,19 @@ class tslib_gmenu extends tslib_menu {
                        $tempcnt_HMENU_MENUOBJ = $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ'];
                        $tempcnt_MENUOBJ = $GLOBALS['TSFE']->register['count_MENUOBJ'];
 
-                       if ($this->mconf['debugItemConf'])      {echo '<h3>$NOconf:</h3>';      debug($NOconf); }
+                       if ($this->mconf['debugItemConf']) {
+                               echo '<h3>$NOconf:</h3>';
+                               debug($NOconf);
+                       }
                        if ($ROconf)    {               // RollOver
                                        //start recount for rollover with initial values
                                $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ']= $temp_HMENU_MENUOBJ;
                                $GLOBALS['TSFE']->register['count_MENUOBJ']= $temp_MENUOBJ;
                                $this->makeGifs($ROconf,'RO');
-                               if ($this->mconf['debugItemConf'])      {echo '<h3>$ROconf:</h3>';      debug($ROconf); }
+                               if ($this->mconf['debugItemConf']) {
+                                       echo '<h3>$ROconf:</h3>';
+                                       debug($ROconf);
+                               }
                        }
                                // use count from NO obj
                        $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ'] = $tempcnt_HMENU_MENUOBJ;
@@ -1977,8 +2191,7 @@ class tslib_gmenu extends tslib_menu {
                $c=0;
                $maxFlag=0;
                $distributeAccu=array('H'=>0,'W'=>0);
-               reset($conf);
-               while (list($key,$val)=each($conf))     {
+               foreach ($conf as $key => $val) {
                        $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ']++;
                        $GLOBALS['TSFE']->register['count_MENUOBJ']++;
 
@@ -1986,8 +2199,7 @@ class tslib_gmenu extends tslib_menu {
                                $Lobjs = $this->mconf['removeObjectsOfDummy'];
                                if ($Lobjs)     {
                                        $Lobjs = t3lib_div::intExplode(',',$Lobjs);
-                                       reset($Lobjs);
-                                       while(list(,$remItem)=each($Lobjs))     {
+                                       foreach ($Lobjs as $remItem) {
                                                unset($val[$remItem]);
                                                unset($val[$remItem.'.']);
                                        }
@@ -1995,8 +2207,14 @@ class tslib_gmenu extends tslib_menu {
 
                                $flag =0;
                                $tempXY = explode(',',$val['XY']);
-                               if ($Wcounter<$minDim[0])       {$tempXY[0]=$minDim[0]-$Wcounter; $flag=1;}
-                               if ($Hcounter<$minDim[1])       {$tempXY[1]=$minDim[1]-$Hcounter; $flag=1;}
+                               if ($Wcounter<$minDim[0]) {
+                                       $tempXY[0] = $minDim[0] - $Wcounter;
+                                       $flag = 1;
+                               }
+                               if ($Hcounter<$minDim[1]) {
+                                       $tempXY[1] = $minDim[1] - $Hcounter;
+                                       $flag = 1;
+                               }
                                $val['XY'] = implode(',',$tempXY);
                                if (!$flag){break;}
                        }
@@ -2047,8 +2265,14 @@ class tslib_gmenu extends tslib_menu {
                                        // If max dimensions are specified
                                if ($maxDim)    {
                                        $tempXY = explode(',',$val['XY']);
-                                       if ($maxDim[0] && $Wcounter+$gifCreator->XY[0]>=$maxDim[0])     {$tempXY[0]==$maxDim[0]-$Wcounter; $maxFlag=1;}
-                                       if ($maxDim[1] && $Hcounter+$gifCreator->XY[1]>=$maxDim[1])     {$tempXY[1]=$maxDim[1]-$Hcounter; $maxFlag=1;}
+                                       if ($maxDim[0] && $Wcounter + $gifCreator->XY[0] >= $maxDim[0]) {
+                                               $tempXY[0] == $maxDim[0] - $Wcounter;
+                                               $maxFlag = 1;
+                                       }
+                                       if ($maxDim[1] && $Hcounter + $gifCreator->XY[1] >= $maxDim[1]) {
+                                               $tempXY[1] = $maxDim[1] - $Hcounter;
+                                               $maxFlag = 1;
+                                       }
                                        if ($maxFlag)   {
                                                $val['XY'] = implode(',',$tempXY);
                                                $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder');
@@ -2062,8 +2286,7 @@ class tslib_gmenu extends tslib_menu {
 
                                // displace
                                if ($Hobjs)     {
-                                       reset($Hobjs);
-                                       while(list(,$index)=each($Hobjs))       {
+                                       foreach ($Hobjs as $index) {
                                                if ($gifCreator->setup[$index] && $gifCreator->setup[$index.'.'])       {
                                                        $oldOffset = explode(',',$gifCreator->setup[$index.'.']['offset']);
                                                        $gifCreator->setup[$index.'.']['offset'] = implode(',',$gifCreator->applyOffset($oldOffset,Array(0,-$Hcounter)));
@@ -2072,8 +2295,7 @@ class tslib_gmenu extends tslib_menu {
                                }
 
                                if ($Wobjs)     {
-                                       reset($Wobjs);
-                                       while(list(,$index)=each($Wobjs))       {
+                                       foreach ($Wobjs as $index) {
                                                if ($gifCreator->setup[$index] && $gifCreator->setup[$index.'.'])       {
                                                        $oldOffset = explode(',',$gifCreator->setup[$index.'.']['offset']);
                                                        $gifCreator->setup[$index.'.']['offset'] = implode(',',$gifCreator->applyOffset($oldOffset,Array(-$Wcounter,0)));
@@ -2100,7 +2322,7 @@ class tslib_gmenu extends tslib_menu {
                        $this->result[$resKey][$key] = $conf[$key];
 
                                // Generation of image file:
-                       if (@file_exists($gifFileName)) {               // File exists
+                       if (file_exists($gifFileName))  {               // File exists
                                $info = @getimagesize($gifFileName);
                                $this->result[$resKey][$key]['output_w']=intval($info[0]);
                                $this->result[$resKey][$key]['output_h']=intval($info[1]);
@@ -2150,15 +2372,13 @@ class tslib_gmenu extends tslib_menu {
                $Wcounter = 0;
                $c=0;
                $maxFlag=0;
-               reset($conf);
-               while (list($key,$val)=each($conf))     {
+               foreach ($conf as $key => $val) {
                        // SAME CODE AS makeGifs()! BEGIN
                        if ($items==($c+1) && $minDim)  {
                                $Lobjs = $this->mconf['removeObjectsOfDummy'];
                                if ($Lobjs)     {
                                        $Lobjs = t3lib_div::intExplode(',',$Lobjs);
-                                       reset($Lobjs);
-                                       while(list(,$remItem)=each($Lobjs))     {
+                                       foreach ($Lobjs as $remItem) {
                                                unset($val[$remItem]);
                                                unset($val[$remItem.'.']);
                                        }
@@ -2166,8 +2386,14 @@ class tslib_gmenu extends tslib_menu {
 
                                $flag =0;
                                $tempXY = explode(',',$val['XY']);
-                               if ($Wcounter<$minDim[0])       {$tempXY[0]=$minDim[0]-$Wcounter; $flag=1;}
-                               if ($Hcounter<$minDim[1])       {$tempXY[1]=$minDim[1]-$Hcounter; $flag=1;}
+                               if ($Wcounter < $minDim[0]) {
+                                       $tempXY[0] = $minDim[0] - $Wcounter;
+                                       $flag = 1;
+                               }
+                               if ($Hcounter < $minDim[1]) {
+                                       $tempXY[1] = $minDim[1] - $Hcounter;
+                                       $flag = 1;
+                               }
                                $val['XY'] = implode(',',$tempXY);
                                if (!$flag){break;}
                        }
@@ -2178,8 +2404,14 @@ class tslib_gmenu extends tslib_menu {
                        $gifCreator->start($val,$this->menuArr[$key]);
                        if ($maxDim)    {
                                $tempXY = explode(',',$val['XY']);
-                               if ($maxDim[0] && $Wcounter+$gifCreator->XY[0]>=$maxDim[0])     {$tempXY[0]==$maxDim[0]-$Wcounter; $maxFlag=1;}
-                               if ($maxDim[1] && $Hcounter+$gifCreator->XY[1]>=$maxDim[1])     {$tempXY[1]=$maxDim[1]-$Hcounter; $maxFlag=1;}
+                               if ($maxDim[0] && $Wcounter + $gifCreator->XY[0] >= $maxDim[0]) {
+                                       $tempXY[0] == $maxDim[0] - $Wcounter;
+                                       $maxFlag = 1;
+                               }
+                               if ($maxDim[1] && $Hcounter + $gifCreator->XY[1] >= $maxDim[1]) {
+                                       $tempXY[1] = $maxDim[1] - $Hcounter;
+                                       $maxFlag = 1;
+                               }
                                if ($maxFlag)   {
                                        $val['XY'] = implode(',',$tempXY);
                                        $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder');
@@ -2246,11 +2478,15 @@ class tslib_gmenu extends tslib_menu {
 
                                                // Make link tag
                                        $this->I['val']['ATagParams'] = $this->WMcObj->getATagParams($this->I['val']);
-                                       $this->I['val']['additionalParams'] = $this->WMcObj->stdWrap($this->I['val']['additionalParams'],$this->I['val']['additionalParams.']);
+                                       if (isset($this->I['val']['additionalParams.'])) {
+                                               $this->I['val']['additionalParams'] = $this->WMcObj->stdWrap($this->I['val']['additionalParams'], $this->I['val']['additionalParams.']);
+                                       }
                                        $this->I['linkHREF'] = $this->link($key,$this->I['val']['altTarget'],$this->mconf['forceTypeValue']);
 
                                                // Title attribute of links:
-                                       $titleAttrValue = $this->WMcObj->stdWrap($this->I['val']['ATagTitle'],$this->I['val']['ATagTitle.']).$this->I['accessKey']['alt'];
+                                       $titleAttrValue = isset($this->I['val']['ATagTitle.'])
+                                               ? $this->WMcObj->stdWrap($this->I['val']['ATagTitle'], $this->I['val']['ATagTitle.']) . $this->I['accessKey']['alt']
+                                               : $this->I['val']['ATagTitle'].$this->I['accessKey']['alt'];
                                        if (strlen($titleAttrValue))    {
                                                $this->I['linkHREF']['title'] = $titleAttrValue;
                                        }
@@ -2265,8 +2501,8 @@ class tslib_gmenu extends tslib_menu {
                                                $this->I['name'] = ' '.$this->nameAttribute.'="'.$this->I["theName"].'"';
                                                $this->I['linkHREF']['onMouseover']=$this->WMfreezePrefix.'over(\''.$this->I['theName'].'\');';
                                                $this->I['linkHREF']['onMouseout']=$this->WMfreezePrefix.'out(\''.$this->I['theName'].'\');';
-                                               $GLOBALS['TSFE']->JSImgCode.= chr(10).$this->I['theName'].'_n=new Image(); '.$this->I['theName'].'_n.src = "'.$GLOBALS['TSFE']->absRefPrefix.$this->I['val']['output_file'].'"; ';
-                                               $GLOBALS['TSFE']->JSImgCode.= chr(10).$this->I['theName'].'_h=new Image(); '.$this->I['theName'].'_h.src = "'.$GLOBALS['TSFE']->absRefPrefix.$this->result['RO'][$key]['output_file'].'"; ';
+                                               $GLOBALS['TSFE']->JSImgCode.= LF.$this->I['theName'].'_n=new Image(); '.$this->I['theName'].'_n.src = "'.$GLOBALS['TSFE']->absRefPrefix.$this->I['val']['output_file'].'"; ';
+                                               $GLOBALS['TSFE']->JSImgCode.= LF.$this->I['theName'].'_h=new Image(); '.$this->I['theName'].'_h.src = "'.$GLOBALS['TSFE']->absRefPrefix.$this->result['RO'][$key]['output_file'].'"; ';
                                                $GLOBALS['TSFE']->imagesOnPage[]=$this->result['RO'][$key]['output_file'];
                                                $GLOBALS['TSFE']->setJS('mouseOver');
                                                $this->extProc_RO($key);
@@ -2307,14 +2543,16 @@ class tslib_gmenu extends tslib_menu {
                                        $this->I['theItem']= $this->tmpl->wrap($this->I['theItem'],$this->I['val']['wrap']);
 
                                                // allWrap:
-                                       $allWrap = $this->WMcObj->stdWrap($this->I['val']['allWrap'],$this->I['val']['allWrap.']);
+                                       $allWrap = isset($this->I['val']['allWrap.'])
+                                               ? $this->WMcObj->stdWrap($this->I['val']['allWrap'], $this->I['val']['allWrap.'])
+                                               : $this->I['val']['allWrap'];
                                        $this->I['theItem'] = $this->tmpl->wrap($this->I['theItem'],$allWrap);
 
                                        if ($this->I['val']['subst_elementUid'])        $this->I['theItem'] = str_replace('{elementUid}',$this->I['uid'],$this->I['theItem']);
 
                                                // allStdWrap:
                                        if (is_array($this->I['val']['allStdWrap.']))   {
-                                               $this->I['theItem'] = $this->WMcObj->stdWrap($this->I['theItem'],$this->I['val']['allStdWrap.']);
+                                               $this->I['theItem'] = $this->WMcObj->stdWrap($this->I['theItem'], $this->I['val']['allStdWrap.']);
                                        }
 
                                        $GLOBALS['TSFE']->imagesOnPage[]=$this->I['val']['output_file'];
@@ -2370,10 +2608,14 @@ class tslib_gmenu extends tslib_menu {
         * @see writeMenu(), tslib_gmenu_layers::extProc_afterLinking(), tslib_menu::subMenu()
         */
        function extProc_afterLinking($key)     {
-               $this->WMresult.=$this->I['theItem'];
+                       // Add part to the accumulated result + fetch submenus
                if (!$this->I['spacer'])        {
-                       $this->WMresult.= $this->subMenu($this->I['uid'], $this->WMsubmenuObjSuffixes[$key]['sOSuffix']);
+                       $this->I['theItem'].= $this->subMenu($this->I['uid'], $this->WMsubmenuObjSuffixes[$key]['sOSuffix']);
                }
+               $part = isset($this->I['val']['wrapItemAndSub.'])
+                       ? $this->WMcObj->stdWrap($this->I['val']['wrapItemAndSub'], $this->I['val']['wrapItemAndSub.'])
+                       : $this->I['val']['wrapItemAndSub'];
+               $this->WMresult.= $part ? $this->tmpl->wrap($this->I['theItem'],$part) : $this->I['theItem'];
        }
 
 
@@ -2400,7 +2642,7 @@ class tslib_gmenu extends tslib_menu {
        function extProc_finish()       {
                        // stdWrap:
                if (is_array($this->mconf['stdWrap.'])) {
-                       $this->WMresult = $this->WMcObj->stdWrap($this->WMresult,$this->mconf['stdWrap.']);
+                       $this->WMresult = $this->WMcObj->stdWrap($this->WMresult, $this->mconf['stdWrap.']);
                }
                return $this->tmpl->wrap($this->WMresult,$this->mconf['wrap']).$this->WMextraScript;
        }
@@ -2430,10 +2672,9 @@ class tslib_gmenu extends tslib_menu {
 /**
  * ImageMap based menus
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage tslib
- * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=389&cHash=fcf18c5d9f
  */
 class tslib_imgmenu extends tslib_menu {
 
@@ -2449,7 +2690,10 @@ class tslib_imgmenu extends tslib_menu {
                if ($splitCount)        {
                        list($NOconf) = $this->procesItemStates($splitCount);
                }
-               if ($this->mconf['debugItemConf'])      {echo '<h3>$NOconf:</h3>';      debug($NOconf); }
+               if ($this->mconf['debugItemConf']) {
+                       echo '<h3>$NOconf:</h3>';
+                       debug($NOconf);
+               }
                $this->makeImageMap($NOconf);
        }
 
@@ -2481,9 +2725,8 @@ class tslib_imgmenu extends tslib_menu {
                                $lastOriginal = $gifObjCount;
 
                                        // Now we add graphical objects to the gifbuilder-setup
-                               reset($itemsConf);
                                $waArr = Array();
-                               while (list($key,$val)=each($itemsConf))        {
+                               foreach ($itemsConf as $key => $val) {
                                        if (is_array($val))     {
                                                $gifObjCount++;
                                                $waArr[$key]['free']=$gifObjCount;
@@ -2506,7 +2749,7 @@ class tslib_imgmenu extends tslib_menu {
                                                                        unset($theValArr['text.']);     // if this is not done it seems that imageMaps will be rendered wrong!!
                                                                                // check links
 
-                                                                       $LD = $this->tmpl->linkData($this->menuArr[$key],$this->mconf['target'],'','',array(),'',$this->mconf['forceTypeValue']);
+                                                                       $LD = $this->menuTypoLink($this->menuArr[$key],$this->mconf['target'],'','',array(),'',$this->mconf['forceTypeValue']);
 
                                                                                // If access restricted pages should be shown in menus, change the link of such pages to link to a redirection page:
                                                                        $this->changeLinksForAccessRestrictedPages($LD, $this->menuArr[$key], $this->mconf['target'], $this->mconf['forceTypeValue']);
@@ -2530,13 +2773,17 @@ class tslib_imgmenu extends tslib_menu {
                                                                        if (is_array($theValArr['imgMap.']['altText.']))        {
                                                                                $cObj =t3lib_div::makeInstance('tslib_cObj');
                                                                                $cObj->start($cObjData,'pages');
-                                                                               $theValArr['imgMap.']['altText'] = $cObj->stdWrap($theValArr['imgMap.']['altText'], $theValArr['imgMap.']['altText.']);
+                                                                               if(isset($theValArr['imgMap.']['altText.'])) {
+                                                                                       $theValArr['imgMap.']['altText'] = $cObj->stdWrap($theValArr['imgMap.']['altText'], $theValArr['imgMap.']['altText.']);
+                                                                               }
                                                                                unset($theValArr['imgMap.']['altText.']);
                                                                }
                                                                        if (is_array($theValArr['imgMap.']['titleText.']))      {
                                                                                $cObj =t3lib_div::makeInstance('tslib_cObj');
                                                                                $cObj->start($cObjData,'pages');
-                                                                               $theValArr['imgMap.']['titleText'] = $cObj->stdWrap($theValArr['imgMap.']['titleText'], $theValArr['imgMap.']['titleText.']);
+                                                                               if(isset($theValArr['imgMap.']['titleText.'])) {
+                                                                                       $theValArr['imgMap.']['titleText'] = $cObj->stdWrap($theValArr['imgMap.']['titleText'], $theValArr['imgMap.']['titleText.']);
+                                                                               }
                                                                                unset($theValArr['imgMap.']['titleText.']);
                                                                        }
                                                                }
@@ -2544,8 +2791,7 @@ class tslib_imgmenu extends tslib_menu {
                                                                if ($theValue=='IMAGE') {
                                                                        if ($theValArr['file']=='GIFBUILDER')   {
                                                                                $temp_sKeyArray=t3lib_TStemplate::sortedKeyList($theValArr['file.']);
-                                                                               reset($temp_sKeyArray);
-                                                                               while(list(,$temp_theKey)=each($temp_sKeyArray))        {
+                                                                               foreach ($temp_sKeyArray as $temp_theKey) {
                                                                                        if ($theValArr['mask.'][$temp_theKey]=='TEXT')  {
                                                                                                $gifCreator->data = $this->menuArr[$key] ? $this->menuArr[$key] : Array();
                                                                                                $theValArr['mask.'][$temp_theKey.'.'] = $gifCreator->checkTextObj($theValArr['mask.'][$temp_theKey.'.']);
@@ -2555,8 +2801,7 @@ class tslib_imgmenu extends tslib_menu {
                                                                        }
                                                                        if ($theValArr['mask']=='GIFBUILDER')   {
                                                                                $temp_sKeyArray=t3lib_TStemplate::sortedKeyList($theValArr['mask.']);
-                                                                               reset($temp_sKeyArray);
-                                                                               while(list(,$temp_theKey)=each($temp_sKeyArray))        {
+                                                                               foreach ($temp_sKeyArray as $temp_theKey) {
                                                                                        if ($theValArr['mask.'][$temp_theKey]=='TEXT')  {
                                                                                                $gifCreator->data = $this->menuArr[$key] ? $this->menuArr[$key] : Array();
                                                                                                $theValArr['mask.'][$temp_theKey.'.'] = $gifCreator->checkTextObj($theValArr['mask.'][$temp_theKey.'.']);
@@ -2590,9 +2835,8 @@ class tslib_imgmenu extends tslib_menu {
                                        // calculations
 
                                $sum=Array(0,0,0,0);
-                               reset($waArr);
-                               while (list($key,$val)=each($waArr))    {
-                                       if ($dConf[$key] =$itemsConf[$key]['distrib'])  {
+                               foreach ($waArr as $key => $val) {
+                                       if (($dConf[$key] = $itemsConf[$key]['distrib'])) {
                                                $textBB = $gifCreator->objBB[$val['textNum']];
                                                $dConf[$key] = str_replace('textX',$textBB[0],$dConf[$key]);
                                                $dConf[$key] = str_replace('textY',$textBB[1],$dConf[$key]);
@@ -2600,8 +2844,7 @@ class tslib_imgmenu extends tslib_menu {
                                        }
                                }
                                $workArea = t3lib_div::intExplode(',',$gifCreator->calcOffset($this->mconf['dWorkArea']));
-                               reset($waArr);
-                               while (list($key,$val)=each($waArr))    {
+                               foreach ($waArr as $key => $val) {
                                        $index = $val['free'];
                                        $gifCreator->setup[$index] = 'WORKAREA';
                                        $workArea[2] = $dConf[$key][2] ? $dConf[$key][2] : $dConf[$key][0];
@@ -2612,16 +2855,19 @@ class tslib_imgmenu extends tslib_menu {
                                        $workArea[1]+=$dConf[$key][1];
                                }
 
-                               if ($this->mconf['debugRenumberedObject'])      {echo '<h3>Renumbered GIFBUILDER object:</h3>'; debug($gifCreator->setup);}
+                               if ($this->mconf['debugRenumberedObject']) {
+                                       echo '<h3>Renumbered GIFBUILDER object:</h3>';
+                                       debug($gifCreator->setup);
+                               }
 
                                $gifCreator->createTempSubDir('menu/');
                                $gifFileName = $gifCreator->fileName('menu/');
 
                                        // Gets the ImageMap from the cache...
                                $imgHash = md5($gifFileName);
-                               $imgMap = $this->sys_page->getHash($imgHash, 0);
+                               $imgMap = $this->sys_page->getHash($imgHash);
 
-                               if ($imgMap && @file_exists($gifFileName))      {               // File exists
+                               if ($imgMap && file_exists($gifFileName))       {               // File exists
                                        $info = @getimagesize($gifFileName);
                                        $w=$info[0];
                                        $h=$info[1];
@@ -2632,7 +2878,7 @@ class tslib_imgmenu extends tslib_menu {
                                        $gifCreator->output($gifFileName);
                                        $gifCreator->destroy();
                                        $imgMap=$gifCreator->map;
-                                       $this->sys_page->storeHash($imgHash, $imgMap, 'MENU IMAGEMAP');
+                                       $this->sys_page->storeHash($imgHash, $imgMap, 'MENUIMAGEMAP');
                                }
                                $imgMap.=$this->mconf['imgMapExtras'];
 
@@ -2644,7 +2890,7 @@ class tslib_imgmenu extends tslib_menu {
 
        /**
         * Returns the HTML for the image map menu.
-        * If ->result is true it will create the HTML for the image map menu.
+        * If ->result is TRUE it will create the HTML for the image map menu.
         *
         * @return      string          The HTML for the menu
         */
@@ -2686,10 +2932,9 @@ class tslib_imgmenu extends tslib_menu {
 /**
  * JavaScript/Selectorbox based menus
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage tslib
- * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=391&cHash=563435abbc
  */
 class tslib_jsmenu extends tslib_menu {
 
@@ -2709,17 +2954,18 @@ class tslib_jsmenu extends tslib_menu {
        function writeMenu()    {
                if ($this->id)  {
                                // Making levels:
-                       $levels = t3lib_div::intInRange($this->mconf['levels'],1,5);
+                       $levels = t3lib_utility_Math::forceIntegerInRange($this->mconf['levels'],1,5);
                        $this->levels = $levels;
-                       $this->JSVarName='eid';
-                       $this->JSMenuName= $this->mconf['menuName'] ? $this->mconf['menuName'] : 'JSmenu';
+                       $uniqueParam = t3lib_div::shortMD5(microtime(), 5);
+                       $this->JSVarName = 'eid' . $uniqueParam;
+                       $this->JSMenuName = ($this->mconf['menuName'] ? $this->mconf['menuName'] : 'JSmenu' . $uniqueParam);
 
                        $JScode="\n var ".$this->JSMenuName." = new JSmenu(".$levels.",'".$this->JSMenuName."Form');";
 
                        for ($a=1;$a<=$levels;$a++)     {
                                $JScode.="\n var ".$this->JSVarName.$a."=0;";
                        }
-                       $JScode.= $this->generate_level($levels,1,$this->id,$this->menuArr,$this->MP_array)."\n";
+                       $JScode.= $this->generate_level($levels,1,$this->id,$this->menuArr,$this->MP_array).LF;
 
                        $GLOBALS['TSFE']->additionalHeaderData['JSMenuCode']='<script type="text/javascript" src="'.$GLOBALS['TSFE']->absRefPrefix.'t3lib/jsfunc.menu.js"></script>';
                        $GLOBALS['TSFE']->JSCode.=$JScode;
@@ -2777,10 +3023,6 @@ class tslib_jsmenu extends tslib_menu {
                        $pid = $mount_info['mount_pid'];
                }
 
-                       // Set "&MP=" var:
-               $MP_var = implode(',',$MP_array);
-               $MP_params = $MP_var ? '&MP='.rawurlencode($MP_var) : '';
-
                        // UIDs to ban:
                $banUidArray = $this->getBannedUids();
 
@@ -2790,14 +3032,26 @@ class tslib_jsmenu extends tslib_menu {
                $parent = $count==1 ? 0 : $var.($count-1);
                $prev=0;
                $c=0;
+               $codeLines = '';
 
                $menuItems = is_array($menuItemArray) ? $menuItemArray : $this->sys_page->getMenu($pid);
                foreach($menuItems as $uid => $data)    {
+
+                               // $data['_MP_PARAM'] contains MP param for overlay mount points (MPs with "substitute this page" set)
+                               // if present: add param to copy of MP array (copy used for that submenu branch only)
+                       $MP_array_sub = $MP_array;
+                       if (array_key_exists('_MP_PARAM', $data) && $data['_MP_PARAM']) {
+                               $MP_array_sub[] = $data['_MP_PARAM'];
+                       }
+                               // Set "&MP=" var:
+                       $MP_var = implode(',', $MP_array_sub);
+                       $MP_params = ($MP_var ? '&MP='.rawurlencode($MP_var) : '');
+
                        $spacer = (t3lib_div::inList($this->spacerIDList,$data['doktype'])?1:0);                // if item is a spacer, $spacer is set
                        if ($this->mconf['SPC'] || !$spacer)    {       // If the spacer-function is not enabled, spacers will not enter the $menuArr
                                if (!t3lib_div::inList($this->doktypeExcludeList,$data['doktype']) && (!$data['nav_hide'] || $this->conf['includeNotInMenu']) && !t3lib_div::inArray($banUidArray,$uid))        {               // Page may not be 'not_in_menu' or 'Backend User Section' + not in banned uid's
                                        if ($count<$levels)     {
-                                               $addLines = $this->generate_level($levels,$count+1,$data['uid'],'',$MP_array);
+                                               $addLines = $this->generate_level($levels, $count+1, $data['uid'], '', $MP_array_sub);
                                        } else {
                                                $addLines = '';
                                        }
@@ -2805,7 +3059,7 @@ class tslib_jsmenu extends tslib_menu {
                                        $url='';
                                        $target='';
                                        if ((!$addLines && !$levelConf['noLink']) || $levelConf['alwaysLink']) {
-                                               $LD = $this->tmpl->linkData($data,$this->mconf['target'],'','',array(),$MP_params,$this->mconf['forceTypeValue']);
+                                               $LD = $this->menuTypoLink($data,$this->mconf['target'],'','',array(),$MP_params,$this->mconf['forceTypeValue']);
 
                                                        // If access restricted pages should be shown in menus, change the link of such pages to link to a redirection page:
                                                $this->changeLinksForAccessRestrictedPages($LD, $data, $this->mconf['target'], $this->mconf['forceTypeValue']);
@@ -2813,17 +3067,17 @@ class tslib_jsmenu extends tslib_menu {
                                                $url = $GLOBALS['TSFE']->baseUrlWrap($LD['totalURL']);
                                                $target = $LD['target'];
                                        }
-                                       $codeLines.="\n".$var.$count."=".$menuName.".add(".$parent.",".$prev.",0,".t3lib_div::quoteJSvalue($title, true).",".t3lib_div::quoteJSvalue($url, true).",".t3lib_div::quoteJSvalue($target, true).");";
+                                       $codeLines .= LF . $var . $count . '=' . $menuName . '.add(' . $parent . ',' . $prev . ',0,' . t3lib_div::quoteJSvalue($title, TRUE) . ',' . t3lib_div::quoteJSvalue($url, TRUE) . ',' . t3lib_div::quoteJSvalue($target, TRUE) . ');';
                                                // If the active one should be chosen...
-                                       $active = ($levelConf['showActive'] && $data['uid'] == $this->tmpl->rootLine[$count]['uid']);
+                                       $active = ($levelConf['showActive'] && $this->isActive($data['uid'], $MP_var));
                                                // If the first item should be shown
                                        $first = (!$c && $levelConf['showFirst']);
                                                // do it...
                                        if ($active || $first)  {
                                                if ($count==1)  {
-                                                       $codeLines.="\n".$menuName.".openID = ".$var.$count.";";
+                                                       $codeLines.=LF.$menuName.".openID = ".$var.$count.";";
                                                } else {
-                                                       $codeLines.="\n".$menuName.".entry[".$parent."].openID = ".$var.$count.";";
+                                                       $codeLines.=LF.$menuName.".entry[".$parent."].openID = ".$var.$count.";";
                                                }
                                        }
                                                // Add submenu...
@@ -2838,15 +3092,15 @@ class tslib_jsmenu extends tslib_menu {
                        $levelConf['firstLabel'] = $this->mconf['firstLabelGeneral'];
                }
                if ($levelConf['firstLabel'] && $codeLines)     {
-                       $codeLines.= chr(10).$menuName.'.defTopTitle['.$count.'] = '.t3lib_div::quoteJSvalue($levelConf['firstLabel'], true).';';
+                       $codeLines.= LF.$menuName.'.defTopTitle['.$count.'] = '.t3lib_div::quoteJSvalue($levelConf['firstLabel'], TRUE).';';
                }
                return $codeLines;
        }
 }
 
 
-if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_menu.php'])     {
-       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_menu.php']);
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['tslib/class.tslib_menu.php'])) {
+       include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['tslib/class.tslib_menu.php']);
 }
 
 ?>