class.tslib_menu.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com)
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *  A copy is found in the textfile GPL.txt and important notices to the license
00017 *  from the author is found in LICENSE.txt distributed with these scripts.
00018 *
00019 *
00020 *  This script is distributed in the hope that it will be useful,
00021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 *  GNU General Public License for more details.
00024 *
00025 *  This copyright notice MUST APPEAR in all copies of the script!
00026 ***************************************************************/
00145 class tslib_menu {
00146         var $menuNumber = 1;                            // tells you which menu-number this is. This is important when getting data from the setup
00147         var $entryLevel = 0;                            // 0 = rootFolder
00148         var $spacerIDList = '199';                      // The doktype-number that defines a spacer
00149         var $doktypeExcludeList = '5,6';                        // doktypes that define which should not be included in a menu
00150         var $alwaysActivePIDlist=array();
00151         var $imgNamePrefix = 'img';
00152         var $imgNameNotRandom=0;
00153         var $debug = 0;
00154         var $parent_cObj ='';                           // Loaded with the parent cObj-object when a new HMENU is made
00155         var $GMENU_fixKey='gmenu';
00156         var $MP_array=array();                          // accumulation of mount point data
00157 
00158                 // internal
00159         var $conf = Array();                            // HMENU configuration
00160         var $mconf = Array();                           // xMENU configuration (TMENU, GMENU etc)
00161         var $tmpl;              // template-object
00162         var $sys_page;  // sys_page-object
00163         var $id;                                                        // The base page-id of the menu.
00164         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.
00165         var $menuArr;   // The array of menuItems which is built
00166         var $hash;
00167         var $result = Array();
00168         var $rL_uidRegister = '';                       // Array: Is filled with an array of page uid numbers + RL parameters which are in the current root line (used to evaluate whether a menu item is in active state)
00169         var $INPfixMD5;
00170         var $I;
00171         var $WMresult;
00172         var $WMfreezePrefix;
00173         var $WMmenuItems;
00174         var $WMsubmenuObjSuffixes;
00175         var $WMextraScript;
00176         var $alternativeMenuTempArray='';               // Can be set to contain menu item arrays for sub-levels.
00177         var $nameAttribute = 'name';                    // Will be 'id' in XHTML-mode
00178 
00191         function start(&$tmpl,&$sys_page,$id,$conf,$menuNumber,$objSuffix='')   {
00192 
00193                         // Init:
00194                 $this->conf = $conf;
00195                 $this->menuNumber = $menuNumber;
00196                 $this->mconf = $conf[$this->menuNumber.$objSuffix.'.'];
00197                 $this->debug=$GLOBALS['TSFE']->debug;
00198 
00199                         // In XHTML there is no "name" attribute anymore
00200                 switch ($GLOBALS['TSFE']->xhtmlDoctype) {
00201                         case 'xhtml_strict':
00202                         case 'xhtml_11':
00203                         case 'xhtml_2':
00204                                 $this->nameAttribute = 'id';
00205                                 break;
00206                         default:
00207                                 $this->nameAttribute = 'name';
00208                                 break;
00209                 }
00210 
00211                         // Sets the internal vars. $tmpl MUST be the template-object. $sys_page MUST be the sys_page object
00212                 if ($this->conf[$this->menuNumber.$objSuffix] && is_object($tmpl) && is_object($sys_page))      {
00213                         $this->tmpl = &$tmpl;
00214                         $this->sys_page = &$sys_page;
00215 
00216                                 // alwaysActivePIDlist initialized:
00217                         if (trim($this->conf['alwaysActivePIDlist']))   {
00218                                 $this->alwaysActivePIDlist = t3lib_div::intExplode(',', $this->conf['alwaysActivePIDlist']);
00219                         }
00220 
00221                                 // 'not in menu' doktypes
00222                         if($this->conf['excludeDoktypes']) {
00223                                 $this->doktypeExcludeList = $GLOBALS['TYPO3_DB']->cleanIntList($this->conf['excludeDoktypes']);
00224                         }
00225                         if($this->conf['includeNotInMenu']) {
00226                                 $exclDoktypeArr = t3lib_div::trimExplode(',',$this->doktypeExcludeList,1);
00227                                 $exclDoktypeArr = t3lib_div::removeArrayEntryByValue($exclDoktypeArr,'5');
00228                                 $this->doktypeExcludeList = implode(',',$exclDoktypeArr);
00229                         }
00230 
00231                                 // EntryLevel
00232                         $this->entryLevel = tslib_cObj::getKey ($conf['entryLevel'],$this->tmpl->rootLine);
00233 
00234                                 // Set parent page: If $id not stated with start() then the base-id will be found from rootLine[$this->entryLevel]
00235                         if ($id)        {       // Called as the next level in a menu. It is assumed that $this->MP_array is set from parent menu.
00236                                 $this->id = intval($id);
00237                         } else {        // This is a BRAND NEW menu, first level. So we take ID from rootline and also find MP_array (mount points)
00238                                 $this->id = intval($this->tmpl->rootLine[$this->entryLevel]['uid']);
00239 
00240                                         // Traverse rootline to build MP_array of pages BEFORE the entryLevel
00241                                         // (MP var for ->id is picked up in the next part of the code...)
00242                                 foreach($this->tmpl->rootLine as $entryLevel => $levelRec)      {
00243                                                 // For overlaid mount points, set the variable right now:
00244                                         if ($levelRec['_MP_PARAM'] && $levelRec['_MOUNT_OL'])   {
00245                                                 $this->MP_array[] = $levelRec['_MP_PARAM'];
00246                         }
00247                                                 // Break when entry level is reached:
00248                                         if ($entryLevel>=$this->entryLevel)     break;
00249 
00250                                                 // For normal mount points, set the variable for next level.
00251                                         if ($levelRec['_MP_PARAM'] && !$levelRec['_MOUNT_OL'])  {
00252                                                 $this->MP_array[] = $levelRec['_MP_PARAM'];
00253                                         }
00254                                 }
00255                         }
00256 
00257                                 // Return false if no page ID was set (thus no menu of subpages can be made).
00258                         if ($this->id<=0)       {
00259                                 return FALSE;
00260                         }
00261 
00262                                 // Check if page is a mount point, and if so set id and MP_array
00263                                 // (basically this is ONLY for non-overlay mode, but in overlay mode an ID with a mount point should never reach this point anyways, so no harm done...)
00264                         $mount_info = $this->sys_page->getMountPointInfo($this->id);
00265                         if (is_array($mount_info))      {
00266                                 $this->MP_array[] = $mount_info['MPvar'];
00267                                 $this->id = $mount_info['mount_pid'];
00268                         }
00269 
00270                                 // Gather list of page uids in root line (for "isActive" evaluation). Also adds the MP params in the path so Mount Points are respected.
00271                                 // (List is specific for this rootline, so it may be supplied from parent menus for speed...)
00272                         if (!is_array($this->rL_uidRegister))   {
00273                                 $rl_MParray = array();
00274                                 foreach($this->tmpl->rootLine as $v_rl) {
00275                                                 // For overlaid mount points, set the variable right now:
00276                                         if ($v_rl['_MP_PARAM'] && $v_rl['_MOUNT_OL'])   {
00277                                                 $rl_MParray[] = $v_rl['_MP_PARAM'];
00278                                         }
00279 
00280                                                 // Add to register:
00281                                         $this->rL_uidRegister[] = 'ITEM:'.$v_rl['uid'].(count($rl_MParray) ? ':'.implode(',',$rl_MParray) : '');
00282 
00283                                                 // For normal mount points, set the variable for next level.
00284                                         if ($v_rl['_MP_PARAM'] && !$v_rl['_MOUNT_OL'])  {
00285                                                 $rl_MParray[] = $v_rl['_MP_PARAM'];
00286                                         }
00287                                 }
00288                         }
00289 
00290                                 // Setting "nextActive": This is the page uid + MPvar of the NEXT page in rootline. Used to expand the menu if we are in the right branch of the tree
00291                                 // Notice: The automatic expansion of a menu is designed to work only when no "special" modes are used.
00292                         if (is_array($this->tmpl->rootLine[$this->entryLevel+$this->menuNumber]))       {
00293                                 $nextMParray = $this->MP_array;
00294                                 if ($this->tmpl->rootLine[$this->entryLevel+$this->menuNumber]['_MOUNT_OL'])    {       // In overlay mode, add next level MPvars as well:
00295                                         $nextMParray[] = $this->tmpl->rootLine[$this->entryLevel+$this->menuNumber]['_MP_PARAM'];
00296                                 }
00297                                 $this->nextActive = $this->tmpl->rootLine[$this->entryLevel+$this->menuNumber]['uid'].
00298                                                                                 (count($nextMParray)?':'.implode(',',$nextMParray):'');
00299                         } else {
00300                                 $this->nextActive = '';
00301                         }
00302 
00303                                 // imgNamePrefix
00304                         if ($this->mconf['imgNamePrefix']) {
00305                                 $this->imgNamePrefix=$this->mconf['imgNamePrefix'];
00306                         }
00307                         $this->imgNameNotRandom = $this->mconf['imgNameNotRandom'];
00308 
00309                         $retVal = TRUE;
00310                 } else {
00311                         $GLOBALS['TT']->setTSlogMessage('ERROR in menu',3);
00312                         $retVal = FALSE;
00313                 }
00314                 return $retVal;
00315         }
00316 
00324         function makeMenu()     {
00325                 if ($this->id)  {
00326 
00327                                 // Initializing showAccessRestrictedPages
00328                         if ($this->mconf['showAccessRestrictedPages'])  {
00329                                         // SAVING where_groupAccess
00330                                 $SAVED_where_groupAccess = $this->sys_page->where_groupAccess;
00331                                 $this->sys_page->where_groupAccess = '';        // Temporarily removing fe_group checking!
00332                         }
00333 
00334                                 // Begin production of menu:
00335                         $temp = array();
00336                         $altSortFieldValue = trim($this->mconf['alternativeSortingField']);
00337                         $altSortField = $altSortFieldValue ? $altSortFieldValue : 'sorting';
00338                         if ($this->menuNumber==1 && $this->conf['special'])     {               // ... only for the FIRST level of a HMENU
00339                                 $value = $this->conf['special.']['value'];
00340 
00341                                 switch($this->conf['special'])  {
00342                                         case 'userdefined':
00343                                                 $temp = $this->includeMakeMenu($this->conf['special.'],$altSortField);
00344                                         break;
00345                                         case 'userfunction':
00346                                                 $temp = $this->parent_cObj->callUserFunction(
00347                                                         $this->conf['special.']['userFunc'],
00348                                                         array_merge($this->conf['special.'],array('_altSortField'=>$altSortField)),
00349                                                         ''
00350                                                 );
00351                                                 if (!is_array($temp))   $temp=array();
00352                                         break;
00353                                         case 'language':
00354                                                 $temp = array();
00355 
00356                                                         // Getting current page record NOT overlaid by any translation:
00357                                                 $currentPageWithNoOverlay = $this->sys_page->getRawRecord('pages',$GLOBALS['TSFE']->page['uid']);
00358 
00359                                                         // Traverse languages set up:
00360                                                 $languageItems = t3lib_div::intExplode(',',$value);
00361                                                 foreach($languageItems as $sUid)        {
00362                                                                 // Find overlay record:
00363                                                         if ($sUid)      {
00364                                                                 $lRecs = $this->sys_page->getPageOverlay($GLOBALS['TSFE']->page['uid'],$sUid);
00365                                                         } else $lRecs=array();
00366                                                                 // Checking if the "disabled" state should be set.
00367                                                         if (
00368                                                                                 (t3lib_div::hideIfNotTranslated($GLOBALS['TSFE']->page['l18n_cfg']) && $sUid && !count($lRecs)) // Blocking for all translations?
00369                                                                         || ($GLOBALS['TSFE']->page['l18n_cfg']&1 && (!$sUid || !count($lRecs))) // Blocking default translation?
00370                                                                         || (!$this->conf['special.']['normalWhenNoLanguage'] && $sUid && !count($lRecs))
00371                                                                 )       {
00372                                                                 $iState = $GLOBALS['TSFE']->sys_language_uid==$sUid ? 'USERDEF2' : 'USERDEF1';
00373                                                         } else {
00374                                                                 $iState = $GLOBALS['TSFE']->sys_language_uid==$sUid ? 'ACT' : 'NO';
00375                                                         }
00376 
00377                                                         if ($this->conf['addQueryString'])      {
00378                                                                 $getVars = $this->parent_cObj->getQueryArguments($this->conf['addQueryString.'],array('L'=>$sUid),true);
00379                                                         } else {
00380                                                                 $getVars = '&L='.$sUid;
00381                                                         }
00382 
00383                                                                 // Adding menu item:
00384                                                         $temp[] = array_merge(
00385                                                                 array_merge($currentPageWithNoOverlay, $lRecs),
00386                                                                 array(
00387                                                                         'ITEM_STATE' => $iState,
00388                                                                         '_ADD_GETVARS' => $getVars,
00389                                                                         '_SAFE' => TRUE
00390                                                                 )
00391                                                         );
00392                                                 }
00393                                         break;
00394                                         case 'directory':
00395                                                 if ($value=='') {
00396                                                         $value=$GLOBALS['TSFE']->page['uid'];
00397                                                 }
00398                                                 $items=t3lib_div::intExplode(',',$value);
00399 
00400                                                 foreach($items as $id)  {
00401                                                         $MP = $this->tmpl->getFromMPmap($id);
00402 
00403                                                                 // Checking if a page is a mount page and if so, change the ID and set the MP var properly.
00404                                                         $mount_info = $this->sys_page->getMountPointInfo($id);
00405                                                         if (is_array($mount_info))      {
00406                                                                 if ($mount_info['overlay'])     {       // Overlays should already have their full MPvars calculated:
00407                                                                         $MP = $this->tmpl->getFromMPmap($mount_info['mount_pid']);
00408                                                                         $MP = $MP ? $MP : $mount_info['MPvar'];
00409                                                                 } else {
00410                                                                         $MP = ($MP ? $MP.',' : '').$mount_info['MPvar'];
00411                                                                 }
00412                                                                 $id = $mount_info['mount_pid'];
00413                                                         }
00414 
00415                                                                 // Get sub-pages:
00416                                                         $res = $GLOBALS['TSFE']->cObj->exec_getQuery('pages',Array('pidInList'=>$id,'orderBy'=>$altSortField));
00417                                                         while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {
00418                                                                 $GLOBALS['TSFE']->sys_page->versionOL('pages',$row);
00419 
00420                                                                 if (is_array($row))     {
00421                                                                                 // Keep mount point?
00422                                                                         $mount_info = $this->sys_page->getMountPointInfo($row['uid'], $row);
00423                                                                         if (is_array($mount_info) && $mount_info['overlay'])    {       // There is a valid mount point.
00424                                                                                 $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!
00425                                                                                 if (count($mp_row))     {
00426                                                                                         $row = $mp_row;
00427                                                                                         $row['_MP_PARAM'] = $mount_info['MPvar'];
00428                                                                                 } 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!
00429                                                                         }
00430 
00431                                                                                 // Add external MP params, then the row:
00432                                                                         if (is_array($row))     {
00433                                                                                 if ($MP)        $row['_MP_PARAM'] = $MP.($row['_MP_PARAM'] ? ','.$row['_MP_PARAM'] : '');
00434                                                                                 $temp[$row['uid']] = $this->sys_page->getPageOverlay($row);
00435                                                                         }
00436                                                                 }
00437                                                         }
00438                                                 }
00439                                         break;
00440                                         case 'list':
00441                                                 if ($value=='') {
00442                                                         $value=$this->id;
00443                                                 }
00444                                                 $loadDB = t3lib_div::makeInstance('FE_loadDBGroup');
00445                                                 $loadDB->start($value, 'pages');
00446                                                 $loadDB->additionalWhere['pages']=tslib_cObj::enableFields('pages');
00447                                                 $loadDB->getFromDB();
00448 
00449                                                 foreach($loadDB->itemArray as $val)     {
00450                                                         $MP = $this->tmpl->getFromMPmap($val['id']);
00451 
00452                                                                 // Keep mount point?
00453                                                         $mount_info = $this->sys_page->getMountPointInfo($val['id']);
00454                                                         if (is_array($mount_info) && $mount_info['overlay'])    {       // There is a valid mount point.
00455                                                                 $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!
00456                                                                 if (count($mp_row))     {
00457                                                                         $row = $mp_row;
00458                                                                         $row['_MP_PARAM'] = $mount_info['MPvar'];
00459 
00460                                                                         if ($mount_info['overlay'])     {       // Overlays should already have their full MPvars calculated:
00461                                                                                 $MP = $this->tmpl->getFromMPmap($mount_info['mount_pid']);
00462                                                                                 if ($MP) unset($row['_MP_PARAM']);
00463                                                                         }
00464                                                                 } 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!
00465                                                         } else {
00466                                                                 $row = $loadDB->results['pages'][$val['id']];
00467                                                         }
00468 
00469                                                                 // Add external MP params, then the row:
00470                                                         if (is_array($row))     {
00471                                                                 if ($MP)        $row['_MP_PARAM'] = $MP.($row['_MP_PARAM'] ? ','.$row['_MP_PARAM'] : '');
00472                                                                 $temp[] = $this->sys_page->getPageOverlay($row);
00473                                                         }
00474                                                 }
00475                                         break;
00476                                         case 'updated':
00477                                                 if ($value=='') {
00478                                                         $value=$GLOBALS['TSFE']->page['uid'];
00479                                                 }
00480                                                 $items=t3lib_div::intExplode(',',$value);
00481                                                 if (t3lib_div::testInt($this->conf['special.']['depth']))       {
00482                                                         $depth = t3lib_div::intInRange($this->conf['special.']['depth'],1,20);          // Tree depth
00483                                                 } else {
00484                                                         $depth=20;
00485                                                 }
00486                                                 $limit = t3lib_div::intInRange($this->conf['special.']['limit'],0,100); // max number of items
00487                                                 $maxAge = intval(tslib_cObj::calc($this->conf['special.']['maxAge']));
00488                                                 if (!$limit)    $limit=10;
00489                                                 $mode = $this->conf['special.']['mode'];        // *'auto', 'manual', 'tstamp'
00490                                                         // Get id's
00491                                                 $id_list_arr = Array();
00492 
00493                                                 foreach($items as $id)  {
00494                                                         $bA = t3lib_div::intInRange($this->conf['special.']['beginAtLevel'],0,100);
00495                                                         $id_list_arr[] = tslib_cObj::getTreeList(-1*$id,$depth-1+$bA,$bA-1);
00496                                                 }
00497                                                 $id_list = implode(',',$id_list_arr);
00498                                                         // Get sortField (mode)
00499                                                 switch($mode)   {
00500                                                         case 'starttime':
00501                                                                 $sortField = 'starttime';
00502                                                         break;
00503                                                         case 'lastUpdated':
00504                                                         case 'manual':
00505                                                                 $sortField = 'lastUpdated';
00506                                                         break;
00507                                                         case 'tstamp':
00508                                                                 $sortField = 'tstamp';
00509                                                         break;
00510                                                         case 'crdate':
00511                                                                 $sortField = 'crdate';
00512                                                         break;
00513                                                         default:
00514                                                                 $sortField = 'SYS_LASTCHANGED';
00515                                                         break;
00516                                                 }
00517                                                         // Get
00518                                                 $extraWhere = ($this->conf['includeNotInMenu'] ? '' : ' AND pages.nav_hide=0').$this->getDoktypeExcludeWhere();
00519 
00520                                                 if ($this->conf['special.']['excludeNoSearchPages']) {
00521                                                         $extraWhere.= ' AND pages.no_search=0';
00522                                                 }
00523                                                 if ($maxAge>0)  {
00524                                                         $extraWhere.=' AND '.$sortField.'>'.($GLOBALS['SIM_EXEC_TIME']-$maxAge);
00525                                                 }
00526 
00527                                                 $res = $GLOBALS['TSFE']->cObj->exec_getQuery('pages',Array('pidInList'=>'0', 'uidInList'=>$id_list, 'where'=>$sortField.'>=0'.$extraWhere, 'orderBy'=>($altSortFieldValue ? $altSortFieldValue : $sortField.' desc'),'max'=>$limit));
00528                                                 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {
00529                                                         $GLOBALS['TSFE']->sys_page->versionOL('pages',$row);
00530                                                         if (is_array($row))     {
00531                                                                 $temp[$row['uid']]=$this->sys_page->getPageOverlay($row);
00532                                                         }
00533                                                 }
00534                                         break;
00535                                         case 'keywords':
00536                                                 list($value)=t3lib_div::intExplode(',',$value);
00537                                                 if (!$value) {
00538                                                         $value=$GLOBALS['TSFE']->page['uid'];
00539                                                 }
00540                                                 if ($this->conf['special.']['setKeywords'] || $this->conf['special.']['setKeywords.']) {
00541                                                         $kw = $this->parent_cObj->stdWrap($this->conf['special.']['setKeywords'], $this->conf['special.']['setKeywords.']);
00542                                                 } else {
00543                                                         $value_rec=$this->sys_page->getPage($value);    // The page record of the 'value'.
00544 
00545                                                         $kfieldSrc = $this->conf['special.']['keywordsField.']['sourceField'] ? $this->conf['special.']['keywordsField.']['sourceField'] : 'keywords';
00546                                                         $kw = trim(tslib_cObj::keywords($value_rec[$kfieldSrc]));               // keywords.
00547                                                 }
00548 
00549                                                 $mode = $this->conf['special.']['mode'];        // *'auto', 'manual', 'tstamp'
00550                                                 switch($mode)   {
00551                                                         case 'starttime':
00552                                                                 $sortField = 'starttime';
00553                                                         break;
00554                                                         case 'lastUpdated':
00555                                                         case 'manual':
00556                                                                 $sortField = 'lastUpdated';
00557                                                         break;
00558                                                         case 'tstamp':
00559                                                                 $sortField = 'tstamp';
00560                                                         break;
00561                                                         case 'crdate':
00562                                                                 $sortField = 'crdate';
00563                                                         break;
00564                                                         default:
00565                                                                 $sortField = 'SYS_LASTCHANGED';
00566                                                         break;
00567                                                 }
00568 
00569                                                         // depth, limit, extra where
00570                                                 if (t3lib_div::testInt($this->conf['special.']['depth']))       {
00571                                                         $depth = t3lib_div::intInRange($this->conf['special.']['depth'],0,20);          // Tree depth
00572                                                 } else {
00573                                                         $depth=20;
00574                                                 }
00575                                                 $limit = t3lib_div::intInRange($this->conf['special.']['limit'],0,100); // max number of items
00576                                                 $extraWhere = ' AND pages.uid!='.$value.($this->conf['includeNotInMenu'] ? '' : ' AND pages.nav_hide=0').$this->getDoktypeExcludeWhere();
00577                                                 if ($this->conf['special.']['excludeNoSearchPages']) {
00578                                                         $extraWhere.= ' AND pages.no_search=0';
00579                                                 }
00580                                                         // start point
00581                                                 $eLevel = tslib_cObj::getKey (intval($this->conf['special.']['entryLevel']),$this->tmpl->rootLine);
00582                                                 $startUid = intval($this->tmpl->rootLine[$eLevel]['uid']);
00583 
00584                                                         // which field is for keywords
00585                                                 $kfield = 'keywords';
00586                                                 if ( $this->conf['special.']['keywordsField'] ) {
00587                                                         list($kfield) = explode(' ',trim ($this->conf['special.']['keywordsField']));
00588                                                 }
00589 
00590                                                         // If there are keywords and the startuid is present.
00591                                                 if ($kw && $startUid)   {
00592                                                         $bA = t3lib_div::intInRange($this->conf['special.']['beginAtLevel'],0,100);
00593                                                         $id_list=tslib_cObj::getTreeList(-1*$startUid,$depth-1+$bA,$bA-1);
00594 
00595                                                         $kwArr = explode(',',$kw);
00596                                                         foreach($kwArr as $word)        {
00597                                                                 $word = trim($word);
00598                                                                 if ($word)      {
00599                                                                         $keyWordsWhereArr[] = $kfield.' LIKE \'%'.$GLOBALS['TYPO3_DB']->quoteStr($word, 'pages').'%\'';
00600                                                                 }
00601                                                         }
00602                                                         $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));
00603                                                         while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {
00604                                                                 $GLOBALS['TSFE']->sys_page->versionOL('pages',$row);
00605                                                                 if (is_array($row))     {
00606                                                                         $temp[$row['uid']]=$this->sys_page->getPageOverlay($row);
00607                                                                 }
00608                                                         }
00609                                                 }
00610                                         break;
00611                                         case 'rootline':
00612                                                 $begin_end = explode('|',$this->conf['special.']['range']);
00613                                                 if (!t3lib_div::testInt($begin_end[0])) {intval($begin_end[0]);}
00614                                                 if (!t3lib_div::testInt($begin_end[1])) {$begin_end[1]=-1;}
00615 
00616                                                 $beginKey = tslib_cObj::getKey ($begin_end[0],$this->tmpl->rootLine);
00617                                                 $endKey = tslib_cObj::getKey ($begin_end[1],$this->tmpl->rootLine);
00618                                                 if ($endKey<$beginKey)  {$endKey=$beginKey;}
00619 
00620                                                 $rl_MParray = array();
00621                                                 foreach($this->tmpl->rootLine as $k_rl => $v_rl)        {
00622                                                                 // For overlaid mount points, set the variable right now:
00623                                                         if ($v_rl['_MP_PARAM'] && $v_rl['_MOUNT_OL'])   {
00624                                                                 $rl_MParray[] = $v_rl['_MP_PARAM'];
00625                                                         }
00626                                                                 // Traverse rootline:
00627                                                         if ($k_rl>=$beginKey && $k_rl<=$endKey) {
00628                                                                 $temp_key=$k_rl;
00629                                                                 $temp[$temp_key]=$this->sys_page->getPage($v_rl['uid']);
00630                                                                 if (count($temp[$temp_key]))    {
00631                                                                         if (!$temp[$temp_key]['target'])        {       // If there are no specific target for the page, put the level specific target on.
00632                                                                                 $temp[$temp_key]['target'] = $this->conf['special.']['targets.'][$k_rl];
00633                                                                                 $temp[$temp_key]['_MP_PARAM'] = implode(',',$rl_MParray);
00634                                                                         }
00635                                                                 } else unset($temp[$temp_key]);
00636                                                         }
00637                                                                 // For normal mount points, set the variable for next level.
00638                                                         if ($v_rl['_MP_PARAM'] && !$v_rl['_MOUNT_OL'])  {
00639                                                                 $rl_MParray[] = $v_rl['_MP_PARAM'];
00640                                                 }
00641                                                 }
00642                                         break;
00643                                         case 'browse':
00644                                                 list($value)=t3lib_div::intExplode(',',$value);
00645                                                 if (!$value) {
00646                                                         $value=$GLOBALS['TSFE']->page['uid'];
00647                                                 }
00648                                                 if ($value!=$this->tmpl->rootLine[0]['uid'])    {       // Will not work out of rootline
00649                                                         $recArr=array();
00650                                                         $value_rec=$this->sys_page->getPage($value);    // The page record of the 'value'.
00651                                                         if ($value_rec['pid'])  {       // 'up' page cannot be outside rootline
00652                                                                 $recArr['up']=$this->sys_page->getPage($value_rec['pid']);      // The page record of 'up'.
00653                                                         }
00654                                                         if ($recArr['up']['pid'] && $value_rec['pid']!=$this->tmpl->rootLine[0]['uid']) {       // If the 'up' item was NOT level 0 in rootline...
00655                                                                 $recArr['index']=$this->sys_page->getPage($recArr['up']['pid']);        // The page record of "index".
00656                                                         }
00657 
00658                                                                 // prev / next is found
00659                                                         $prevnext_menu = $this->sys_page->getMenu($value_rec['pid'],'*',$altSortField);
00660                                                         $lastKey=0;
00661                                                         $nextActive=0;
00662                                                         reset($prevnext_menu);
00663                                                         while(list($k_b,$v_b)=each($prevnext_menu))     {
00664                                                                 if ($nextActive)        {
00665                                                                         $recArr['next']=$v_b;
00666                                                                         $nextActive=0;
00667                                                                 }
00668                                                                 if ($v_b['uid']==$value)        {
00669                                                                         if ($lastKey)   {
00670                                                                                 $recArr['prev']=$prevnext_menu[$lastKey];
00671                                                                         }
00672                                                                         $nextActive=1;
00673                                                                 }
00674                                                                 $lastKey=$k_b;
00675                                                         }
00676                                                         reset($prevnext_menu);
00677                                                         $recArr['first']=pos($prevnext_menu);
00678                                                         end($prevnext_menu);
00679                                                         $recArr['last']=pos($prevnext_menu);
00680 
00681                                                                 // prevsection / nextsection is found
00682                                                         if (is_array($recArr['index'])) {       // You can only do this, if there is a valid page two levels up!
00683                                                                 $prevnextsection_menu = $this->sys_page->getMenu($recArr['index']['uid'],'*',$altSortField);
00684                                                                 $lastKey=0;
00685                                                                 $nextActive=0;
00686                                                                 reset($prevnextsection_menu);
00687                                                                 while(list($k_b,$v_b)=each($prevnextsection_menu))      {
00688                                                                         if ($nextActive)        {
00689                                                                                 $sectionRec_temp = $this->sys_page->getMenu($v_b['uid'],'*',$altSortField);
00690                                                                                 if (count($sectionRec_temp))    {
00691                                                                                         reset($sectionRec_temp);
00692                                                                                         $recArr['nextsection']=pos($sectionRec_temp);
00693                                                                                         end ($sectionRec_temp);
00694                                                                                         $recArr['nextsection_last']=pos($sectionRec_temp);
00695                                                                                         $nextActive=0;
00696                                                                                 }
00697                                                                         }
00698                                                                         if ($v_b['uid']==$value_rec['pid'])     {
00699                                                                                 if ($lastKey)   {
00700                                                                                         $sectionRec_temp = $this->sys_page->getMenu($prevnextsection_menu[$lastKey]['uid'],'*',$altSortField);
00701                                                                                         if (count($sectionRec_temp))    {
00702                                                                                                 reset($sectionRec_temp);
00703                                                                                                 $recArr['prevsection']=pos($sectionRec_temp);
00704                                                                                                 end ($sectionRec_temp);
00705                                                                                                 $recArr['prevsection_last']=pos($sectionRec_temp);
00706                                                                                         }
00707                                                                                 }
00708                                                                                 $nextActive=1;
00709                                                                         }
00710                                                                         $lastKey=$k_b;
00711                                                                 }
00712                                                         }
00713                                                         if ($this->conf['special.']['items.']['prevnextToSection'])     {
00714                                                                 if (!is_array($recArr['prev']) && is_array($recArr['prevsection_last']))        {
00715                                                                         $recArr['prev']=$recArr['prevsection_last'];
00716                                                                 }
00717                                                                 if (!is_array($recArr['next']) && is_array($recArr['nextsection']))     {
00718                                                                         $recArr['next']=$recArr['nextsection'];
00719                                                                 }
00720                                                         }
00721 
00722                                                         $items = explode('|',$this->conf['special.']['items']);
00723                                                         $c=0;
00724                                                         while(list($k_b,$v_b)=each($items))     {
00725                                                                 $v_b=strtolower(trim($v_b));
00726                                                                 if (intval($this->conf['special.'][$v_b.'.']['uid']))   {
00727                                                                         $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
00728                                                                 }
00729                                                                 if (is_array($recArr[$v_b]))    {
00730                                                                         $temp[$c]=$recArr[$v_b];
00731                                                                         if ($this->conf['special.'][$v_b.'.']['target'])        {
00732                                                                                 $temp[$c]['target']=$this->conf['special.'][$v_b.'.']['target'];
00733                                                                         }
00734                                                                         if (is_array($this->conf['special.'][$v_b.'.']['fields.']))     {
00735                                                                                 reset($this->conf['special.'][$v_b.'.']['fields.']);
00736                                                                                 while(list($fk,$val)=each($this->conf['special.'][$v_b.'.']['fields.']))        {
00737                                                                                         $temp[$c][$fk]=$val;
00738                                                                                 }
00739                                                                         }
00740                                                                         $c++;
00741                                                                 }
00742                                                         }
00743                                                 }
00744                                         break;
00745                                 }
00746                         } elseif (is_array($this->alternativeMenuTempArray))    {       // Setting $temp array if not level 1.
00747                                 $temp = $this->alternativeMenuTempArray;
00748                         } elseif ($this->mconf['sectionIndex']) {
00749                                 if ($GLOBALS['TSFE']->sys_language_uid && count($this->sys_page->getPageOverlay($this->id)))    {
00750                                         $sys_language_uid = intval($GLOBALS['TSFE']->sys_language_uid);
00751                                 } else $sys_language_uid=0;
00752 
00753                                 $selectSetup = Array(
00754                                         'pidInList'=>$this->id,
00755                                         'orderBy'=>$altSortField,
00756                                         'where' => 'colPos=0 AND sys_language_uid='.$sys_language_uid,
00757                                         'andWhere' => 'sectionIndex!=0'
00758                                         );
00759                                 switch($this->mconf['sectionIndex.']['type'])   {
00760                                         case 'all':
00761                                                 unset($selectSetup['andWhere']);
00762                                         break;
00763                                         case 'header':
00764                                                 $selectSetup['andWhere']='header_layout!=100 AND header!=""';
00765                                         break;
00766                                 }
00767                                 $basePageRow=$this->sys_page->getPage($this->id);
00768                                 if (is_array($basePageRow))     {
00769                                         $res = $GLOBALS['TSFE']->cObj->exec_getQuery('tt_content',      $selectSetup);
00770                                         while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {
00771                                                 $GLOBALS['TSFE']->sys_page->versionOL('tt_content',$row);
00772 
00773                                                 if (is_array($row))     {
00774                                                         $temp[$row['uid']]=$basePageRow;
00775                                                         $temp[$row['uid']]['title']=$row['header'];
00776                                                         $temp[$row['uid']]['nav_title']=$row['header'];
00777                                                         $temp[$row['uid']]['subtitle']=$row['subheader'];
00778                                                         $temp[$row['uid']]['starttime']=$row['starttime'];
00779                                                         $temp[$row['uid']]['endtime']=$row['endtime'];
00780                                                         $temp[$row['uid']]['fe_group']=$row['fe_group'];
00781                                                         $temp[$row['uid']]['media']=$row['media'];
00782 
00783                                                         $temp[$row['uid']]['header_layout']=$row['header_layout'];
00784                                                         $temp[$row['uid']]['bodytext']=$row['bodytext'];
00785                                                         $temp[$row['uid']]['image']=$row['image'];
00786 
00787                                                         $temp[$row['uid']]['sectionIndex_uid']=$row['uid'];
00788                                                 }
00789                                         }
00790                                 }
00791                         } else {        // Default:
00792                                 $temp = $this->sys_page->getMenu($this->id,'*',$altSortField);          // gets the menu
00793                         }
00794 
00795                         $c=0;
00796                         $c_b=0;
00797                         $minItems = intval($this->mconf['minItems'] ? $this->mconf['minItems'] : $this->conf['minItems']);
00798                         $maxItems = intval($this->mconf['maxItems'] ? $this->mconf['maxItems'] : $this->conf['maxItems']);
00799                         $begin = tslib_cObj::calc($this->mconf['begin'] ? $this->mconf['begin'] : $this->conf['begin']);
00800 
00801                         $banUidArray = $this->getBannedUids();
00802 
00803                                 // Fill in the menuArr with elements that should go into the menu:
00804                         $this->menuArr = Array();
00805                         foreach($temp as $data) {
00806                                 $spacer = (t3lib_div::inList($this->spacerIDList,$data['doktype']) || !strcmp($data['ITEM_STATE'],'SPC')) ? 1 : 0;              // if item is a spacer, $spacer is set
00807                                 if ($this->filterMenuPages($data, $banUidArray, $spacer))       {
00808                                         $c_b++;
00809                                         if ($begin<=$c_b)       {               // If the beginning item has been reached.
00810                                                 $this->menuArr[$c] = $data;
00811                                                 $this->menuArr[$c]['isSpacer'] = $spacer;
00812                                                 $c++;
00813                                                 if ($maxItems && $c>=$maxItems) {
00814                                                         break;
00815                                                 }
00816                                         }
00817                                 }
00818                         }
00819 
00820                                 // Fill in fake items, if min-items is set.
00821                         if ($minItems)  {
00822                                 while($c<$minItems)     {
00823                                         $this->menuArr[$c] = Array(
00824                                                 'title' => '...',
00825                                                 'uid' => $GLOBALS['TSFE']->id
00826                                         );
00827                                         $c++;
00828                                 }
00829                         }
00830                                 // Setting number of menu items
00831                         $GLOBALS['TSFE']->register['count_menuItems'] = count($this->menuArr);
00832                                 //      Passing the menuArr through a user defined function:
00833                         if ($this->mconf['itemArrayProcFunc'])  {
00834                                 if (!is_array($this->parentMenuArr)) {$this->parentMenuArr=array();}
00835                                 $this->menuArr = $this->userProcess('itemArrayProcFunc',$this->menuArr);
00836                         }
00837                         $this->hash = md5(serialize($this->menuArr).serialize($this->mconf).serialize($this->tmpl->rootLine).serialize($this->MP_array));
00838 
00839                         $serData = $this->sys_page->getHash($this->hash, 60*60*24);
00840                         if (!$serData)  {
00841                                 $this->generate();
00842                                 $this->sys_page->storeHash($this->hash, serialize($this->result),'MENUDATA');
00843                         } else {
00844                                 $this->result=unserialize($serData);
00845                         }
00846 
00847                                 // End showAccessRestrictedPages
00848                         if ($this->mconf['showAccessRestrictedPages'])  {
00849                                         // RESTORING where_groupAccess
00850                                 $this->sys_page->where_groupAccess = $SAVED_where_groupAccess;
00851                         }
00852                 }
00853         }
00854 
00865         function includeMakeMenu($conf,$altSortField)   {
00866                 $incFile = $GLOBALS['TSFE']->tmpl->getFileName($conf['file']);
00867                 if ($incFile && $GLOBALS['TSFE']->checkFileInclude($incFile))   {
00868                         include($incFile);
00869                 }
00870                 return is_array($menuItemsArray) ? $menuItemsArray : array();
00871         }
00872 
00881         function filterMenuPages(&$data,$banUidArray,$spacer)   {
00882 
00883                 if ($data['_SAFE'])     return TRUE;
00884 
00885                 $uid = $data['uid'];
00886                 if ($this->mconf['SPC'] || !$spacer)    {       // If the spacer-function is not enabled, spacers will not enter the $menuArr
00887                         if (!t3lib_div::inList($this->doktypeExcludeList,$data['doktype']))     {               // Page may not be 'not_in_menu' or 'Backend User Section'
00888                                 if (!$data['nav_hide'] || $this->conf['includeNotInMenu'])      {       // Not hidden in navigation
00889                                         if (!t3lib_div::inArray($banUidArray,$uid))     {       // not in banned uid's
00890 
00891                                                         // Checks if the default language version can be shown:
00892                                                         // Block page is set, if l18n_cfg allows plus: 1) Either default language or 2) another language but NO overlay record set for page!
00893                                                 $blockPage = $data['l18n_cfg']&1 && (!$GLOBALS['TSFE']->sys_language_uid || ($GLOBALS['TSFE']->sys_language_uid && !$data['_PAGES_OVERLAY']));
00894                                                 if (!$blockPage)        {
00895 
00896                                                                 // Checking if a page should be shown in the menu depending on whether a translation exists:
00897                                                         $tok = TRUE;
00898                                                         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:
00899                                                                 if (!$data['_PAGES_OVERLAY'])   {
00900                                                                         $tok = FALSE;
00901                                                                 }
00902                                                         }
00903 
00904                                                                 // Continue if token is true:
00905                                                         if ($tok)       {
00906 
00907                                                                         // Checking if "&L" should be modified so links to non-accessible pages will not happen.
00908                                                                 if ($this->conf['protectLvar']) {
00909                                                                         $languageUid = intval($GLOBALS['TSFE']->config['config']['sys_language_uid']);
00910                                                                         if ($languageUid && ($this->conf['protectLvar']=='all' || t3lib_div::hideIfNotTranslated($data['l18n_cfg'])))   {
00911                                                                                 $olRec = $GLOBALS['TSFE']->sys_page->getPageOverlay($data['uid'], $languageUid);
00912                                                                                 if (!count($olRec))     {
00913                                                                                                 // 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"
00914                                                                                         $data['_ADD_GETVARS'].= '&L=0';
00915                                                                                 }
00916                                                                         }
00917                                                                 }
00918 
00919                                                                 return TRUE;
00920                                                         }
00921                                                 }
00922                                         }
00923                                 }
00924                         }
00925                 }
00926         }
00927 
00937         function procesItemStates($splitCount)  {
00938 
00939                         // Prepare normal settings
00940                 if (!is_array($this->mconf['NO.']) && $this->mconf['NO'])       $this->mconf['NO.']=array();    // Setting a blank array if NO=1 and there are no properties.
00941                 $NOconf = $this->tmpl->splitConfArray($this->mconf['NO.'],$splitCount);
00942 
00943                         // Prepare rollOver settings, overriding normal settings
00944                 $ROconf=array();
00945                 if ($this->mconf['RO']) {
00946                         $ROconf = $this->tmpl->splitConfArray($this->mconf['RO.'],$splitCount);
00947                 }
00948 
00949                         // Prepare IFSUB settings, overriding normal settings
00950                         // IFSUB is true if there exist submenu items to the current item
00951                 if ($this->mconf['IFSUB'])      {
00952                         $IFSUBinit = 0; // Flag: If $IFSUB is generated
00953                         reset($NOconf);
00954                         while (list($key,$val)=each($NOconf))   {
00955                                 if ($this->isItemState('IFSUB',$key))   {
00956                                         if (!$IFSUBinit)        {       // if this is the first IFSUB element, we must generate IFSUB.
00957                                                 $IFSUBconf = $this->tmpl->splitConfArray($this->mconf['IFSUB.'],$splitCount);
00958                                                 if ($this->mconf['IFSUBRO'])    {
00959                                                         $IFSUBROconf = $this->tmpl->splitConfArray($this->mconf['IFSUBRO.'],$splitCount);
00960                                                 }
00961                                                 $IFSUBinit = 1;
00962                                         }
00963                                         $NOconf[$key] = $IFSUBconf[$key];               // Substitute normal with ifsub
00964                                         if ($ROconf)    {       // If rollOver on normal, we must apply a state for rollOver on the active
00965                                                 $ROconf[$key] = $IFSUBROconf[$key] ? $IFSUBROconf[$key] : $IFSUBconf[$key];             // If RollOver on active then apply this
00966                                         }
00967                                 }
00968                         }
00969                 }
00970                         // Prepare active settings, overriding normal settings
00971                 if ($this->mconf['ACT'])        {
00972                         $ACTinit = 0;   // Flag: If $ACT is generated
00973                         reset($NOconf);
00974                         while (list($key,$val)=each($NOconf))   {       // Find active
00975                                 if ($this->isItemState('ACT',$key))     {
00976                                         if (!$ACTinit)  {       // if this is the first 'active', we must generate ACT.
00977                                                 $ACTconf = $this->tmpl->splitConfArray($this->mconf['ACT.'],$splitCount);
00978                                                         // Prepare active rollOver settings, overriding normal active settings
00979                                                 if ($this->mconf['ACTRO'])      {
00980                                                         $ACTROconf = $this->tmpl->splitConfArray($this->mconf['ACTRO.'],$splitCount);
00981                                                 }