Bug #6682: GMENU property disableAltText clears the content of alt param, but does...
[Packages/TYPO3.CMS.git] / typo3 / sysext / cms / tslib / class.tslib_menu.php
index 910575d..c67566c 100755 (executable)
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2004 Kasper Skaarhoj (kasper@typo3.com)
+*  (c) 1999-2007 Kasper Skaarhoj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
  * Revised for TYPO3 3.6 June/2003 by Kasper Skaarhoj
  * XHTML compliant
  *
- * @author     Kasper Skaarhoj <kasper@typo3.com>
+ * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
  */
 /**
  * [CLASS/FUNCTION INDEX of SCRIPT]
  *
  *
  *
- *  141: class tslib_menu
- *  183:     function start(&$tmpl,&$sys_page,$id,$conf,$menuNumber)
- *  294:     function makeMenu()
- *  774:     function includeMakeMenu($conf,$altSortField)
- *  791:     function procesItemStates($splitCount)
- *  978:     function link($key,$altTarget='',$typeOverride='')
- * 1032:     function subMenu($uid)
- * 1074:     function isNext($uid, $MPvar='')
- * 1089:     function isActive($uid, $MPvar='')
- * 1104:     function isCurrent($uid, $MPvar='')
- * 1119:     function isSubMenu($uid)
- * 1144:     function isItemState($kind,$key)
- * 1181:     function accessKey($title)
- * 1207:     function userProcess($mConfKey,$passVar)
- * 1222:     function setATagParts()
- * 1235:     function getPageTitle($title,$nav_title)
- * 1247:     function getMPvar($key)
+ *  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()
  *
  *
- * 1283: class tslib_tmenu extends tslib_menu
- * 1292:     function generate()
- * 1308:     function writeMenu()
- * 1438:     function getBeforeAfter($pref)
- * 1468:     function addJScolorShiftFunction()
- * 1490:     function extProc_init()
- * 1501:     function extProc_RO($key)
- * 1512:     function extProc_beforeLinking($key)
- * 1524:     function extProc_afterLinking($key)
- * 1541:     function extProc_beforeAllWrap($item,$key)
- * 1552:     function extProc_finish()
+ * 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()
  *
  *
- * 1588: class tslib_gmenu extends tslib_menu
- * 1597:     function generate()
- * 1635:     function makeGifs($conf, $resKey)
- * 1832:     function findLargestDims($conf,$items,$Hobjs,$Wobjs,$minDim,$maxDim)
- * 1904:     function writeMenu()
- * 2002:     function extProc_init()
- * 2013:     function extProc_RO($key)
- * 2024:     function extProc_beforeLinking($key)
- * 2037:     function extProc_afterLinking($key)
- * 2053:     function extProc_beforeAllWrap($item,$key)
- * 2064:     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()
  *
  *
- * 2098: class tslib_imgmenu extends tslib_menu
- * 2107:     function generate()
- * 2125:     function makeImageMap($conf)
- * 2294:     function writeMenu()
+ * 2391: class tslib_imgmenu extends tslib_menu
+ * 2400:     function generate()
+ * 2418:     function makeImageMap($conf)
+ * 2604:     function writeMenu()
  *
  *
- * 2337: class tslib_jsmenu extends tslib_menu
- * 2344:     function generate()
- * 2352:     function writeMenu()
- * 2413:     function generate_level($levels,$count,$pid,$menuItemArray='',$MP_array=array())
+ * 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: 42
+ * TOTAL FUNCTIONS: 46
  * (This index is automatically created/updated by the extension "extdeveval")
  *
  */
  * $menu->makeMenu();
  * $content.=$menu->writeMenu();
  *
- * @author     Kasper Skaarhoj <kasper@typo3.com>
+ * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage tslib
  * @see tslib_cObj::HMENU()
 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 $subLevelClass = '';                        // Points to the menu-class, that should be used for the next level
        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 $alwaysActivePIDlist=array();
        var $imgNamePrefix = 'img';
        var $imgNameNotRandom=0;
        var $debug = 0;
-       var $parent_cObj ='';                           // Loaded with the parent cObj-object when a new HMENU is made
+
+       /**
+        * Loaded with the parent cObj-object when a new HMENU is made
+        *
+        * @var tslib_cObj
+        */
+       var $parent_cObj;
        var $GMENU_fixKey='gmenu';
        var $MP_array=array();                          // accumulation of mount point data
 
                // internal
        var $conf = Array();                            // HMENU configuration
        var $mconf = Array();                           // xMENU configuration (TMENU, GMENU etc)
-       var $tmpl;              // template-object
-       var $sys_page;  // sys_page-object
+
+       /**
+        * template-object
+        *
+        * @var t3lib_TStemplate
+        */
+       var $tmpl;
+
+       /**
+        * sys_page-object, pagefunctions
+        *
+        * @var t3lib_pageSelect
+        */
+       var $sys_page;
        var $id;                                                        // The base page-id of the menu.
        var $nextActive;                                        // Holds the page uid of the NEXT page in the root line from the page pointed to by entryLevel; Used to expand the menu automatically if in a certain root line.
        var $menuArr;   // The array of menuItems which is built
@@ -167,8 +189,10 @@ class tslib_menu {
        var $WMresult;
        var $WMfreezePrefix;
        var $WMmenuItems;
+       var $WMsubmenuObjSuffixes;
        var $WMextraScript;
        var $alternativeMenuTempArray='';               // Can be set to contain menu item arrays for sub-levels.
+       var $nameAttribute = 'name';                    // Will be 'id' in XHTML-mode
 
        /**
         * The initialization of the object. This just sets some internal variables.
@@ -178,22 +202,40 @@ class tslib_menu {
         * @param       integer         A starting point page id. This should probably be blank since the 'entryLevel' value will be used then.
         * @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
         * @see tslib_cObj::HMENU()
         */
-       function start(&$tmpl,&$sys_page,$id,$conf,$menuNumber) {
+       function start(&$tmpl,&$sys_page,$id,$conf,$menuNumber,$objSuffix='')   {
 
                        // Init:
                $this->conf = $conf;
                $this->menuNumber = $menuNumber;
-               $this->mconf = $conf[$this->menuNumber.'.'];
+               $this->mconf = $conf[$this->menuNumber.$objSuffix.'.'];
                $this->debug=$GLOBALS['TSFE']->debug;
 
+                       // In XHTML there is no "name" attribute anymore
+               switch ($GLOBALS['TSFE']->xhtmlDoctype) {
+                       case 'xhtml_strict':
+                       case 'xhtml_11':
+                       case 'xhtml_2':
+                               $this->nameAttribute = 'id';
+                               break;
+                       default:
+                               $this->nameAttribute = 'name';
+                               break;
+               }
+
                        // Sets the internal vars. $tmpl MUST be the template-object. $sys_page MUST be the sys_page object
-               if ($this->conf[$this->menuNumber] && is_object($tmpl) && is_object($sys_page)) {
+               if ($this->conf[$this->menuNumber.$objSuffix] && is_object($tmpl) && is_object($sys_page))      {
                        $this->tmpl = &$tmpl;
                        $this->sys_page = &$sys_page;
 
+                               // alwaysActivePIDlist initialized:
+                       if (trim($this->conf['alwaysActivePIDlist']))   {
+                               $this->alwaysActivePIDlist = t3lib_div::intExplode(',', $this->conf['alwaysActivePIDlist']);
+                       }
+
                                // 'not in menu' doktypes
                        if($this->conf['excludeDoktypes']) {
                                $this->doktypeExcludeList = $GLOBALS['TYPO3_DB']->cleanIntList($this->conf['excludeDoktypes']);
@@ -282,11 +324,6 @@ class tslib_menu {
                        }
                        $this->imgNameNotRandom = $this->mconf['imgNameNotRandom'];
 
-                               // subLevelClass
-                       $cls = strtolower($this->conf[$this->menuNumber+1]);
-                       if ($cls && t3lib_div::inList($this->tmpl->menuclasses,$cls))   {
-                               $this->subLevelClass = $cls;
-                       }
                        $retVal = TRUE;
                } else {
                        $GLOBALS['TT']->setTSlogMessage('ERROR in menu',3);
@@ -304,6 +341,15 @@ class tslib_menu {
         */
        function makeMenu()     {
                if ($this->id)  {
+
+                               // Initializing showAccessRestrictedPages
+                       if ($this->mconf['showAccessRestrictedPages'])  {
+                                       // SAVING where_groupAccess
+                               $SAVED_where_groupAccess = $this->sys_page->where_groupAccess;
+                               $this->sys_page->where_groupAccess = '';        // Temporarily removing fe_group checking!
+                       }
+
+                               // Begin production of menu:
                        $temp = array();
                        $altSortFieldValue = trim($this->mconf['alternativeSortingField']);
                        $altSortField = $altSortFieldValue ? $altSortFieldValue : 'sorting';
@@ -337,7 +383,7 @@ class tslib_menu {
                                                        } else $lRecs=array();
                                                                // Checking if the "disabled" state should be set.
                                                        if (
-                                                                               ($GLOBALS['TSFE']->page['l18n_cfg']&2 && $sUid && !count($lRecs)) // Blocking for all translations?
+                                                                               (t3lib_div::hideIfNotTranslated($GLOBALS['TSFE']->page['l18n_cfg']) && $sUid && !count($lRecs)) // Blocking for all translations?
                                                                        || ($GLOBALS['TSFE']->page['l18n_cfg']&1 && (!$sUid || !count($lRecs))) // Blocking default translation?
                                                                        || (!$this->conf['special.']['normalWhenNoLanguage'] && $sUid && !count($lRecs))
                                                                )       {
@@ -345,12 +391,19 @@ class tslib_menu {
                                                        } else {
                                                                $iState = $GLOBALS['TSFE']->sys_language_uid==$sUid ? 'ACT' : 'NO';
                                                        }
+
+                                                       if ($this->conf['addQueryString'])      {
+                                                               $getVars = $this->parent_cObj->getQueryArguments($this->conf['addQueryString.'],array('L'=>$sUid),true);
+                                                       } else {
+                                                               $getVars = '&L='.$sUid;
+                                                       }
+
                                                                // Adding menu item:
                                                        $temp[] = array_merge(
                                                                array_merge($currentPageWithNoOverlay, $lRecs),
                                                                array(
                                                                        'ITEM_STATE' => $iState,
-                                                                       '_ADD_GETVARS' => '&L='.$sUid,
+                                                                       '_ADD_GETVARS' => $getVars,
                                                                        '_SAFE' => TRUE
                                                                )
                                                        );
@@ -373,28 +426,31 @@ class tslib_menu {
                                                                        $MP = $MP ? $MP : $mount_info['MPvar'];
                                                                } else {
                                                                        $MP = ($MP ? $MP.',' : '').$mount_info['MPvar'];
-                                                       }
+                                                               }
                                                                $id = $mount_info['mount_pid'];
-                                               }
+                                                       }
 
                                                                // Get sub-pages:
                                                        $res = $GLOBALS['TSFE']->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);
 
-                                                                       // Keep mount point?
-                                                               $mount_info = $this->sys_page->getMountPointInfo($row['uid'], $row);
-                                                               if (is_array($mount_info) && $mount_info['overlay'])    {       // There is a valid mount point.
-                                                                       $mp_row = $this->sys_page->getPage($mount_info['mount_pid']);           // Using "getPage" is OK since we need the check for enableFields AND for type 2 of mount pids we DO require a doktype < 200!
-                                                                       if (count($mp_row))     {
-                                                                               $row = $mp_row;
-                                                                               $row['_MP_PARAM'] = $mount_info['MPvar'];
-                                                                       } else unset($row);     // If the mount point could not be fetched with respect to enableFields, unset the row so it does not become a part of the menu!
-                                                               }
-
-                                                                       // Add external MP params, then the row:
                                                                if (is_array($row))     {
-                                                                       if ($MP)        $row['_MP_PARAM'] = $MP.($row['_MP_PARAM'] ? ','.$row['_MP_PARAM'] : '');
-                                                                       $temp[$row['uid']] = $this->sys_page->getPageOverlay($row);
+                                                                               // Keep mount point?
+                                                                       $mount_info = $this->sys_page->getMountPointInfo($row['uid'], $row);
+                                                                       if (is_array($mount_info) && $mount_info['overlay'])    {       // There is a valid mount point.
+                                                                               $mp_row = $this->sys_page->getPage($mount_info['mount_pid']);           // Using "getPage" is OK since we need the check for enableFields AND for type 2 of mount pids we DO require a doktype < 200!
+                                                                               if (count($mp_row))     {
+                                                                                       $row = $mp_row;
+                                                                                       $row['_MP_PARAM'] = $mount_info['MPvar'];
+                                                                               } else unset($row);     // If the mount point could not be fetched with respect to enableFields, unset the row so it does not become a part of the menu!
+                                                                       }
+
+                                                                               // Add external MP params, then the row:
+                                                                       if (is_array($row))     {
+                                                                               if ($MP)        $row['_MP_PARAM'] = $MP.($row['_MP_PARAM'] ? ','.$row['_MP_PARAM'] : '');
+                                                                               $temp[$row['uid']] = $this->sys_page->getPageOverlay($row);
+                                                                       }
                                                                }
                                                        }
                                                }
@@ -422,12 +478,11 @@ class tslib_menu {
                                                                        if ($mount_info['overlay'])     {       // Overlays should already have their full MPvars calculated:
                                                                                $MP = $this->tmpl->getFromMPmap($mount_info['mount_pid']);
                                                                                if ($MP) unset($row['_MP_PARAM']);
-                                                       }
-
+                                                                       }
                                                                } else unset($row);     // If the mount point could not be fetched with respect to enableFields, unset the row so it does not become a part of the menu!
                                                        } else {
                                                                $row = $loadDB->results['pages'][$val['id']];
-                                               }
+                                                       }
 
                                                                // Add external MP params, then the row:
                                                        if (is_array($row))     {
@@ -478,7 +533,7 @@ class tslib_menu {
                                                        break;
                                                }
                                                        // Get
-                                               $extraWhere = ' AND pages.nav_hide=0'.$this->getDoktypeExcludeWhere();
+                                               $extraWhere = ($this->conf['includeNotInMenu'] ? '' : ' AND pages.nav_hide=0').$this->getDoktypeExcludeWhere();
 
                                                if ($this->conf['special.']['excludeNoSearchPages']) {
                                                        $extraWhere.= ' AND pages.no_search=0';
@@ -489,7 +544,10 @@ class tslib_menu {
 
                                                $res = $GLOBALS['TSFE']->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))      {
-                                                       $temp[$row['uid']]=$this->sys_page->getPageOverlay($row);
+                                                       $GLOBALS['TSFE']->sys_page->versionOL('pages',$row);
+                                                       if (is_array($row))     {
+                                                               $temp[$row['uid']]=$this->sys_page->getPageOverlay($row);
+                                                       }
                                                }
                                        break;
                                        case 'keywords':
@@ -533,7 +591,7 @@ class tslib_menu {
                                                        $depth=20;
                                                }
                                                $limit = t3lib_div::intInRange($this->conf['special.']['limit'],0,100); // max number of items
-                                               $extraWhere = ' AND pages.uid!='.$value.' AND pages.nav_hide=0'.$this->getDoktypeExcludeWhere();
+                                               $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';
                                                }
@@ -556,12 +614,15 @@ class tslib_menu {
                                                        foreach($kwArr as $word)        {
                                                                $word = trim($word);
                                                                if ($word)      {
-                                                                       $keyWordsWhereArr[] = $kfield.' LIKE "%'.$GLOBALS['TYPO3_DB']->quoteStr($word, 'pages').'%"';
+                                                                       $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));
                                                        while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {
-                                                               $temp[$row['uid']]=$this->sys_page->getPageOverlay($row);
+                                                               $GLOBALS['TSFE']->sys_page->versionOL('pages',$row);
+                                                               if (is_array($row))     {
+                                                                       $temp[$row['uid']]=$this->sys_page->getPageOverlay($row);
+                                                               }
                                                        }
                                                }
                                        break;
@@ -603,69 +664,69 @@ class tslib_menu {
                                                        $value=$GLOBALS['TSFE']->page['uid'];
                                                }
                                                if ($value!=$this->tmpl->rootLine[0]['uid'])    {       // Will not work out of rootline
-                                                       $recArr=array();
-                                                       $value_rec=$this->sys_page->getPage($value);    // The page record of the 'value'.
-                                                       if ($value_rec['pid'])  {       // 'up' page cannot be outside rootline
-                                                               $recArr['up']=$this->sys_page->getPage($value_rec['pid']);      // The page record of 'up'.
-                                                       }
-                                                       if ($recArr['up']['pid'] && $value_rec['pid']!=$this->tmpl->rootLine[0]['uid']) {       // If the 'up' item was NOT level 0 in rootline...
-                                                               $recArr['index']=$this->sys_page->getPage($recArr['up']['pid']);        // The page record of "index".
-                                                       }
-
-                                                               // prev / next is found
-                                                       $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))     {
-                                                               if ($nextActive)        {
-                                                                       $recArr['next']=$v_b;
-                                                                       $nextActive=0;
+                                                       $recArr=array();
+                                                       $value_rec=$this->sys_page->getPage($value);    // The page record of the 'value'.
+                                                       if ($value_rec['pid'])  {       // 'up' page cannot be outside rootline
+                                                               $recArr['up']=$this->sys_page->getPage($value_rec['pid']);      // The page record of 'up'.
+                                                       }
+                                                       if ($recArr['up']['pid'] && $value_rec['pid']!=$this->tmpl->rootLine[0]['uid']) {       // If the 'up' item was NOT level 0 in rootline...
+                                                               $recArr['index']=$this->sys_page->getPage($recArr['up']['pid']);        // The page record of "index".
+                                                       }
+
+                                                               // prev / next is found
+                                                       $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))     {
+                                                               if ($nextActive)        {
+                                                                       $recArr['next']=$v_b;
+                                                                       $nextActive=0;
                                                                }
-                                                               if ($v_b['uid']==$value)        {
-                                                                       if ($lastKey)   {
-                                                                               $recArr['prev']=$prevnext_menu[$lastKey];
-                                                                       }
-                                                                       $nextActive=1;
+                                                               if ($v_b['uid']==$value)        {
+                                                                       if ($lastKey)   {
+                                                                               $recArr['prev']=$prevnext_menu[$lastKey];
+                                                                       }
+                                                                       $nextActive=1;
                                                                }
-                                                               $lastKey=$k_b;
-                                                       }
-                                                       reset($prevnext_menu);
+                                                               $lastKey=$k_b;
+                                                       }
+                                                       reset($prevnext_menu);
                                                        $recArr['first']=pos($prevnext_menu);
                                                        end($prevnext_menu);
                                                        $recArr['last']=pos($prevnext_menu);
 
-                                                               // prevsection / nextsection is found
+                                                               // prevsection / nextsection is found
                                                        if (is_array($recArr['index'])) {       // You can only do this, if there is a valid page two levels up!
-                                                               $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))      {
-                                                                       if ($nextActive)        {
+                                                               $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))      {
+                                                                       if ($nextActive)        {
                                                                                $sectionRec_temp = $this->sys_page->getMenu($v_b['uid'],'*',$altSortField);
                                                                                if (count($sectionRec_temp))    {
                                                                                        reset($sectionRec_temp);
-                                                                                       $recArr['nextsection']=pos($sectionRec_temp);
+                                                                                       $recArr['nextsection']=pos($sectionRec_temp);
                                                                                        end ($sectionRec_temp);
-                                                                                       $recArr['nextsection_last']=pos($sectionRec_temp);
-                                                                                       $nextActive=0;
+                                                                                       $recArr['nextsection_last']=pos($sectionRec_temp);
+                                                                                       $nextActive=0;
                                                                                }
                                                                        }
-                                                                       if ($v_b['uid']==$value_rec['pid'])     {
-                                                                               if ($lastKey)   {
+                                                                       if ($v_b['uid']==$value_rec['pid'])     {
+                                                                               if ($lastKey)   {
                                                                                        $sectionRec_temp = $this->sys_page->getMenu($prevnextsection_menu[$lastKey]['uid'],'*',$altSortField);
                                                                                        if (count($sectionRec_temp))    {
                                                                                                reset($sectionRec_temp);
-                                                                                               $recArr['prevsection']=pos($sectionRec_temp);
+                                                                                               $recArr['prevsection']=pos($sectionRec_temp);
                                                                                                end ($sectionRec_temp);
-                                                                                               $recArr['prevsection_last']=pos($sectionRec_temp);
+                                                                                               $recArr['prevsection_last']=pos($sectionRec_temp);
                                                                                        }
-                                                                               }
-                                                                               $nextActive=1;
+                                                                               }
+                                                                               $nextActive=1;
                                                                        }
-                                                                       $lastKey=$k_b;
-                                                               }
+                                                                       $lastKey=$k_b;
+                                                               }
                                                        }
                                                        if ($this->conf['special.']['items.']['prevnextToSection'])     {
                                                                if (!is_array($recArr['prev']) && is_array($recArr['prevsection_last']))        {
@@ -676,15 +737,15 @@ class tslib_menu {
                                                                }
                                                        }
 
-                                                       $items = explode('|',$this->conf['special.']['items']);
+                                                       $items = explode('|',$this->conf['special.']['items']);
                                                        $c=0;
-                                                       while(list($k_b,$v_b)=each($items))     {
-                                                               $v_b=strtolower(trim($v_b));
+                                                       while(list($k_b,$v_b)=each($items))     {
+                                                               $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
                                                                }
-                                                               if (is_array($recArr[$v_b]))    {
-                                                                       $temp[$c]=$recArr[$v_b];
+                                                               if (is_array($recArr[$v_b]))    {
+                                                                       $temp[$c]=$recArr[$v_b];
                                                                        if ($this->conf['special.'][$v_b.'.']['target'])        {
                                                                                $temp[$c]['target']=$this->conf['special.'][$v_b.'.']['target'];
                                                                        }
@@ -696,7 +757,7 @@ class tslib_menu {
                                                                        }
                                                                        $c++;
                                                                }
-                                                       }
+                                                       }
                                                }
                                        break;
                                }
@@ -725,19 +786,24 @@ class tslib_menu {
                                if (is_array($basePageRow))     {
                                        $res = $GLOBALS['TSFE']->cObj->exec_getQuery('tt_content',      $selectSetup);
                                        while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {
-                                               $temp[$row['uid']]=$basePageRow;
-                                               $temp[$row['uid']]['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'];
+                                               $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'];
+                                               }
                                        }
                                }
                        } else {        // Default:
@@ -750,10 +816,7 @@ class tslib_menu {
                        $maxItems = intval($this->mconf['maxItems'] ? $this->mconf['maxItems'] : $this->conf['maxItems']);
                        $begin = tslib_cObj::calc($this->mconf['begin'] ? $this->mconf['begin'] : $this->conf['begin']);
 
-                       $banUidArray=array();
-                       if (trim($this->conf['excludeUidList']))        {
-                               $banUidArray = t3lib_div::intExplode(',', $this->conf['excludeUidList']);
-                       }
+                       $banUidArray = $this->getBannedUids();
 
                                // Fill in the menuArr with elements that should go into the menu:
                        $this->menuArr = Array();
@@ -791,12 +854,24 @@ class tslib_menu {
                        }
                        $this->hash = md5(serialize($this->menuArr).serialize($this->mconf).serialize($this->tmpl->rootLine).serialize($this->MP_array));
 
-                       $serData = $this->sys_page->getHash($this->hash, 60*60*24);
+                               // Get the cache timeout:
+                       if ($this->conf['cache_period']) {
+                               $cacheTimeout = $this->conf['cache_period'];
+                       } else {
+                               $cacheTimeout = $GLOBALS['TSFE']->get_cache_timeout();
+                       }
+                       $serData = $this->sys_page->getHash($this->hash, $cacheTimeout);
                        if (!$serData)  {
                                $this->generate();
                                $this->sys_page->storeHash($this->hash, serialize($this->result),'MENUDATA');
                        } else {
-                               $this->result=unserialize($serData);
+                               $this->result = unserialize($serData);
+                       }
+
+                               // End showAccessRestrictedPages
+                       if ($this->mconf['showAccessRestrictedPages'])  {
+                                       // RESTORING where_groupAccess
+                               $this->sys_page->where_groupAccess = $SAVED_where_groupAccess;
                        }
                }
        }
@@ -804,7 +879,7 @@ 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 depreciated since "userfunction" has arrived since and is a better choice for many reasons (like using classes/functions for rendering 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.
@@ -822,10 +897,10 @@ class tslib_menu {
        /**
         * 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.
+        * @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.
         */
        function filterMenuPages(&$data,$banUidArray,$spacer)   {
 
@@ -834,7 +909,7 @@ class tslib_menu {
                $uid = $data['uid'];
                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']))     {               // Page may not be 'not_in_menu' or 'Backend User Section'
-                               if (!$data['nav_hide']) {       // Not hidden in navigation
+                               if (!$data['nav_hide'] || $this->conf['includeNotInMenu'])      {       // Not hidden in navigation
                                        if (!t3lib_div::inArray($banUidArray,$uid))     {       // not in banned uid's
 
                                                        // Checks if the default language version can be shown:
@@ -844,7 +919,7 @@ class tslib_menu {
 
                                                                // Checking if a page should be shown in the menu depending on whether a translation exists:
                                                        $tok = TRUE;
-                                                       if ($GLOBALS['TSFE']->sys_language_uid && $data['l18n_cfg']&2)  {       // There is an alternative language active AND the current page requires a translation:
+                                                       if ($GLOBALS['TSFE']->sys_language_uid && t3lib_div::hideIfNotTranslated($data['l18n_cfg']))    {       // There is an alternative language active AND the current page requires a translation:
                                                                if (!$data['_PAGES_OVERLAY'])   {
                                                                        $tok = FALSE;
                                                                }
@@ -855,9 +930,9 @@ class tslib_menu {
 
                                                                        // Checking if "&L" should be modified so links to non-accessible pages will not happen.
                                                                if ($this->conf['protectLvar']) {
-                                                                       $Lvar = intval(t3lib_div::_GP('L'));
-                                                                       if (($this->conf['protectLvar']=='all' || $data['l18n_cfg']&2) && $Lvar!=$GLOBALS['TSFE']->sys_language_uid)    {       // page cannot be access in locaization and Lvar is different than sys_language uid - this means we must check!
-                                                                               $olRec = $GLOBALS['TSFE']->sys_page->getPageOverlay($data['uid'], $Lvar);
+                                                                       $languageUid = intval($GLOBALS['TSFE']->config['config']['sys_language_uid']);
+                                                                       if ($languageUid && ($this->conf['protectLvar']=='all' || t3lib_div::hideIfNotTranslated($data['l18n_cfg'])))   {
+                                                                               $olRec = $GLOBALS['TSFE']->sys_page->getPageOverlay($data['uid'], $languageUid);
                                                                                if (!count($olRec))     {
                                                                                                // If no pages_language_overlay record then page can NOT be accessed in the language pointed to by "&L" and therefore we protect the link by setting "&L=0"
                                                                                        $data['_ADD_GETVARS'].= '&L=0';
@@ -922,7 +997,7 @@ class tslib_menu {
                        reset($NOconf);
                        while (list($key,$val)=each($NOconf))   {       // Find active
                                if ($this->isItemState('ACT',$key))     {
-                                       if (!$ACTinit)  {       // if this is the first active, we must generate ACT.
+                                       if (!$ACTinit)  {       // if this is the first 'active', we must generate ACT.
                                                $ACTconf = $this->tmpl->splitConfArray($this->mconf['ACT.'],$splitCount);
                                                        // Prepare active rollOver settings, overriding normal active settings
                                                if ($this->mconf['ACTRO'])      {
@@ -937,14 +1012,14 @@ class tslib_menu {
                                }
                        }
                }
-                       // Prepare active/IFSUB settings, overriding normal settings
+                       // 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
                if ($this->mconf['ACTIFSUB'])   {
                        $ACTIFSUBinit = 0;      // Flag: If $ACTIFSUB is generated
                        reset($NOconf);
                        while (list($key,$val)=each($NOconf))   {       // Find active
                                if ($this->isItemState('ACTIFSUB',$key))        {
-                                       if (!$ACTIFSUBinit)     {       // if this is the first active, we must generate ACTIFSUB.
+                                       if (!$ACTIFSUBinit)     {       // if this is the first 'active', we must generate ACTIFSUB.
                                                $ACTIFSUBconf = $this->tmpl->splitConfArray($this->mconf['ACTIFSUB.'],$splitCount);
                                                        // Prepare active rollOver settings, overriding normal active settings
                                                if ($this->mconf['ACTIFSUBRO']) {
@@ -980,6 +1055,28 @@ 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!
+               if ($this->mconf['CURIFSUB'])   {
+                       $CURIFSUBinit = 0;      // Flag: If $CURIFSUB is generated
+                       reset($NOconf);
+                       while (list($key,$val)=each($NOconf))   {
+                               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);
+                                                       // Prepare current rollOver settings, overriding normal current settings
+                                               if ($this->mconf['CURIFSUBRO']) {
+                                                       $CURIFSUBROconf = $this->tmpl->splitConfArray($this->mconf['CURIFSUBRO.'],$splitCount);
+                                               }
+                                               $CURIFSUBinit = 1;
+                                       }
+                                       $NOconf[$key] = $CURIFSUBconf[$key];            // Substitute normal with active
+                                       if ($ROconf)    {       // If rollOver on normal, we must apply a state for rollOver on the current
+                                               $ROconf[$key] = $CURIFSUBROconf[$key] ? $CURIFSUBROconf[$key] : $CURIFSUBconf[$key];            // If RollOver on current then apply this
+                                       }
+                               }
+                       }
+               }
                        // Prepare active settings, overriding normal settings
                if ($this->mconf['USR'])        {
                        $USRinit = 0;   // Flag: If $USR is generated
@@ -1096,9 +1193,19 @@ class tslib_menu {
                        $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);
                } else {
-                       $LD = $this->tmpl->linkData($this->menuArr[$key],$mainTarget,'','',$overrideArray, $this->mconf['addParams'].$MP_params.$this->menuArr[$key]['_ADD_GETVARS'], $typeOverride);
+                       $LD = $this->tmpl->linkData($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'])) {
+                               // Create mailto-link using tslib_cObj::typolink (concerning spamProtectEmailAddresses):
+                       $LD['totalURL'] = $this->parent_cObj->typoLink_URL(array('parameter' => $this->menuArr[$key]['url']));
+                       $LD['target'] = '';
+               }
+
+                       // Manipulation in case of access restricted pages:
+               $this->changeLinksForAccessRestrictedPages($LD,$this->menuArr[$key],$mainTarget,$typeOverride);
+
                        // Overriding URL / Target if set to do so:
                if ($this->menuArr[$key]['_OVERRIDE_HREF'])     {
                        $LD['totalURL'] = $this->menuArr[$key]['_OVERRIDE_HREF'];
@@ -1111,26 +1218,50 @@ class tslib_menu {
                        $conf=$this->mconf['JSWindow.'];
                        $url=$LD['totalURL'];
                        $LD['totalURL'] = '#';
-                       $onClick= 'openPic(\''.$url.'\',\''.($conf['newWindow']?md5($url):'theNewPage').'\',\''.$conf['params'].'\'); return false;';
+                       $onClick= 'openPic(\''.$GLOBALS['TSFE']->baseUrlWrap($url).'\',\''.($conf['newWindow']?md5($url):'theNewPage').'\',\''.$conf['params'].'\'); return false;';
                        $GLOBALS['TSFE']->setJS('openPic');
                }
+
                        // out:
                $list = array();
-               $list['HREF']=$LD['totalURL'];
-               $list['TARGET']=$LD['target'];
-               $list['onClick']=$onClick;
+               $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.
+               $list['TARGET'] = $LD['target'];
+               $list['onClick'] = $onClick;
 
                return $list;
        }
 
        /**
+        * Will change $LD (passed by reference) if the page is access restricted
+        *
+        * @param       array           $LD, the array from the linkData() function
+        * @param       array           Page array
+        * @param       string          Main target value
+        * @param       string          Type number override if any
+        * @return      void            ($LD passed by reference might be changed.)
+        */
+       function changeLinksForAccessRestrictedPages(&$LD, $page, $mainTarget, $typeOverride)   {
+
+                       // If access restricted pages should be shown in menus, change the link of such pages to link to a redirection page:
+               if ($this->mconf['showAccessRestrictedPages'] && $this->mconf['showAccessRestrictedPages']!=='NONE' && !$GLOBALS['TSFE']->checkPageGroupAccess($page))  {
+                       $thePage = $this->sys_page->getPage($this->mconf['showAccessRestrictedPages']);
+
+                       $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);
+               }
+       }
+
+       /**
         * Creates a submenu level to the current level - if configured for.
         *
         * @param       integer         Page id of the current page for which a submenu MAY be produced (if conditions are met)
+        * @param       string          Object prefix, see ->start()
         * @return      string          HTML content of the submenu
         * @access private
         */
-       function subMenu($uid)  {
+       function subMenu($uid, $objSuffix='')   {
 
                        // Setting alternative menu item array if _SUB_MENU has been defined in the current ->menuArr
                $altArray = '';
@@ -1139,8 +1270,11 @@ class tslib_menu {
                }
 
                        // Make submenu if the page is the next active
-               if ($this->subLevelClass && ($this->mconf['expAll'] || $this->isNext($uid, $this->getMPvar($this->I['key'])) || is_array($altArray)) && !$this->mconf['sectionIndex'])  {
-                       $submenu = t3lib_div::makeInstance('tslib_'.$this->subLevelClass);
+               $cls = strtolower($this->conf[($this->menuNumber+1).$objSuffix]);
+               $subLevelClass = ($cls && t3lib_div::inList($this->tmpl->menuclasses,$cls)) ? $cls : '';
+
+               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;
                        $submenu->rL_uidRegister = $this->rL_uidRegister;
                        $submenu->MP_array = $this->MP_array;
@@ -1149,6 +1283,7 @@ class tslib_menu {
                        }
 
                                // especially scripts that build the submenu needs the parent data
+                       $submenu->parent_cObj = &$this->parent_cObj;
                        $submenu->parentMenuArr = $this->menuArr;
 
                                // Setting alternativeMenuTempArray (will be effective only if an array)
@@ -1156,7 +1291,7 @@ class tslib_menu {
                                $submenu->alternativeMenuTempArray = $altArray;
                        }
 
-                       if ($submenu->start($this->tmpl, $this->sys_page, $uid, $this->conf, $this->menuNumber+1))      {
+                       if ($submenu->start($this->tmpl, $this->sys_page, $uid, $this->conf, $this->menuNumber+1, $objSuffix))  {
                                $submenu->makeMenu();
                                return $submenu->writeMenu();
                        }
@@ -1173,6 +1308,12 @@ class tslib_menu {
         * @see subMenu()
         */
        function isNext($uid, $MPvar='')        {
+
+                       // Check for always active PIDs:
+               if (count($this->alwaysActivePIDlist) && in_array($uid,$this->alwaysActivePIDlist))     {
+                       return TRUE;
+               }
+
                $testUid = $uid.($MPvar?':'.$MPvar:'');
                if ($uid && $testUid==$this->nextActive)        {
                        return TRUE;
@@ -1188,10 +1329,16 @@ class tslib_menu {
         * @access private
         */
        function isActive($uid, $MPvar='')      {
+
+                       // Check for always active PIDs:
+               if (count($this->alwaysActivePIDlist) && in_array($uid,$this->alwaysActivePIDlist))     {
+                       return TRUE;
+               }
+
                $testUid = $uid.($MPvar?':'.$MPvar:'');
                if ($uid && in_array('ITEM:'.$testUid, $this->rL_uidRegister))  {
                        return TRUE;
-       }
+               }
        }
 
        /**
@@ -1206,12 +1353,12 @@ class tslib_menu {
                $testUid = $uid.($MPvar?':'.$MPvar:'');
                if ($uid && !strcmp(end($this->rL_uidRegister),'ITEM:'.$testUid))       {
                        return TRUE;
-       }
+               }
        }
 
        /**
         * Returns true if there is a submenu with items for the page id, $uid
-        * Used by the item states "IFSUB" and "ACTIFSUB" to check if there is a submenu
+        * 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
@@ -1225,9 +1372,9 @@ class tslib_menu {
                        $uid = $mount_info['mount_pid'];
                }
 
-               $recs = $this->sys_page->getMenu($uid,'uid,pid,doktype,mount_pid,mount_pid_ol');
+               $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'])   {       // If a menu item seems to be another type than 'Not in menu', then return true (there were items!)
+                       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;
                        }
                }
@@ -1263,6 +1410,9 @@ class tslib_menu {
                                case 'CUR':
                                        $natVal = $this->isCurrent($this->menuArr[$key]['uid'], $this->getMPvar($key));
                                break;
+                               case 'CURIFSUB':
+                                       $natVal = $this->isCurrent($this->menuArr[$key]['uid'], $this->getMPvar($key)) && $this->isSubMenu($this->menuArr[$key]['uid']);
+                               break;
                                case 'USR':
                                        $natVal = $this->menuArr[$key]['fe_group'];
                                break;
@@ -1273,7 +1423,7 @@ class tslib_menu {
        }
 
        /**
-        * Creates an access-key for a GMENU menu item based on the menu item titles first letter
+        * Creates an access-key for a TMENU/GMENU menu item based on the menu item titles first letter
         *
         * @param       string          Menu item title.
         * @return      array           Returns an array with keys "code" ("accesskey" attribute for the img-tag) and "alt" (text-addition to the "alt" attribute) if an access key was defined. Otherwise array was empty
@@ -1283,13 +1433,15 @@ class tslib_menu {
                        // The global array ACCESSKEY is used to globally control if letters are already used!!
                $result = Array();
 
+               $title = trim(strip_tags($title));
                $titleLen = strlen($title);
                for ($a=0;$a<$titleLen;$a++)    {
-                       $key = strtoupper(trim(substr($title,$a,1)));
-                       if ($key && !isset($GLOBALS['TSFE']->accessKey[$key]))  {
-                               $GLOBALS['TSFE']->accessKey[$key]=1;
+                       $key = strtoupper(substr($title,$a,1));
+                       if (preg_match('/[A-Z]/', $key) && !isset($GLOBALS['TSFE']->accessKey[$key]))   {
+                               $GLOBALS['TSFE']->accessKey[$key] = 1;
                                $result['code'] = ' accesskey="'.$key.'"';
                                $result['alt'] = ' (ALT+'.$key.')';
+                               $result['key'] = $key;
                                break;
                        }
                }
@@ -1321,7 +1473,7 @@ class tslib_menu {
         * @access private
         */
        function setATagParts() {
-               $this->I['A1'] = '<a '.t3lib_div::implodeAttributes($this->I['linkHREF'],1).$this->I['val']['ATagParams'].$this->I['addATagParams'].$this->I['accessKey']['code'].'>';
+               $this->I['A1'] = '<a '.t3lib_div::implodeAttributes($this->I['linkHREF'],1).' '.$this->I['val']['ATagParams'].$this->I['accessKey']['code'].'>';
                $this->I['A2'] = '</a>';
        }
 
@@ -1329,7 +1481,7 @@ class tslib_menu {
         * Returns the title for the navigation
         *
         * @param       string          The current page title
-        * @param       string          The current value of the naviation title
+        * @param       string          The current value of the navigation title
         * @return      string          Returns the navigation title if it is NOT blank, otherwise the page title.
         * @access private
         */
@@ -1364,6 +1516,23 @@ class tslib_menu {
                return $this->doktypeExcludeList ? ' AND pages.doktype NOT IN ('.$this->doktypeExcludeList.')' : '';
        }
 
+       /**
+        * Returns an array of banned UIDs (from excludeUidList)
+        *
+        * @return      array           Array of banned UIDs
+        * @access private
+        */
+       function getBannedUids() {
+               $banUidArray = array();
+
+               if (trim($this->conf['excludeUidList']))        {
+                       $banUidList = str_replace('current', $GLOBALS['TSFE']->page['uid'], $this->conf['excludeUidList']);
+                       $banUidArray = t3lib_div::intExplode(',', $banUidList);
+               }
+
+               return $banUidArray;
+       }
+
 }
 
 
@@ -1387,7 +1556,7 @@ class tslib_menu {
 /**
  * Extension class creating text based menus
  *
- * @author     Kasper Skaarhoj <kasper@typo3.com>
+ * @author     Kasper Skaarhoj <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
@@ -1419,20 +1588,24 @@ class tslib_tmenu extends tslib_menu {
         */
        function writeMenu()    {
                if (is_array($this->result) && count($this->result))    {
-                       $this->WMcObj =t3lib_div::makeInstance('tslib_cObj');   // Create new tslib_cObj for our use
-                       $this->WMresult='';
+                       $this->WMcObj = t3lib_div::makeInstance('tslib_cObj');  // Create new tslib_cObj for our use
+                       $this->WMresult = '';
                        $this->INPfixMD5 = substr(md5(microtime().'tmenu'),0,4);
                        $this->WMmenuItems = count($this->result);
+
+                       $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))     {
                                $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ']++;
                                $GLOBALS['TSFE']->register['count_MENUOBJ']++;
 
-                               $this->I=array();
                                $this->WMcObj->start($this->menuArr[$key],'pages');             // Initialize the cObj with the page record of the menu item
+
+                               $this->I = array();
                                $this->I['key'] = $key;
-                               $this->I['INPfix']= $this->imgNameNotRandom?'':'_'.$this->INPfixMD5.'_'.$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['uid'] = $this->menuArr[$key]['uid'];
@@ -1440,12 +1613,20 @@ class tslib_tmenu extends tslib_menu {
                                $this->I['pid'] = $this->menuArr[$key]['pid'];
                                $this->I['spacer'] = $this->menuArr[$key]['isSpacer'];
 
+                                       // Set access key
+                               if ($this->mconf['accessKey'])  {
+                                       $this->I['accessKey'] = $this->accessKey($this->I['title']);
+                               } else {
+                                       $this->I['accessKey'] = Array();
+                               }
+
                                        // Make link tag
-                               $this->I['val']['ATagParams'] = $this->I['val']['ATagParams'] ? ' '.$this->I['val']['ATagParams'] : '';
-                               $this->I['linkHREF'] =  $this->link($key,$this->I['val']['altTarget'],$this->mconf['forceTypeValue']);
+                               $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.']);
+                               $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.']);
+                               $titleAttrValue = $this->WMcObj->stdWrap($this->I['val']['ATagTitle'],$this->I['val']['ATagTitle.']).$this->I['accessKey']['alt'];
                                if (strlen($titleAttrValue))    {
                                        $this->I['linkHREF']['title'] = $titleAttrValue;
                                }
@@ -1496,7 +1677,7 @@ class tslib_tmenu extends tslib_menu {
                                        $this->I['A2'] = '';
                                }
 
-                                       // ATAGBeforeWrap processing:
+                                       // ATagBeforeWrap processing:
                                if ($this->I['val']['ATagBeforeWrap'])  {
                                        $wrapPartsBefore = explode('|',$this->I['val']['linkWrap']);
                                        $wrapPartsAfter = array('','');
@@ -1567,13 +1748,13 @@ class tslib_tmenu extends tslib_menu {
                                $imgROInfo[3] = t3lib_div::png_to_gif_by_imagemagick($imgROInfo[3]);
                                if ($imgROInfo) {
                                        $theName = $this->imgNamePrefix.$this->I['uid'].$this->I['INPfix'].$pref;
-                                       $name = ' name="'.$theName.'"';
+                                       $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']->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']:'').' border="0"';
+                       $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'];}
@@ -1647,7 +1828,7 @@ class tslib_tmenu extends tslib_menu {
        function extProc_afterLinking($key)     {
                        // Add part to the accumulated result + fetch submenus
                if (!$this->I['spacer'])        {
-                       $this->I['theItem'].= $this->subMenu($this->I['uid']);
+                       $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'];
        }
@@ -1673,6 +1854,10 @@ class tslib_tmenu extends tslib_menu {
         * @see writeMenu(), tslib_tmenu_layers::extProc_finish()
         */
        function extProc_finish()       {
+                       // stdWrap:
+               if (is_array($this->mconf['stdWrap.'])) {
+                       $this->WMresult = $this->WMcObj->stdWrap($this->WMresult,$this->mconf['stdWrap.']);
+               }
                return $this->tmpl->wrap($this->WMresult,$this->mconf['wrap']).$this->WMextraScript;
        }
 }
@@ -1703,7 +1888,7 @@ class tslib_tmenu extends tslib_menu {
 /**
  * Extension class creating graphic based menus (PNG or GIF files)
  *
- * @author     Kasper Skaarhoj <kasper@typo3.com>
+ * @author     Kasper Skaarhoj <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
@@ -1912,12 +2097,14 @@ class tslib_gmenu extends tslib_menu {
                                $gifFileName = $gifCreator->fileName('menu/');
                        }
 
+                       $this->result[$resKey][$key] = $conf[$key];
+
                                // Generation of image file:
                        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]);
-                               $this->result[$resKey][$key]['output_file']=$gifFileName;
+                               $this->result[$resKey][$key]['output_file'] = $gifFileName;
                        } elseif ($isGD) {              // file is generated
                                $gifCreator->make();
                                $this->result[$resKey][$key]['output_w']=$gifCreator->w;
@@ -1926,22 +2113,13 @@ class tslib_gmenu extends tslib_menu {
                                $gifCreator->output($this->result[$resKey][$key]['output_file']);
                                $gifCreator->destroy();
                        }
+
                        $this->result[$resKey][$key]['output_file'] = t3lib_div::png_to_gif_by_imagemagick($this->result[$resKey][$key]['output_file']);
-                       $this->result[$resKey][$key]['noLink']=$conf[$key]['noLink'];
-                       $this->result[$resKey][$key]['altTarget']=$conf[$key]['altTarget'];
-                       $this->result[$resKey][$key]['imgParams']=$conf[$key]['imgParams'];
-                       $this->result[$resKey][$key]['ATagTitle'] = $conf[$key]['ATagTitle'];
-                       $this->result[$resKey][$key]['ATagTitle.'] = $conf[$key]['ATagTitle.'];
-                       $this->result[$resKey][$key]['wrap'] = $conf[$key]['wrap'];
-                       $this->result[$resKey][$key]['allWrap'] = $conf[$key]['allWrap'];
-                       $this->result[$resKey][$key]['allWrap.'] = $conf[$key]['allWrap.'];
-                       $this->result[$resKey][$key]['subst_elementUid'] = $conf[$key]['subst_elementUid'];
-                       $this->result[$resKey][$key]['allStdWrap.'] = $conf[$key]['allStdWrap.'];
 
                        $Hcounter+=$this->result[$resKey][$key]['output_h'];            // counter is increased
                        $Wcounter+=$this->result[$resKey][$key]['output_w'];            // counter is increased
 
-                       if ($maxFlag){break;}
+                       if ($maxFlag)   break;
                }
        }
 
@@ -2035,17 +2213,20 @@ class tslib_gmenu extends tslib_menu {
        function writeMenu()    {
                if (is_array($this->menuArr) && is_array($this->result) && count($this->result) && is_array($this->result['NO']))       {
                        $this->WMcObj = t3lib_div::makeInstance('tslib_cObj');  // Create new tslib_cObj for our use
-                       $this->WMresult='';
+                       $this->WMresult = '';
                        $this->INPfixMD5 = substr(md5(microtime().$this->GMENU_fixKey),0,4);
                        $this->WMmenuItems = count($this->result['NO']);
+
+                       $this->WMsubmenuObjSuffixes = $this->tmpl->splitConfArray(array('sOSuffix'=>$this->mconf['submenuObjSuffixes']),$this->WMmenuItems);
+
                        $this->extProc_init();
                        for ($key=0;$key<$this->WMmenuItems;$key++)     {
                                if ($this->result['NO'][$key]['output_file'])   {
                                        $this->WMcObj->start($this->menuArr[$key],'pages');             // Initialize the cObj with the page record of the menu item
 
-                                       $this->I =array();
+                                       $this->I = array();
                                        $this->I['key'] = $key;
-                                       $this->I['INPfix']= $this->imgNameNotRandom?'':'_'.$this->INPfixMD5.'_'.$key;
+                                       $this->I['INPfix']= ($this->imgNameNotRandom ? '' : '_'.$this->INPfixMD5).'_'.$key;
                                        $this->I['val'] = $this->result['NO'][$key];
                                        $this->I['title'] = $this->getPageTitle($this->menuArr[$key]['title'],$this->menuArr[$key]['nav_title']);
                                        $this->I['uid'] = $this->menuArr[$key]['uid'];
@@ -2054,12 +2235,22 @@ class tslib_gmenu extends tslib_menu {
                                        $this->I['spacer'] = $this->menuArr[$key]['isSpacer'];
                                        if (!$this->I['uid'] && !$this->menuArr[$key]['_OVERRIDE_HREF']) {$this->I['spacer']=1;}
                                        $this->I['noLink'] = ($this->I['spacer'] || $this->I['val']['noLink'] || !count($this->menuArr[$key]));         // !count($this->menuArr[$key]) means that this item is a dummyItem
-                                       $this->I['name']='';
+                                       $this->I['name'] = '';
+
+                                               // Set access key
+                                       if ($this->mconf['accessKey'])  {
+                                               $this->I['accessKey'] = $this->accessKey($this->I['title']);
+                                       } else {
+                                               $this->I['accessKey'] = array();
+                                       }
 
-                                               // Get link.
+                                               // 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.']);
                                        $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.']);
+                                       $titleAttrValue = $this->WMcObj->stdWrap($this->I['val']['ATagTitle'],$this->I['val']['ATagTitle.']).$this->I['accessKey']['alt'];
                                        if (strlen($titleAttrValue))    {
                                                $this->I['linkHREF']['title'] = $titleAttrValue;
                                        }
@@ -2071,7 +2262,7 @@ class tslib_gmenu extends tslib_menu {
                                                // Set rollover
                                        if ($this->result['RO'][$key] && !$this->I['noLink'])   {
                                                $this->I['theName'] = $this->imgNamePrefix.$this->I['uid'].$this->I['INPfix'];
-                                               $this->I['name'] = ' name="'.$this->I["theName"].'"';
+                                               $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'].'"; ';
@@ -2080,15 +2271,9 @@ class tslib_gmenu extends tslib_menu {
                                                $GLOBALS['TSFE']->setJS('mouseOver');
                                                $this->extProc_RO($key);
                                        }
-                                               // Set access key
-                                       if ($this->mconf['accessKey'])  {
-                                               $this->I['accessKey'] = $this->accessKey($this->I['title']);
-                                       } else {
-                                               $this->I['accessKey']=Array();
-                                       }
 
                                                // Set altText
-                                       $this->I['altText'] = $this->mconf['disableAltText'] ? '' : $this->I['title'].$this->I['accessKey']['alt'];
+                                       $this->I['altText'] = $this->I['title'].$this->I['accessKey']['alt'];
 
                                                // Calling extra processing function
                                        $this->extProc_beforeLinking($key);
@@ -2100,7 +2285,7 @@ class tslib_gmenu extends tslib_menu {
                                                $this->I['A1'] = '';
                                                $this->I['A2'] = '';
                                        }
-                                       $this->I['IMG'] = '<img src="'.$GLOBALS['TSFE']->absRefPrefix.$this->I['val']['output_file'].'" width="'.$this->I['val']['output_w'].'" height="'.$this->I['val']['output_h'].'" border="0" alt="'.htmlspecialchars($this->I['altText']).'"'.$this->I['name'].($this->I['val']['imgParams']?' '.$this->I['val']['imgParams']:'').' />';
+                                       $this->I['IMG'] = '<img src="'.$GLOBALS['TSFE']->absRefPrefix.$this->I['val']['output_file'].'" width="'.$this->I['val']['output_w'].'" height="'.$this->I['val']['output_h'].'" '.tslib_cObj::getBorderAttr('border="0"').($this->mconf['disableAltText'] ? '' : ' alt="'.htmlspecialchars($this->I['altText']).'"').$this->I['name'].($this->I['val']['imgParams']?' '.$this->I['val']['imgParams']:'').' />';
 
                                                // Make before, middle and after parts
                                        $this->I['parts'] = array();
@@ -2187,7 +2372,7 @@ class tslib_gmenu extends tslib_menu {
        function extProc_afterLinking($key)     {
                $this->WMresult.=$this->I['theItem'];
                if (!$this->I['spacer'])        {
-                       $this->WMresult.= $this->subMenu($this->I['uid']);
+                       $this->WMresult.= $this->subMenu($this->I['uid'], $this->WMsubmenuObjSuffixes[$key]['sOSuffix']);
                }
        }
 
@@ -2213,6 +2398,10 @@ class tslib_gmenu extends tslib_menu {
         * @see writeMenu(), tslib_gmenu_layers::extProc_finish()
         */
        function extProc_finish()       {
+                       // stdWrap:
+               if (is_array($this->mconf['stdWrap.'])) {
+                       $this->WMresult = $this->WMcObj->stdWrap($this->WMresult,$this->mconf['stdWrap.']);
+               }
                return $this->tmpl->wrap($this->WMresult,$this->mconf['wrap']).$this->WMextraScript;
        }
 }
@@ -2241,7 +2430,7 @@ class tslib_gmenu extends tslib_menu {
 /**
  * ImageMap based menus
  *
- * @author     Kasper Skaarhoj <kasper@typo3.com>
+ * @author     Kasper Skaarhoj <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
@@ -2319,6 +2508,9 @@ class tslib_imgmenu extends tslib_menu {
 
                                                                        $LD = $this->tmpl->linkData($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']);
+
                                                                                // Overriding URL / Target if set to do so:
                                                                        if ($this->menuArr[$key]['_OVERRIDE_HREF'])     {
                                                                                $LD['totalURL'] = $this->menuArr[$key]['_OVERRIDE_HREF'];
@@ -2458,7 +2650,7 @@ class tslib_imgmenu extends tslib_menu {
         */
        function writeMenu()    {
                if ($this->result)      {
-                       $res = $this->result;
+                       $res = &$this->result;
                        $menuName = 'menu_'.t3lib_div::shortMD5($res['imgMap']);        // shortMD5 260900
                        $result = '<img src="'.$GLOBALS['TSFE']->absRefPrefix.$res['output_file'].'" width="'.$res['output_w'].'" height="'.$res['output_h'].'" usemap="#'.$menuName.'" border="0" '.$this->mconf['params'];
                        if (!strstr($result,'alt="'))   $result.=' alt="Menu Image Map"';       // Adding alt attribute if not set.
@@ -2494,7 +2686,7 @@ class tslib_imgmenu extends tslib_menu {
 /**
  * JavaScript/Selectorbox based menus
  *
- * @author     Kasper Skaarhoj <kasper@typo3.com>
+ * @author     Kasper Skaarhoj <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
@@ -2590,10 +2782,7 @@ class tslib_jsmenu extends tslib_menu {
                $MP_params = $MP_var ? '&MP='.rawurlencode($MP_var) : '';
 
                        // UIDs to ban:
-               $banUidArray=array();
-               if (trim($this->conf['excludeUidList']))        {
-                       $banUidArray = t3lib_div::intExplode(',', $this->conf['excludeUidList']);
-               }
+               $banUidArray = $this->getBannedUids();
 
                        // Initializing variables:
                $var = $this->JSVarName;
@@ -2606,21 +2795,25 @@ class tslib_jsmenu extends tslib_menu {
                foreach($menuItems as $uid => $data)    {
                        $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'] && !t3lib_div::inArray($banUidArray,$uid))     {               // Page may not be 'not_in_menu' or 'Backend User Section' + not in banned uid's
+                               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);
                                        } else {
                                                $addLines = '';
                                        }
-                                       $title=rawurlencode($data['title']);
+                                       $title=$data['title'];
                                        $url='';
                                        $target='';
                                        if ((!$addLines && !$levelConf['noLink']) || $levelConf['alwaysLink']) {
                                                $LD = $this->tmpl->linkData($data,$this->mconf['target'],'','',array(),$MP_params,$this->mconf['forceTypeValue']);
-                                               $url = rawurlencode($LD['totalURL']);
-                                               $target = rawurlencode($LD['target']);
+
+                                                       // 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']);
+
+                                               $url = $GLOBALS['TSFE']->baseUrlWrap($LD['totalURL']);
+                                               $target = $LD['target'];
                                        }
-                                       $codeLines.="\n".$var.$count."=".$menuName.".add(".$parent.",".$prev.",0,'".$title."','".$url."','".$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).");";
                                                // If the active one should be chosen...
                                        $active = ($levelConf['showActive'] && $data['uid'] == $this->tmpl->rootLine[$count]['uid']);
                                                // If the first item should be shown
@@ -2643,10 +2836,10 @@ class tslib_jsmenu extends tslib_menu {
                }
                if ($this->mconf['firstLabelGeneral'] && !$levelConf['firstLabel'])     {
                        $levelConf['firstLabel'] = $this->mconf['firstLabelGeneral'];
-       }
+               }
                if ($levelConf['firstLabel'] && $codeLines)     {
-                       $codeLines.="\n".$menuName.".defTopTitle[".$count."] = unescape('".rawurlencode($levelConf['firstLabel'])."');";
-}
+                       $codeLines.= chr(10).$menuName.'.defTopTitle['.$count.'] = '.t3lib_div::quoteJSvalue($levelConf['firstLabel'], true).';';
+               }
                return $codeLines;
        }
 }
@@ -2656,4 +2849,4 @@ if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_menu.php']);
 }
 
-?>
\ No newline at end of file
+?>