|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2011 Kasper Skårhøj (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 ***************************************************************/ 00027 /** 00028 * Generating navigation / menus from TypoScript 00029 * 00030 * This file contains five classes, four of which are extensions to the main class, tslib_menu. 00031 * The main class, tslib_menu, is also extended by other external PHP scripts such as the GMENU_LAYERS and GMENU_FOLDOUT scripts which creates pop-up menus. 00032 * Notice that extension classes (like "tslib_tmenu") must have their suffix (here "tmenu") listed in $this->tmpl->menuclasses - otherwise they cannot be instantiated. 00033 * 00034 * $Id: class.tslib_menu.php 10382 2011-02-04 15:50:08Z francois $ 00035 * Revised for TYPO3 3.6 June/2003 by Kasper Skårhøj 00036 * XHTML compliant 00037 * 00038 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00039 */ 00040 /** 00041 * [CLASS/FUNCTION INDEX of SCRIPT] 00042 * 00043 * 00044 * 00045 * 146: class tslib_menu 00046 * 211: function start(&$tmpl,&$sys_page,$id,$conf,$menuNumber,$objSuffix='') 00047 * 357: function makeMenu() 00048 * 909: function includeMakeMenu($conf,$altSortField) 00049 * 925: function filterMenuPages(&$data,$banUidArray,$spacer) 00050 * 981: function procesItemStates($splitCount) 00051 * 1191: function link($key,$altTarget='',$typeOverride='') 00052 * 1263: function changeLinksForAccessRestrictedPages(&$LD, $page, $mainTarget, $typeOverride) 00053 * 1284: function subMenu($uid, $objSuffix='') 00054 * 1330: function isNext($uid, $MPvar='') 00055 * 1351: function isActive($uid, $MPvar='') 00056 * 1372: function isCurrent($uid, $MPvar='') 00057 * 1387: function isSubMenu($uid) 00058 * 1412: function isItemState($kind,$key) 00059 * 1452: function accessKey($title) 00060 * 1480: function userProcess($mConfKey,$passVar) 00061 * 1495: function setATagParts() 00062 * 1508: function getPageTitle($title,$nav_title) 00063 * 1520: function getMPvar($key) 00064 * 1535: function getDoktypeExcludeWhere() 00065 * 1545: function getBannedUids() 00066 * 1568: function menuTypoLink($page, $oTarget, $no_cache, $script, $overrideArray = '', $addParams = '', $typeOverride = '') 00067 * 00068 * 00069 * 1618: class tslib_tmenu extends tslib_menu 00070 * 1627: function generate() 00071 * 1643: function writeMenu() 00072 * 1796: function getBeforeAfter($pref) 00073 * 1826: function addJScolorShiftFunction() 00074 * 1848: function extProc_init() 00075 * 1859: function extProc_RO($key) 00076 * 1870: function extProc_beforeLinking($key) 00077 * 1882: function extProc_afterLinking($key) 00078 * 1900: function extProc_beforeAllWrap($item,$key) 00079 * 1911: function extProc_finish() 00080 * 00081 * 00082 * 1951: class tslib_gmenu extends tslib_menu 00083 * 1960: function generate() 00084 * 1998: function makeGifs($conf, $resKey) 00085 * 2196: function findLargestDims($conf,$items,$Hobjs,$Wobjs,$minDim,$maxDim) 00086 * 2268: function writeMenu() 00087 * 2392: function extProc_init() 00088 * 2403: function extProc_RO($key) 00089 * 2414: function extProc_beforeLinking($key) 00090 * 2427: function extProc_afterLinking($key) 00091 * 2444: function extProc_beforeAllWrap($item,$key) 00092 * 2455: function extProc_finish() 00093 * 00094 * 00095 * 2493: class tslib_imgmenu extends tslib_menu 00096 * 2502: function generate() 00097 * 2520: function makeImageMap($conf) 00098 * 2706: function writeMenu() 00099 * 00100 * 00101 * 2749: class tslib_jsmenu extends tslib_menu 00102 * 2756: function generate() 00103 * 2764: function writeMenu() 00104 * 2825: function generate_level($levels,$count,$pid,$menuItemArray='',$MP_array=array()) 00105 * 00106 * TOTAL FUNCTIONS: 47 00107 * (This index is automatically created/updated by the extension "extdeveval") 00108 * 00109 */ 00110 00111 00112 00113 00114 00115 00116 00117 00118 00119 00120 00121 00122 00123 00124 00125 00126 00127 00128 /** 00129 * Base class. The HMENU content object uses this (or more precisely one of the extension classes). 00130 * Amoung others the class generates an array of menuitems. Thereafter functions from the subclasses are called. 00131 * The class is ALWAYS used through extension classes (like tslib_gmenu or tslib_tmenu which are classics) and 00132 * 00133 * Example of usage (from tslib_cObj): 00134 * 00135 * $menu = t3lib_div::makeInstance('tslib_'.$cls); 00136 * $menu->parent_cObj = $this; 00137 * $menu->start($GLOBALS['TSFE']->tmpl,$GLOBALS['TSFE']->sys_page,'',$conf,1); 00138 * $menu->makeMenu(); 00139 * $content.=$menu->writeMenu(); 00140 * 00141 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00142 * @package TYPO3 00143 * @subpackage tslib 00144 * @see tslib_cObj::HMENU() 00145 */ 00146 class tslib_menu { 00147 var $menuNumber = 1; // tells you which menu-number this is. This is important when getting data from the setup 00148 var $entryLevel = 0; // 0 = rootFolder 00149 var $spacerIDList = '199'; // The doktype-number that defines a spacer 00150 // @TODO: RFC #7370: doktype 2&5 are deprecated since TYPO3 4.2-beta1 00151 var $doktypeExcludeList = '5,6'; // doktypes that define which should not be included in a menu 00152 var $alwaysActivePIDlist=array(); 00153 var $imgNamePrefix = 'img'; 00154 var $imgNameNotRandom=0; 00155 var $debug = 0; 00156 00157 /** 00158 * Loaded with the parent cObj-object when a new HMENU is made 00159 * 00160 * @var tslib_cObj 00161 */ 00162 var $parent_cObj; 00163 var $GMENU_fixKey='gmenu'; 00164 var $MP_array=array(); // accumulation of mount point data 00165 00166 // internal 00167 var $conf = Array(); // HMENU configuration 00168 var $mconf = Array(); // xMENU configuration (TMENU, GMENU etc) 00169 00170 /** 00171 * template-object 00172 * 00173 * @var t3lib_TStemplate 00174 */ 00175 var $tmpl; 00176 00177 /** 00178 * sys_page-object, pagefunctions 00179 * 00180 * @var t3lib_pageSelect 00181 */ 00182 var $sys_page; 00183 var $id; // The base page-id of the menu. 00184 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. 00185 var $menuArr; // The array of menuItems which is built 00186 var $hash; 00187 var $result = Array(); 00188 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) 00189 var $INPfixMD5; 00190 var $I; 00191 var $WMresult; 00192 var $WMfreezePrefix; 00193 var $WMmenuItems; 00194 var $WMsubmenuObjSuffixes; 00195 var $WMextraScript; 00196 var $alternativeMenuTempArray=''; // Can be set to contain menu item arrays for sub-levels. 00197 var $nameAttribute = 'name'; // Will be 'id' in XHTML-mode 00198 00199 /** 00200 * The initialization of the object. This just sets some internal variables. 00201 * 00202 * @param object The $GLOBALS['TSFE']->tmpl object 00203 * @param object The $GLOBALS['TSFE']->sys_page object 00204 * @param integer A starting point page id. This should probably be blank since the 'entryLevel' value will be used then. 00205 * @param array The TypoScript configuration for the HMENU cObject 00206 * @param integer Menu number; 1,2,3. Should probably be '1' 00207 * @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") 00208 * @return boolean Returns true on success 00209 * @see tslib_cObj::HMENU() 00210 */ 00211 function start(&$tmpl,&$sys_page,$id,$conf,$menuNumber,$objSuffix='') { 00212 00213 // Init: 00214 $this->conf = $conf; 00215 $this->menuNumber = $menuNumber; 00216 $this->mconf = $conf[$this->menuNumber.$objSuffix.'.']; 00217 $this->debug=$GLOBALS['TSFE']->debug; 00218 00219 // In XHTML there is no "name" attribute anymore 00220 switch ($GLOBALS['TSFE']->xhtmlDoctype) { 00221 case 'xhtml_strict': 00222 case 'xhtml_11': 00223 case 'xhtml_2': 00224 case 'html5': 00225 $this->nameAttribute = 'id'; 00226 break; 00227 default: 00228 $this->nameAttribute = 'name'; 00229 break; 00230 } 00231 00232 // Sets the internal vars. $tmpl MUST be the template-object. $sys_page MUST be the sys_page object 00233 if ($this->conf[$this->menuNumber.$objSuffix] && is_object($tmpl) && is_object($sys_page)) { 00234 $this->tmpl = $tmpl; 00235 $this->sys_page = $sys_page; 00236 00237 // alwaysActivePIDlist initialized: 00238 if (trim($this->conf['alwaysActivePIDlist']) || isset($this->conf['alwaysActivePIDlist.'])) { 00239 if (isset($this->conf['alwaysActivePIDlist.'])) { 00240 $this->conf['alwaysActivePIDlist'] = $this->parent_cObj->stdWrap($this->conf['alwaysActivePIDlist'], $this->conf['alwaysActivePIDlist.']); 00241 } 00242 $this->alwaysActivePIDlist = t3lib_div::intExplode(',', $this->conf['alwaysActivePIDlist']); 00243 } 00244 00245 // 'not in menu' doktypes 00246 if($this->conf['excludeDoktypes']) { 00247 $this->doktypeExcludeList = $GLOBALS['TYPO3_DB']->cleanIntList($this->conf['excludeDoktypes']); 00248 } 00249 if($this->conf['includeNotInMenu']) { 00250 $exclDoktypeArr = t3lib_div::trimExplode(',',$this->doktypeExcludeList,1); 00251 // @TODO: RFC #7370: doktype 2&5 are deprecated since TYPO3 4.2-beta1 00252 $exclDoktypeArr = t3lib_div::removeArrayEntryByValue($exclDoktypeArr,'5'); 00253 $this->doktypeExcludeList = implode(',',$exclDoktypeArr); 00254 } 00255 // EntryLevel 00256 $this->entryLevel = tslib_cObj::getKey ( 00257 isset($conf['entryLevel.']) 00258 ? $this->parent_cObj->stdWrap($conf['entryLevel'], $conf['entryLevel.']) 00259 : $conf['entryLevel'], 00260 $this->tmpl->rootLine 00261 ); 00262 // Set parent page: If $id not stated with start() then the base-id will be found from rootLine[$this->entryLevel] 00263 if ($id) { // Called as the next level in a menu. It is assumed that $this->MP_array is set from parent menu. 00264 $this->id = intval($id); 00265 } else { // This is a BRAND NEW menu, first level. So we take ID from rootline and also find MP_array (mount points) 00266 $this->id = intval($this->tmpl->rootLine[$this->entryLevel]['uid']); 00267 00268 // Traverse rootline to build MP_array of pages BEFORE the entryLevel 00269 // (MP var for ->id is picked up in the next part of the code...) 00270 foreach($this->tmpl->rootLine as $entryLevel => $levelRec) { 00271 // For overlaid mount points, set the variable right now: 00272 if ($levelRec['_MP_PARAM'] && $levelRec['_MOUNT_OL']) { 00273 $this->MP_array[] = $levelRec['_MP_PARAM']; 00274 } 00275 // Break when entry level is reached: 00276 if ($entryLevel>=$this->entryLevel) break; 00277 00278 // For normal mount points, set the variable for next level. 00279 if ($levelRec['_MP_PARAM'] && !$levelRec['_MOUNT_OL']) { 00280 $this->MP_array[] = $levelRec['_MP_PARAM']; 00281 } 00282 } 00283 } 00284 00285 // Return false if no page ID was set (thus no menu of subpages can be made). 00286 if ($this->id<=0) { 00287 return FALSE; 00288 } 00289 00290 // Check if page is a mount point, and if so set id and MP_array 00291 // (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...) 00292 $mount_info = $this->sys_page->getMountPointInfo($this->id); 00293 if (is_array($mount_info)) { 00294 $this->MP_array[] = $mount_info['MPvar']; 00295 $this->id = $mount_info['mount_pid']; 00296 } 00297 00298 // Gather list of page uids in root line (for "isActive" evaluation). Also adds the MP params in the path so Mount Points are respected. 00299 // (List is specific for this rootline, so it may be supplied from parent menus for speed...) 00300 if (!is_array($this->rL_uidRegister)) { 00301 $rl_MParray = array(); 00302 foreach($this->tmpl->rootLine as $v_rl) { 00303 // For overlaid mount points, set the variable right now: 00304 if ($v_rl['_MP_PARAM'] && $v_rl['_MOUNT_OL']) { 00305 $rl_MParray[] = $v_rl['_MP_PARAM']; 00306 } 00307 00308 // Add to register: 00309 $this->rL_uidRegister[] = 'ITEM:'.$v_rl['uid'].(count($rl_MParray) ? ':'.implode(',',$rl_MParray) : ''); 00310 00311 // For normal mount points, set the variable for next level. 00312 if ($v_rl['_MP_PARAM'] && !$v_rl['_MOUNT_OL']) { 00313 $rl_MParray[] = $v_rl['_MP_PARAM']; 00314 } 00315 } 00316 } 00317 00318 // Set $directoryLevel so the following evalution of the nextActive will not return 00319 // an invalid value if .special=directory was set 00320 $directoryLevel = 0; 00321 if ($this->conf['special'] == 'directory') { 00322 $value = isset($this->conf['special.']['value.']) 00323 ? $this->parent_cObj->stdWrap($this->conf['special.']['value'], $this->conf['special.']['value.']) 00324 : $this->conf['special.']['value']; 00325 if ($value=='') { 00326 $value=$GLOBALS['TSFE']->page['uid']; 00327 } 00328 $directoryLevel = intval($GLOBALS['TSFE']->tmpl->getRootlineLevel($value)); 00329 } 00330 00331 // 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 00332 // Notice: The automatic expansion of a menu is designed to work only when no "special" modes (except "directory") are used. 00333 $startLevel = $directoryLevel ? $directoryLevel : $this->entryLevel; 00334 $currentLevel = $startLevel + $this->menuNumber; 00335 if (is_array($this->tmpl->rootLine[$currentLevel])) { 00336 $nextMParray = $this->MP_array; 00337 if (!count($nextMParray) && !$this->tmpl->rootLine[$currentLevel]['_MOUNT_OL'] && $currentLevel > 0) { 00338 // Make sure to slide-down any mount point information (_MP_PARAM) to children records in the rootline 00339 // otherwise automatic expansion will not work 00340 $parentRecord = $this->tmpl->rootLine[$currentLevel - 1]; 00341 if (isset($parentRecord['_MP_PARAM'])) { 00342 $nextMParray[] = $parentRecord['_MP_PARAM']; 00343 } 00344 } 00345 00346 if ($this->tmpl->rootLine[$currentLevel]['_MOUNT_OL']) { // In overlay mode, add next level MPvars as well: 00347 $nextMParray[] = $this->tmpl->rootLine[$currentLevel]['_MP_PARAM']; 00348 } 00349 $this->nextActive = $this->tmpl->rootLine[$currentLevel]['uid'] . (count($nextMParray) ? ':' . implode(',', $nextMParray) : ''); 00350 } else { 00351 $this->nextActive = ''; 00352 } 00353 00354 // imgNamePrefix 00355 if ($this->mconf['imgNamePrefix']) { 00356 $this->imgNamePrefix=$this->mconf['imgNamePrefix']; 00357 } 00358 $this->imgNameNotRandom = $this->mconf['imgNameNotRandom']; 00359 00360 $retVal = TRUE; 00361 } else { 00362 $GLOBALS['TT']->setTSlogMessage('ERROR in menu',3); 00363 $retVal = FALSE; 00364 } 00365 return $retVal; 00366 } 00367 00368 /** 00369 * Creates the menu in the internal variables, ready for output. 00370 * Basically this will read the page records needed and fill in the internal $this->menuArr 00371 * Based on a hash of this array and some other variables the $this->result variable will be loaded either from cache OR by calling the generate() method of the class to create the menu for real. 00372 * 00373 * @return void 00374 */ 00375 function makeMenu() { 00376 if ($this->id) { 00377 00378 // Initializing showAccessRestrictedPages 00379 if ($this->mconf['showAccessRestrictedPages']) { 00380 // SAVING where_groupAccess 00381 $SAVED_where_groupAccess = $this->sys_page->where_groupAccess; 00382 $this->sys_page->where_groupAccess = ''; // Temporarily removing fe_group checking! 00383 } 00384 00385 // Begin production of menu: 00386 $temp = array(); 00387 $altSortFieldValue = trim($this->mconf['alternativeSortingField']); 00388 $altSortField = $altSortFieldValue ? $altSortFieldValue : 'sorting'; 00389 if ($this->menuNumber==1 && $this->conf['special']) { // ... only for the FIRST level of a HMENU 00390 $value = isset($this->conf['special.']['value.']) 00391 ? $this->parent_cObj->stdWrap($this->conf['special.']['value'], $this->conf['special.']['value.']) 00392 : $this->conf['special.']['value']; 00393 00394 switch($this->conf['special']) { 00395 case 'userdefined': 00396 $temp = $this->includeMakeMenu($this->conf['special.'],$altSortField); 00397 break; 00398 case 'userfunction': 00399 $temp = $this->parent_cObj->callUserFunction( 00400 $this->conf['special.']['userFunc'], 00401 array_merge($this->conf['special.'],array('_altSortField'=>$altSortField)), 00402 '' 00403 ); 00404 if (!is_array($temp)) $temp=array(); 00405 break; 00406 case 'language': 00407 $temp = array(); 00408 00409 // Getting current page record NOT overlaid by any translation: 00410 $currentPageWithNoOverlay = $this->sys_page->getRawRecord('pages',$GLOBALS['TSFE']->page['uid']); 00411 00412 // Traverse languages set up: 00413 $languageItems = t3lib_div::intExplode(',',$value); 00414 foreach($languageItems as $sUid) { 00415 // Find overlay record: 00416 if ($sUid) { 00417 $lRecs = $this->sys_page->getPageOverlay($GLOBALS['TSFE']->page['uid'],$sUid); 00418 } else $lRecs=array(); 00419 // Checking if the "disabled" state should be set. 00420 if ( 00421 (t3lib_div::hideIfNotTranslated($GLOBALS['TSFE']->page['l18n_cfg']) && $sUid && !count($lRecs)) // Blocking for all translations? 00422 || ($GLOBALS['TSFE']->page['l18n_cfg']&1 && (!$sUid || !count($lRecs))) // Blocking default translation? 00423 || (!$this->conf['special.']['normalWhenNoLanguage'] && $sUid && !count($lRecs)) 00424 ) { 00425 $iState = $GLOBALS['TSFE']->sys_language_uid==$sUid ? 'USERDEF2' : 'USERDEF1'; 00426 } else { 00427 $iState = $GLOBALS['TSFE']->sys_language_uid==$sUid ? 'ACT' : 'NO'; 00428 } 00429 00430 if ($this->conf['addQueryString']) { 00431 $getVars = $this->parent_cObj->getQueryArguments($this->conf['addQueryString.'],array('L'=>$sUid),true); 00432 } else { 00433 $getVars = '&L='.$sUid; 00434 } 00435 00436 // Adding menu item: 00437 $temp[] = array_merge( 00438 array_merge($currentPageWithNoOverlay, $lRecs), 00439 array( 00440 'ITEM_STATE' => $iState, 00441 '_ADD_GETVARS' => $getVars, 00442 '_SAFE' => TRUE 00443 ) 00444 ); 00445 } 00446 break; 00447 case 'directory': 00448 if ($value=='') { 00449 $value=$GLOBALS['TSFE']->page['uid']; 00450 } 00451 $items=t3lib_div::intExplode(',',$value); 00452 00453 foreach($items as $id) { 00454 $MP = $this->tmpl->getFromMPmap($id); 00455 00456 // Checking if a page is a mount page and if so, change the ID and set the MP var properly. 00457 $mount_info = $this->sys_page->getMountPointInfo($id); 00458 if (is_array($mount_info)) { 00459 if ($mount_info['overlay']) { // Overlays should already have their full MPvars calculated: 00460 $MP = $this->tmpl->getFromMPmap($mount_info['mount_pid']); 00461 $MP = $MP ? $MP : $mount_info['MPvar']; 00462 } else { 00463 $MP = ($MP ? $MP.',' : '').$mount_info['MPvar']; 00464 } 00465 $id = $mount_info['mount_pid']; 00466 } 00467 00468 // Get sub-pages: 00469 $res = $this->parent_cObj->exec_getQuery('pages',Array('pidInList'=>$id,'orderBy'=>$altSortField)); 00470 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00471 $GLOBALS['TSFE']->sys_page->versionOL('pages',$row); 00472 00473 if (is_array($row)) { 00474 // Keep mount point? 00475 $mount_info = $this->sys_page->getMountPointInfo($row['uid'], $row); 00476 if (is_array($mount_info) && $mount_info['overlay']) { // There is a valid mount point. 00477 $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! 00478 if (count($mp_row)) { 00479 $row = $mp_row; 00480 $row['_MP_PARAM'] = $mount_info['MPvar']; 00481 } 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! 00482 } 00483 00484 // Add external MP params, then the row: 00485 if (is_array($row)) { 00486 if ($MP) $row['_MP_PARAM'] = $MP.($row['_MP_PARAM'] ? ','.$row['_MP_PARAM'] : ''); 00487 $temp[$row['uid']] = $this->sys_page->getPageOverlay($row); 00488 } 00489 } 00490 } 00491 } 00492 break; 00493 case 'list': 00494 if ($value=='') { 00495 $value=$this->id; 00496 } 00497 $loadDB = t3lib_div::makeInstance('FE_loadDBGroup'); 00498 $loadDB->start($value, 'pages'); 00499 $loadDB->additionalWhere['pages']=tslib_cObj::enableFields('pages'); 00500 $loadDB->getFromDB(); 00501 00502 foreach($loadDB->itemArray as $val) { 00503 $MP = $this->tmpl->getFromMPmap($val['id']); 00504 00505 // Keep mount point? 00506 $mount_info = $this->sys_page->getMountPointInfo($val['id']); 00507 if (is_array($mount_info) && $mount_info['overlay']) { // There is a valid mount point. 00508 $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! 00509 if (count($mp_row)) { 00510 $row = $mp_row; 00511 $row['_MP_PARAM'] = $mount_info['MPvar']; 00512 00513 if ($mount_info['overlay']) { // Overlays should already have their full MPvars calculated: 00514 $MP = $this->tmpl->getFromMPmap($mount_info['mount_pid']); 00515 if ($MP) unset($row['_MP_PARAM']); 00516 } 00517 } 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! 00518 } else { 00519 $row = $loadDB->results['pages'][$val['id']]; 00520 } 00521 00522 //Add versioning overlay for current page (to respect workspaces) 00523 if (is_array($row)) { 00524 $this->sys_page->versionOL('pages', $row, true); 00525 } 00526 00527 // Add external MP params, then the row: 00528 if (is_array($row)) { 00529 if ($MP) $row['_MP_PARAM'] = $MP.($row['_MP_PARAM'] ? ','.$row['_MP_PARAM'] : ''); 00530 $temp[] = $this->sys_page->getPageOverlay($row); 00531 } 00532 } 00533 break; 00534 case 'updated': 00535 if ($value=='') { 00536 $value=$GLOBALS['TSFE']->page['uid']; 00537 } 00538 $items=t3lib_div::intExplode(',',$value); 00539 if (t3lib_div::testInt($this->conf['special.']['depth'])) { 00540 $depth = t3lib_div::intInRange($this->conf['special.']['depth'],1,20); // Tree depth 00541 } else { 00542 $depth=20; 00543 } 00544 $limit = t3lib_div::intInRange($this->conf['special.']['limit'],0,100); // max number of items 00545 $maxAge = intval(tslib_cObj::calc($this->conf['special.']['maxAge'])); 00546 if (!$limit) $limit=10; 00547 $mode = $this->conf['special.']['mode']; // *'auto', 'manual', 'tstamp' 00548 // Get id's 00549 $id_list_arr = Array(); 00550 00551 foreach($items as $id) { 00552 $bA = t3lib_div::intInRange($this->conf['special.']['beginAtLevel'],0,100); 00553 $id_list_arr[] = tslib_cObj::getTreeList(-1*$id,$depth-1+$bA,$bA-1); 00554 } 00555 $id_list = implode(',',$id_list_arr); 00556 // Get sortField (mode) 00557 switch($mode) { 00558 case 'starttime': 00559 $sortField = 'starttime'; 00560 break; 00561 case 'lastUpdated': 00562 case 'manual': 00563 $sortField = 'lastUpdated'; 00564 break; 00565 case 'tstamp': 00566 $sortField = 'tstamp'; 00567 break; 00568 case 'crdate': 00569 $sortField = 'crdate'; 00570 break; 00571 default: 00572 $sortField = 'SYS_LASTCHANGED'; 00573 break; 00574 } 00575 // Get 00576 $extraWhere = ($this->conf['includeNotInMenu'] ? '' : ' AND pages.nav_hide=0').$this->getDoktypeExcludeWhere(); 00577 00578 if ($this->conf['special.']['excludeNoSearchPages']) { 00579 $extraWhere.= ' AND pages.no_search=0'; 00580 } 00581 if ($maxAge>0) { 00582 $extraWhere.=' AND '.$sortField.'>'.($GLOBALS['SIM_ACCESS_TIME']-$maxAge); 00583 } 00584 00585 $res = $this->parent_cObj->exec_getQuery('pages',Array('pidInList'=>'0', 'uidInList'=>$id_list, 'where'=>$sortField.'>=0'.$extraWhere, 'orderBy'=>($altSortFieldValue ? $altSortFieldValue : $sortField.' desc'),'max'=>$limit)); 00586 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00587 $GLOBALS['TSFE']->sys_page->versionOL('pages',$row); 00588 if (is_array($row)) { 00589 $temp[$row['uid']]=$this->sys_page->getPageOverlay($row); 00590 } 00591 } 00592 break; 00593 case 'keywords': 00594 list($value)=t3lib_div::intExplode(',',$value); 00595 if (!$value) { 00596 $value=$GLOBALS['TSFE']->page['uid']; 00597 } 00598 if ($this->conf['special.']['setKeywords'] || $this->conf['special.']['setKeywords.']) { 00599 $kw = isset($this->conf['special.']['setKeywords.']) 00600 ? $this->parent_cObj->stdWrap($this->conf['special.']['setKeywords'], $this->conf['special.']['setKeywords.']) 00601 : $this->conf['special.']['setKeywords']; 00602 } else { 00603 $value_rec=$this->sys_page->getPage($value); // The page record of the 'value'. 00604 00605 $kfieldSrc = $this->conf['special.']['keywordsField.']['sourceField'] ? $this->conf['special.']['keywordsField.']['sourceField'] : 'keywords'; 00606 $kw = trim(tslib_cObj::keywords($value_rec[$kfieldSrc])); // keywords. 00607 } 00608 00609 $mode = $this->conf['special.']['mode']; // *'auto', 'manual', 'tstamp' 00610 switch($mode) { 00611 case 'starttime': 00612 $sortField = 'starttime'; 00613 break; 00614 case 'lastUpdated': 00615 case 'manual': 00616 $sortField = 'lastUpdated'; 00617 break; 00618 case 'tstamp': 00619 $sortField = 'tstamp'; 00620 break; 00621 case 'crdate': 00622 $sortField = 'crdate'; 00623 break; 00624 default: 00625 $sortField = 'SYS_LASTCHANGED'; 00626 break; 00627 } 00628 00629 // depth, limit, extra where 00630 if (t3lib_div::testInt($this->conf['special.']['depth'])) { 00631 $depth = t3lib_div::intInRange($this->conf['special.']['depth'],0,20); // Tree depth 00632 } else { 00633 $depth=20; 00634 } 00635 $limit = t3lib_div::intInRange($this->conf['special.']['limit'],0,100); // max number of items 00636 $extraWhere = ' AND pages.uid!='.$value.($this->conf['includeNotInMenu'] ? '' : ' AND pages.nav_hide=0').$this->getDoktypeExcludeWhere(); 00637 if ($this->conf['special.']['excludeNoSearchPages']) { 00638 $extraWhere.= ' AND pages.no_search=0'; 00639 } 00640 // start point 00641 $eLevel = tslib_cObj::getKey( 00642 isset($this->conf['special.']['entryLevel.']) 00643 ? $this->parent_cObj->stdWrap($this->conf['special.']['entryLevel'], $this->conf['special.']['entryLevel.']) 00644 : $this->conf['special.']['entryLevel'], 00645 $this->tmpl->rootLine 00646 ); 00647 $startUid = intval($this->tmpl->rootLine[$eLevel]['uid']); 00648 00649 // which field is for keywords 00650 $kfield = 'keywords'; 00651 if ( $this->conf['special.']['keywordsField'] ) { 00652 list($kfield) = explode(' ',trim ($this->conf['special.']['keywordsField'])); 00653 } 00654 00655 // If there are keywords and the startuid is present. 00656 if ($kw && $startUid) { 00657 $bA = t3lib_div::intInRange($this->conf['special.']['beginAtLevel'],0,100); 00658 $id_list=tslib_cObj::getTreeList(-1*$startUid,$depth-1+$bA,$bA-1); 00659 00660 $kwArr = explode(',',$kw); 00661 foreach($kwArr as $word) { 00662 $word = trim($word); 00663 if ($word) { 00664 $keyWordsWhereArr[] = $kfield.' LIKE \'%'.$GLOBALS['TYPO3_DB']->quoteStr($word, 'pages').'%\''; 00665 } 00666 } 00667 $res = $this->parent_cObj->exec_getQuery('pages',Array('pidInList'=>'0', 'uidInList'=>$id_list, 'where'=>'('.implode(' OR ',$keyWordsWhereArr).')'.$extraWhere, 'orderBy'=>($altSortFieldValue ? $altSortFieldValue : $sortField.' desc'),'max'=>$limit)); 00668 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00669 $GLOBALS['TSFE']->sys_page->versionOL('pages',$row); 00670 if (is_array($row)) { 00671 $temp[$row['uid']]=$this->sys_page->getPageOverlay($row); 00672 } 00673 } 00674 } 00675 break; 00676 case 'rootline': 00677 $range = isset($this->conf['special.']['range.']) 00678 ? $this->parent_cObj->stdWrap($this->conf['special.']['range'], $this->conf['special.']['range.']) 00679 : $this->conf['special.']['range']; 00680 $begin_end = explode('|', $range); 00681 $begin_end[0] = intval($begin_end[0]); 00682 if (!t3lib_div::testInt($begin_end[1])) { 00683 $begin_end[1] = -1; 00684 } 00685 00686 $beginKey = tslib_cObj::getKey ($begin_end[0],$this->tmpl->rootLine); 00687 $endKey = tslib_cObj::getKey ($begin_end[1],$this->tmpl->rootLine); 00688 if ($endKey<$beginKey) {$endKey=$beginKey;} 00689 00690 $rl_MParray = array(); 00691 foreach($this->tmpl->rootLine as $k_rl => $v_rl) { 00692 // For overlaid mount points, set the variable right now: 00693 if ($v_rl['_MP_PARAM'] && $v_rl['_MOUNT_OL']) { 00694 $rl_MParray[] = $v_rl['_MP_PARAM']; 00695 } 00696 // Traverse rootline: 00697 if ($k_rl>=$beginKey && $k_rl<=$endKey) { 00698 $temp_key=$k_rl; 00699 $temp[$temp_key]=$this->sys_page->getPage($v_rl['uid']); 00700 if (count($temp[$temp_key])) { 00701 if (!$temp[$temp_key]['target']) { // If there are no specific target for the page, put the level specific target on. 00702 $temp[$temp_key]['target'] = $this->conf['special.']['targets.'][$k_rl]; 00703 $temp[$temp_key]['_MP_PARAM'] = implode(',',$rl_MParray); 00704 } 00705 } else unset($temp[$temp_key]); 00706 } 00707 // For normal mount points, set the variable for next level. 00708 if ($v_rl['_MP_PARAM'] && !$v_rl['_MOUNT_OL']) { 00709 $rl_MParray[] = $v_rl['_MP_PARAM']; 00710 } 00711 } 00712 // Reverse order of elements (e.g. "1,2,3,4" gets "4,3,2,1"): 00713 if (isset($this->conf['special.']['reverseOrder']) && $this->conf['special.']['reverseOrder']) { 00714 $temp = array_reverse($temp); 00715 $rl_MParray = array_reverse($rl_MParray); 00716 } 00717 break; 00718 case 'browse': 00719 list($value)=t3lib_div::intExplode(',',$value); 00720 if (!$value) { 00721 $value=$GLOBALS['TSFE']->page['uid']; 00722 } 00723 if ($value!=$this->tmpl->rootLine[0]['uid']) { // Will not work out of rootline 00724 $recArr=array(); 00725 $value_rec=$this->sys_page->getPage($value); // The page record of the 'value'. 00726 if ($value_rec['pid']) { // 'up' page cannot be outside rootline 00727 $recArr['up']=$this->sys_page->getPage($value_rec['pid']); // The page record of 'up'. 00728 } 00729 if ($recArr['up']['pid'] && $value_rec['pid']!=$this->tmpl->rootLine[0]['uid']) { // If the 'up' item was NOT level 0 in rootline... 00730 $recArr['index']=$this->sys_page->getPage($recArr['up']['pid']); // The page record of "index". 00731 } 00732 00733 // prev / next is found 00734 $prevnext_menu = $this->sys_page->getMenu($value_rec['pid'],'*',$altSortField); 00735 $lastKey=0; 00736 $nextActive=0; 00737 foreach ($prevnext_menu as $k_b => $v_b) { 00738 if ($nextActive) { 00739 $recArr['next']=$v_b; 00740 $nextActive=0; 00741 } 00742 if ($v_b['uid']==$value) { 00743 if ($lastKey) { 00744 $recArr['prev']=$prevnext_menu[$lastKey]; 00745 } 00746 $nextActive=1; 00747 } 00748 $lastKey=$k_b; 00749 } 00750 reset($prevnext_menu); 00751 $recArr['first']=pos($prevnext_menu); 00752 end($prevnext_menu); 00753 $recArr['last']=pos($prevnext_menu); 00754 00755 // prevsection / nextsection is found 00756 if (is_array($recArr['index'])) { // You can only do this, if there is a valid page two levels up! 00757 $prevnextsection_menu = $this->sys_page->getMenu($recArr['index']['uid'],'*',$altSortField); 00758 $lastKey=0; 00759 $nextActive=0; 00760 foreach ($prevnextsection_menu as $k_b => $v_b) { 00761 if ($nextActive) { 00762 $sectionRec_temp = $this->sys_page->getMenu($v_b['uid'],'*',$altSortField); 00763 if (count($sectionRec_temp)) { 00764 reset($sectionRec_temp); 00765 $recArr['nextsection']=pos($sectionRec_temp); 00766 end ($sectionRec_temp); 00767 $recArr['nextsection_last']=pos($sectionRec_temp); 00768 $nextActive=0; 00769 } 00770 } 00771 if ($v_b['uid']==$value_rec['pid']) { 00772 if ($lastKey) { 00773 $sectionRec_temp = $this->sys_page->getMenu($prevnextsection_menu[$lastKey]['uid'],'*',$altSortField); 00774 if (count($sectionRec_temp)) { 00775 reset($sectionRec_temp); 00776 $recArr['prevsection']=pos($sectionRec_temp); 00777 end ($sectionRec_temp); 00778 $recArr['prevsection_last']=pos($sectionRec_temp); 00779 } 00780 } 00781 $nextActive=1; 00782 } 00783 $lastKey=$k_b; 00784 } 00785 } 00786 if ($this->conf['special.']['items.']['prevnextToSection']) { 00787 if (!is_array($recArr['prev']) && is_array($recArr['prevsection_last'])) { 00788 $recArr['prev']=$recArr['prevsection_last']; 00789 } 00790 if (!is_array($recArr['next']) && is_array($recArr['nextsection'])) { 00791 $recArr['next']=$recArr['nextsection']; 00792 } 00793 } 00794 00795 $items = explode('|',$this->conf['special.']['items']); 00796 $c=0; 00797 foreach ($items as $k_b => $v_b) { 00798 $v_b=strtolower(trim($v_b)); 00799 if (intval($this->conf['special.'][$v_b.'.']['uid'])) { 00800 $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 00801 } 00802 if (is_array($recArr[$v_b])) { 00803 $temp[$c]=$recArr[$v_b]; 00804 if ($this->conf['special.'][$v_b.'.']['target']) { 00805 $temp[$c]['target']=$this->conf['special.'][$v_b.'.']['target']; 00806 } 00807 $tmpSpecialFields = $this->conf['special.'][$v_b.'.']['fields.']; 00808 if (is_array($tmpSpecialFields)) { 00809 foreach ($tmpSpecialFields as $fk => $val) { 00810 $temp[$c][$fk]=$val; 00811 } 00812 } 00813 $c++; 00814 } 00815 } 00816 } 00817 break; 00818 } 00819 } elseif (is_array($this->alternativeMenuTempArray)) { // Setting $temp array if not level 1. 00820 $temp = $this->alternativeMenuTempArray; 00821 } elseif ($this->mconf['sectionIndex']) { 00822 if ($GLOBALS['TSFE']->sys_language_uid && count($this->sys_page->getPageOverlay($this->id))) { 00823 $sys_language_uid = intval($GLOBALS['TSFE']->sys_language_uid); 00824 } else $sys_language_uid=0; 00825 00826 $selectSetup = Array( 00827 'pidInList'=>$this->id, 00828 'orderBy'=>$altSortField, 00829 'where' => 'colPos=0 AND sys_language_uid='.$sys_language_uid, 00830 'andWhere' => 'sectionIndex!=0' 00831 ); 00832 switch($this->mconf['sectionIndex.']['type']) { 00833 case 'all': 00834 unset($selectSetup['andWhere']); 00835 break; 00836 case 'header': 00837 $selectSetup['andWhere'] .= ' AND header_layout!=100 AND header!=""'; 00838 break; 00839 } 00840 $basePageRow=$this->sys_page->getPage($this->id); 00841 if (is_array($basePageRow)) { 00842 $res = $this->parent_cObj->exec_getQuery('tt_content', $selectSetup); 00843 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00844 $GLOBALS['TSFE']->sys_page->versionOL('tt_content',$row); 00845 00846 if (is_array($row)) { 00847 $temp[$row['uid']] = $basePageRow; 00848 $temp[$row['uid']]['title'] = $row['header']; 00849 $temp[$row['uid']]['nav_title'] = $row['header']; 00850 $temp[$row['uid']]['subtitle'] = $row['subheader']; 00851 $temp[$row['uid']]['starttime'] = $row['starttime']; 00852 $temp[$row['uid']]['endtime'] = $row['endtime']; 00853 $temp[$row['uid']]['fe_group'] = $row['fe_group']; 00854 $temp[$row['uid']]['media'] = $row['media']; 00855 00856 $temp[$row['uid']]['header_layout'] = $row['header_layout']; 00857 $temp[$row['uid']]['bodytext'] = $row['bodytext']; 00858 $temp[$row['uid']]['image'] = $row['image']; 00859 00860 $temp[$row['uid']]['sectionIndex_uid'] = $row['uid']; 00861 } 00862 } 00863 } 00864 } else { // Default: 00865 $temp = $this->sys_page->getMenu($this->id,'*',$altSortField); // gets the menu 00866 } 00867 00868 $c=0; 00869 $c_b=0; 00870 $minItems = intval($this->mconf['minItems'] ? $this->mconf['minItems'] : $this->conf['minItems']); 00871 $maxItems = intval($this->mconf['maxItems'] ? $this->mconf['maxItems'] : $this->conf['maxItems']); 00872 $begin = tslib_cObj::calc($this->mconf['begin'] ? $this->mconf['begin'] : $this->conf['begin']); 00873 00874 $banUidArray = $this->getBannedUids(); 00875 00876 // Fill in the menuArr with elements that should go into the menu: 00877 $this->menuArr = Array(); 00878 foreach($temp as $data) { 00879 $spacer = (t3lib_div::inList($this->spacerIDList,$data['doktype']) || !strcmp($data['ITEM_STATE'],'SPC')) ? 1 : 0; // if item is a spacer, $spacer is set 00880 if ($this->filterMenuPages($data, $banUidArray, $spacer)) { 00881 $c_b++; 00882 if ($begin<=$c_b) { // If the beginning item has been reached. 00883 $this->menuArr[$c] = $data; 00884 $this->menuArr[$c]['isSpacer'] = $spacer; 00885 $c++; 00886 if ($maxItems && $c>=$maxItems) { 00887 break; 00888 } 00889 } 00890 } 00891 } 00892 00893 // Fill in fake items, if min-items is set. 00894 if ($minItems) { 00895 while($c<$minItems) { 00896 $this->menuArr[$c] = Array( 00897 'title' => '...', 00898 'uid' => $GLOBALS['TSFE']->id 00899 ); 00900 $c++; 00901 } 00902 } 00903 // Setting number of menu items 00904 $GLOBALS['TSFE']->register['count_menuItems'] = count($this->menuArr); 00905 // Passing the menuArr through a user defined function: 00906 if ($this->mconf['itemArrayProcFunc']) { 00907 if (!is_array($this->parentMenuArr)) {$this->parentMenuArr=array();} 00908 $this->menuArr = $this->userProcess('itemArrayProcFunc',$this->menuArr); 00909 } 00910 $this->hash = md5(serialize($this->menuArr).serialize($this->mconf).serialize($this->tmpl->rootLine).serialize($this->MP_array)); 00911 00912 // Get the cache timeout: 00913 if ($this->conf['cache_period']) { 00914 $cacheTimeout = $this->conf['cache_period']; 00915 } else { 00916 $cacheTimeout = $GLOBALS['TSFE']->get_cache_timeout(); 00917 } 00918 00919 $serData = $this->sys_page->getHash($this->hash); 00920 if (!$serData) { 00921 $this->generate(); 00922 $this->sys_page->storeHash($this->hash, serialize($this->result), 'MENUDATA', $cacheTimeout); 00923 } else { 00924 $this->result = unserialize($serData); 00925 } 00926 00927 // End showAccessRestrictedPages 00928 if ($this->mconf['showAccessRestrictedPages']) { 00929 // RESTORING where_groupAccess 00930 $this->sys_page->where_groupAccess = $SAVED_where_groupAccess; 00931 } 00932 } 00933 } 00934 00935 /** 00936 * Includes the PHP script defined for the HMENU special type "userdefined". 00937 * This script is supposed to populate the array $menuItemsArray with a set of page records comprising the menu. 00938 * 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) 00939 * 00940 * @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. 00941 * @param string The sorting field. Can be used from the script in the $incFile. 00942 * @return array An array with the menu items 00943 * @deprecated since TYPO3 3.6, this function will be removed in TYPO3 4.6, use HMENU of type "userfunction" instead of "userdefined" 00944 * @access private 00945 */ 00946 function includeMakeMenu($conf,$altSortField) { 00947 t3lib_div::logDeprecatedFunction(); 00948 00949 $incFile = $GLOBALS['TSFE']->tmpl->getFileName($conf['file']); 00950 if ($incFile && $GLOBALS['TSFE']->checkFileInclude($incFile)) { 00951 include($incFile); 00952 } 00953 return is_array($menuItemsArray) ? $menuItemsArray : array(); 00954 } 00955 00956 /** 00957 * 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. 00958 * 00959 * @param array Array of menu items 00960 * @param array Array of page uids which are to be excluded 00961 * @param boolean If set, then the page is a spacer. 00962 * @return boolean Returns true if the page can be safely included. 00963 */ 00964 function filterMenuPages(&$data,$banUidArray,$spacer) { 00965 00966 $includePage = TRUE; 00967 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/tslib/class.tslib_menu.php']['filterMenuPages'])) { 00968 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/tslib/class.tslib_menu.php']['filterMenuPages'] as $classRef) { 00969 $hookObject = t3lib_div::getUserObj($classRef); 00970 00971 if (!($hookObject instanceof tslib_menu_filterMenuPagesHook)) { 00972 throw new UnexpectedValueException('$hookObject must implement interface tslib_menu_filterMenuPagesHook', 1269877402); 00973 } 00974 00975 $includePage = $includePage && $hookObject->tslib_menu_filterMenuPagesHook($data, $banUidArray, $spacer, $this); 00976 } 00977 } 00978 if (!$includePage) { 00979 return FALSE; 00980 } 00981 00982 if ($data['_SAFE']) return TRUE; 00983 00984 $uid = $data['uid']; 00985 if ($this->mconf['SPC'] || !$spacer) { // If the spacer-function is not enabled, spacers will not enter the $menuArr 00986 if (!t3lib_div::inList($this->doktypeExcludeList,$data['doktype'])) { // Page may not be 'not_in_menu' or 'Backend User Section' 00987 if (!$data['nav_hide'] || $this->conf['includeNotInMenu']) { // Not hidden in navigation 00988 if (!t3lib_div::inArray($banUidArray,$uid)) { // not in banned uid's 00989 00990 // Checks if the default language version can be shown: 00991 // Block page is set, if l18n_cfg allows plus: 1) Either default language or 2) another language but NO overlay record set for page! 00992 $blockPage = $data['l18n_cfg']&1 && (!$GLOBALS['TSFE']->sys_language_uid || ($GLOBALS['TSFE']->sys_language_uid && !$data['_PAGES_OVERLAY'])); 00993 if (!$blockPage) { 00994 00995 // Checking if a page should be shown in the menu depending on whether a translation exists: 00996 $tok = TRUE; 00997 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: 00998 if (!$data['_PAGES_OVERLAY']) { 00999 $tok = FALSE; 01000 } 01001 } 01002 01003 // Continue if token is true: 01004 if ($tok) { 01005 01006 // Checking if "&L" should be modified so links to non-accessible pages will not happen. 01007 if ($this->conf['protectLvar']) { 01008 $languageUid = intval($GLOBALS['TSFE']->config['config']['sys_language_uid']); 01009 if ($languageUid && ($this->conf['protectLvar']=='all' || t3lib_div::hideIfNotTranslated($data['l18n_cfg']))) { 01010 $olRec = $GLOBALS['TSFE']->sys_page->getPageOverlay($data['uid'], $languageUid); 01011 if (!count($olRec)) { 01012 // 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" 01013 $data['_ADD_GETVARS'].= '&L=0'; 01014 } 01015 } 01016 } 01017 01018 return TRUE; 01019 } 01020 } 01021 } 01022 } 01023 } 01024 } 01025 } 01026 01027 /** 01028 * Generating the per-menu-item configuration arrays based on the settings for item states (NO, RO, ACT, CUR etc) set in ->mconf (config for the current menu object) 01029 * Basically it will produce an individual array for each menu item based on the item states. BUT in addition the "optionSplit" syntax for the values is ALSO evaluated here so that all property-values are "option-splitted" and the output will thus be resolved. 01030 * Is called from the "generate" functions in the extension classes. The function is processor intensive due to the option split feature in particular. But since the generate function is not always called (since the ->result array may be cached, see makeMenu) it doesn't hurt so badly. 01031 * 01032 * @param integer Number of menu items in the menu 01033 * @return array An array with two keys: array($NOconf,$ROconf) - where $NOconf contains the resolved configuration for each item when NOT rolled-over and $ROconf contains the ditto for the mouseover state (if any) 01034 * @access private 01035 */ 01036 function procesItemStates($splitCount) { 01037 01038 // Prepare normal settings 01039 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. 01040 $NOconf = $this->tmpl->splitConfArray($this->mconf['NO.'],$splitCount); 01041 01042 // Prepare rollOver settings, overriding normal settings 01043 $ROconf=array(); 01044 if ($this->mconf['RO']) { 01045 $ROconf = $this->tmpl->splitConfArray($this->mconf['RO.'],$splitCount); 01046 } 01047 01048 // Prepare IFSUB settings, overriding normal settings 01049 // IFSUB is true if there exist submenu items to the current item 01050 if ($this->mconf['IFSUB']) { 01051 $IFSUBinit = 0; // Flag: If $IFSUB is generated 01052 foreach ($NOconf as $key => $val) { 01053 if ($this->isItemState('IFSUB',$key)) { 01054 if (!$IFSUBinit) { // if this is the first IFSUB element, we must generate IFSUB. 01055 $IFSUBconf = $this->tmpl->splitConfArray($this->mconf['IFSUB.'],$splitCount); 01056 if ($this->mconf['IFSUBRO']) { 01057 $IFSUBROconf = $this->tmpl->splitConfArray($this->mconf['IFSUBRO.'],$splitCount); 01058 } 01059 $IFSUBinit = 1; 01060 } 01061 $NOconf[$key] = $IFSUBconf[$key]; // Substitute normal with ifsub 01062 if ($ROconf) { // If rollOver on normal, we must apply a state for rollOver on the active 01063 $ROconf[$key] = $IFSUBROconf[$key] ? $IFSUBROconf[$key] : $IFSUBconf[$key]; // If RollOver on active then apply this 01064 } 01065 } 01066 } 01067 } 01068 // Prepare active settings, overriding normal settings 01069 if ($this->mconf['ACT']) { 01070 $ACTinit = 0; // Flag: If $ACT is generated 01071 foreach ($NOconf as $key => $val) { // Find active 01072 if ($this->isItemState('ACT',$key)) { 01073 if (!$ACTinit) { // if this is the first 'active', we must generate ACT. 01074 $ACTconf = $this->tmpl->splitConfArray($this->mconf['ACT.'],$splitCount); 01075 // Prepare active rollOver settings, overriding normal active settings 01076 if ($this->mconf['ACTRO']) { 01077 $ACTROconf = $this->tmpl->splitConfArray($this->mconf['ACTRO.'],$splitCount); 01078 } 01079 $ACTinit = 1; 01080 } 01081 $NOconf[$key] = $ACTconf[$key]; // Substitute normal with active 01082 if ($ROconf) { // If rollOver on normal, we must apply a state for rollOver on the active 01083 $ROconf[$key] = $ACTROconf[$key] ? $ACTROconf[$key] : $ACTconf[$key]; // If RollOver on active then apply this 01084 } 01085 } 01086 } 01087 } 01088 // Prepare ACT (active)/IFSUB settings, overriding normal settings 01089 // ACTIFSUB is true if there exist submenu items to the current item and the current item is active 01090 if ($this->mconf['ACTIFSUB']) { 01091 $ACTIFSUBinit = 0; // Flag: If $ACTIFSUB is generated 01092 foreach ($NOconf as $key => $val) { // Find active 01093 if ($this->isItemState('ACTIFSUB',$key)) { 01094 if (!$ACTIFSUBinit) { // if this is the first 'active', we must generate ACTIFSUB. 01095 $ACTIFSUBconf = $this->tmpl->splitConfArray($this->mconf['ACTIFSUB.'],$splitCount); 01096 // Prepare active rollOver settings, overriding normal active settings 01097 if ($this->mconf['ACTIFSUBRO']) { 01098 $ACTIFSUBROconf = $this->tmpl->splitConfArray($this->mconf['ACTIFSUBRO.'],$splitCount); 01099 } 01100 $ACTIFSUBinit = 1; 01101 } 01102 $NOconf[$key] = $ACTIFSUBconf[$key]; // Substitute normal with active 01103 if ($ROconf) { // If rollOver on normal, we must apply a state for rollOver on the active 01104 $ROconf[$key] = $ACTIFSUBROconf[$key] ? $ACTIFSUBROconf[$key] : $ACTIFSUBconf[$key]; // If RollOver on active then apply this 01105 } 01106 } 01107 } 01108 } 01109 // Prepare CUR (current) settings, overriding normal settings 01110 // CUR is true if the current page equals the item here! 01111 if ($this->mconf['CUR']) { 01112 $CURinit = 0; // Flag: If $CUR is generated 01113 foreach ($NOconf as $key => $val) { 01114 if ($this->isItemState('CUR',$key)) { 01115 if (!$CURinit) { // if this is the first 'current', we must generate CUR. Basically this control is just inherited from the other implementations as current would only exist one time and thats it (unless you use special-features of HMENU) 01116 $CURconf = $this->tmpl->splitConfArray($this->mconf['CUR.'],$splitCount); 01117 if ($this->mconf['CURRO']) { 01118 $CURROconf = $this->tmpl->splitConfArray($this->mconf['CURRO.'],$splitCount); 01119 } 01120 $CURinit = 1; 01121 } 01122 $NOconf[$key] = $CURconf[$key]; // Substitute normal with current 01123 if ($ROconf) { // If rollOver on normal, we must apply a state for rollOver on the active 01124 $ROconf[$key] = $CURROconf[$key] ? $CURROconf[$key] : $CURconf[$key]; // If RollOver on active then apply this 01125 } 01126 } 01127 } 01128 } 01129 // Prepare CUR (current)/IFSUB settings, overriding normal settings 01130 // CURIFSUB is true if there exist submenu items to the current item and the current page equals the item here! 01131 if ($this->mconf['CURIFSUB']) { 01132 $CURIFSUBinit = 0; // Flag: If $CURIFSUB is generated 01133 foreach ($NOconf as $key => $val) { 01134 if ($this->isItemState('CURIFSUB',$key)) { 01135 if (!$CURIFSUBinit) { // if this is the first 'current', we must generate CURIFSUB. 01136 $CURIFSUBconf = $this->tmpl->splitConfArray($this->mconf['CURIFSUB.'],$splitCount); 01137 // Prepare current rollOver settings, overriding normal current settings 01138 if ($this->mconf['CURIFSUBRO']) { 01139 $CURIFSUBROconf = $this->tmpl->splitConfArray($this->mconf['CURIFSUBRO.'],$splitCount); 01140 } 01141 $CURIFSUBinit = 1; 01142 } 01143 $NOconf[$key] = $CURIFSUBconf[$key]; // Substitute normal with active 01144 if ($ROconf) { // If rollOver on normal, we must apply a state for rollOver on the current 01145 $ROconf[$key] = $CURIFSUBROconf[$key] ? $CURIFSUBROconf[$key] : $CURIFSUBconf[$key]; // If RollOver on current then apply this 01146 } 01147 } 01148 } 01149 } 01150 // Prepare active settings, overriding normal settings 01151 if ($this->mconf['USR']) { 01152 $USRinit = 0; // Flag: If $USR is generated 01153 foreach ($NOconf as $key => $val) { // Find active 01154 if ($this->isItemState('USR',$key)) { 01155 if (!$USRinit) { // if this is the first active, we must generate USR. 01156 $USRconf = $this->tmpl->splitConfArray($this->mconf['USR.'],$splitCount); 01157 // Prepare active rollOver settings, overriding normal active settings 01158 if ($this->mconf['USRRO']) { 01159 $USRROconf = $this->tmpl->splitConfArray($this->mconf['USRRO.'],$splitCount); 01160 } 01161 $USRinit = 1; 01162 } 01163 $NOconf[$key] = $USRconf[$key]; // Substitute normal with active 01164 if ($ROconf) { // If rollOver on normal, we must apply a state for rollOver on the active 01165 $ROconf[$key] = $USRROconf[$key] ? $USRROconf[$key] : $USRconf[$key]; // If RollOver on active then apply this 01166 } 01167 } 01168 } 01169 } 01170 // Prepare spacer settings, overriding normal settings 01171 if ($this->mconf['SPC']) { 01172 $SPCinit = 0; // Flag: If $SPC is generated 01173 foreach ($NOconf as $key => $val) { // Find spacers 01174 if ($this->isItemState('SPC',$key)) { 01175 if (!$SPCinit) { // if this is the first spacer, we must generate SPC. 01176 $SPCconf = $this->tmpl->splitConfArray($this->mconf['SPC.'],$splitCount); 01177 $SPCinit = 1; 01178 } 01179 $NOconf[$key] = $SPCconf[$key]; // Substitute normal with spacer 01180 } 01181 } 01182 } 01183 // Prepare Userdefined settings 01184 if ($this->mconf['USERDEF1']) { 01185 $USERDEF1init = 0; // Flag: If $USERDEF1 is generated 01186 foreach ($NOconf as $key => $val) { // Find active 01187 if ($this->isItemState('USERDEF1',$key)) { 01188 if (!$USERDEF1init) { // if this is the first active, we must generate USERDEF1. 01189 $USERDEF1conf = $this->tmpl->splitConfArray($this->mconf['USERDEF1.'],$splitCount); 01190 // Prepare active rollOver settings, overriding normal active settings 01191 if ($this->mconf['USERDEF1RO']) { 01192 $USERDEF1ROconf = $this->tmpl->splitConfArray($this->mconf['USERDEF1RO.'],$splitCount); 01193 } 01194 $USERDEF1init = 1; 01195 } 01196 $NOconf[$key] = $USERDEF1conf[$key]; // Substitute normal with active 01197 if ($ROconf) { // If rollOver on normal, we must apply a state for rollOver on the active 01198 $ROconf[$key] = $USERDEF1ROconf[$key] ? $USERDEF1ROconf[$key] : $USERDEF1conf[$key]; // If RollOver on active then apply this 01199 } 01200 } 01201 } 01202 } 01203 // Prepare Userdefined settings 01204 if ($this->mconf['USERDEF2']) { 01205 $USERDEF2init = 0; // Flag: If $USERDEF2 is generated 01206 foreach ($NOconf as $key => $val) { // Find active 01207 if ($this->isItemState('USERDEF2',$key)) { 01208 if (!$USERDEF2init) { // if this is the first active, we must generate USERDEF2. 01209 $USERDEF2conf = $this->tmpl->splitConfArray($this->mconf['USERDEF2.'],$splitCount); 01210 // Prepare active rollOver settings, overriding normal active settings 01211 if ($this->mconf['USERDEF2RO']) { 01212 $USERDEF2ROconf = $this->tmpl->splitConfArray($this->mconf['USERDEF2RO.'],$splitCount); 01213 } 01214 $USERDEF2init = 1; 01215 } 01216 $NOconf[$key] = $USERDEF2conf[$key]; // Substitute normal with active 01217 if ($ROconf) { // If rollOver on normal, we must apply a state for rollOver on the active 01218 $ROconf[$key] = $USERDEF2ROconf[$key] ? $USERDEF2ROconf[$key] : $USERDEF2conf[$key]; // If RollOver on active then apply this 01219 } 01220 } 01221 } 01222 } 01223 01224 return array($NOconf,$ROconf); 01225 } 01226 01227 /** 01228 * Creates the URL, target and onclick values for the menu item link. Returns them in an array as key/value pairs for <A>-tag attributes 01229 * This function doesn't care about the url, because if we let the url be redirected, it will be logged in the stat!!! 01230 * 01231 * @param integer Pointer to a key in the $this->menuArr array where the value for that key represents the menu item we are linking to (page record) 01232 * @param string Alternative target 01233 * @param integer Alternative type 01234 * @return array Returns an array with A-tag attributes as key/value pairs (HREF, TARGET and onClick) 01235 * @access private 01236 */ 01237 function link($key,$altTarget='',$typeOverride='') { 01238 01239 // Mount points: 01240 $MP_var = $this->getMPvar($key); 01241 $MP_params = $MP_var ? '&MP='.rawurlencode($MP_var) : ''; 01242 01243 // Setting override ID 01244 if ($this->mconf['overrideId'] || $this->menuArr[$key]['overrideId']) { 01245 $overrideArray = array(); 01246 // If a user script returned the value overrideId in the menu array we use that as page id 01247 $overrideArray['uid'] = $this->mconf['overrideId']?$this->mconf['overrideId']:$this->menuArr[$key]['overrideId']; 01248 $overrideArray['alias'] = ''; 01249 $MP_params = ''; // clear MP parameters since ID was changed. 01250 } else { 01251 $overrideArray=''; 01252 } 01253 01254 // Setting main target: 01255 $mainTarget = $altTarget ? $altTarget : $this->mconf['target']; 01256 01257 // Creating link: 01258 if ($this->mconf['collapse'] && $this->isActive($this->menuArr[$key]['uid'], $this->getMPvar($key))) { 01259 $thePage = $this->sys_page->getPage($this->menuArr[$key]['pid']); 01260 $LD = $this->menuTypoLink($thePage,$mainTarget,'','',$overrideArray, $this->mconf['addParams'].$MP_params.$this->menuArr[$key]['_ADD_GETVARS'], $typeOverride); 01261 } else { 01262 $LD = $this->menuTypoLink($this->menuArr[$key],$mainTarget,'','',$overrideArray, $this->mconf['addParams'].$MP_params.$this->I['val']['additionalParams'].$this->menuArr[$key]['_ADD_GETVARS'], $typeOverride); 01263 } 01264 01265 // Override URL if using "External URL" as doktype with a valid e-mail address: 01266 if ($this->menuArr[$key]['doktype'] == t3lib_pageSelect::DOKTYPE_LINK && $this->menuArr[$key]['urltype'] == 3 && t3lib_div::validEmail($this->menuArr[$key]['url'])) { 01267 // Create mailto-link using tslib_cObj::typolink (concerning spamProtectEmailAddresses): 01268 $LD['totalURL'] = $this->parent_cObj->typoLink_URL(array('parameter' => $this->menuArr[$key]['url'])); 01269 $LD['target'] = ''; 01270 } 01271 01272 // Manipulation in case of access restricted pages: 01273 $this->changeLinksForAccessRestrictedPages($LD,$this->menuArr[$key],$mainTarget,$typeOverride); 01274 01275 // Overriding URL / Target if set to do so: 01276 if ($this->menuArr[$key]['_OVERRIDE_HREF']) { 01277 $LD['totalURL'] = $this->menuArr[$key]['_OVERRIDE_HREF']; 01278 if ($this->menuArr[$key]['_OVERRIDE_TARGET']) $LD['target'] = $this->menuArr[$key]['_OVERRIDE_TARGET']; 01279 } 01280 01281 // OnClick open in windows. 01282 $onClick=''; 01283 if ($this->mconf['JSWindow']) { 01284 $conf=$this->mconf['JSWindow.']; 01285 $url=$LD['totalURL']; 01286 $LD['totalURL'] = '#'; 01287 $onClick= 'openPic(\''.$GLOBALS['TSFE']->baseUrlWrap($url).'\',\''.($conf['newWindow']?md5($url):'theNewPage').'\',\''.$conf['params'].'\'); return false;'; 01288 $GLOBALS['TSFE']->setJS('openPic'); 01289 } 01290 01291 // look for type and popup 01292 // following settings are valid in field target: 01293 // 230 will add type=230 to the link 01294 // 230 500x600 will add type=230 to the link and open in popup window with 500x600 pixels 01295 // 230 _blank will add type=230 to the link and open with target "_blank" 01296 // 230x450:resizable=0,location=1 will open in popup window with 500x600 pixels with settings "resizable=0,location=1" 01297 $matches = array(); 01298 $targetIsType = $LD['target'] && (string) intval($LD['target']) == trim($LD['target']) ? intval($LD['target']) : FALSE; 01299 if (preg_match('/([0-9]+[\s])?(([0-9]+)x([0-9]+))?(:.+)?/s', $LD['target'], $matches) || $targetIsType) { 01300 // has type? 01301 if(intval($matches[1]) || $targetIsType) { 01302 $LD['totalURL'] .= '&type=' . ($targetIsType ? $targetIsType : intval($matches[1])); 01303 $LD['target'] = $targetIsType ? '' : trim(substr($LD['target'], strlen($matches[1]) + 1)); 01304 } 01305 // open in popup window? 01306 if ($matches[3] && $matches[4]) { 01307 $JSparamWH = 'width=' . $matches[3] . ',height=' . $matches[4] . ($matches[5] ? ',' . substr($matches[5], 1) : ''); 01308 $onClick = 'vHWin=window.open(\'' . $LD['totalURL'] . '\',\'FEopenLink\',\'' . $JSparamWH . '\');vHWin.focus();return false;'; 01309 $LD['target'] = ''; 01310 } 01311 } 01312 01313 // out: 01314 $list = array(); 01315 $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. 01316 $list['TARGET'] = $LD['target']; 01317 $list['onClick'] = $onClick; 01318 01319 return $list; 01320 } 01321 01322 /** 01323 * Will change $LD (passed by reference) if the page is access restricted 01324 * 01325 * @param array $LD, the array from the linkData() function 01326 * @param array Page array 01327 * @param string Main target value 01328 * @param string Type number override if any 01329 * @return void ($LD passed by reference might be changed.) 01330 */ 01331 function changeLinksForAccessRestrictedPages(&$LD, $page, $mainTarget, $typeOverride) { 01332 01333 // If access restricted pages should be shown in menus, change the link of such pages to link to a redirection page: 01334 if ($this->mconf['showAccessRestrictedPages'] && $this->mconf['showAccessRestrictedPages']!=='NONE' && !$GLOBALS['TSFE']->checkPageGroupAccess($page)) { 01335 $thePage = $this->sys_page->getPage($this->mconf['showAccessRestrictedPages']); 01336 01337 $addParams = $this->mconf['showAccessRestrictedPages.']['addParams']; 01338 $addParams = str_replace('###RETURN_URL###',rawurlencode($LD['totalURL']),$addParams); 01339 $addParams = str_replace('###PAGE_ID###',$page['uid'],$addParams); 01340 $LD = $this->menuTypoLink($thePage,$mainTarget,'','','', $addParams, $typeOverride); 01341 } 01342 } 01343 01344 /** 01345 * Creates a submenu level to the current level - if configured for. 01346 * 01347 * @param integer Page id of the current page for which a submenu MAY be produced (if conditions are met) 01348 * @param string Object prefix, see ->start() 01349 * @return string HTML content of the submenu 01350 * @access private 01351 */ 01352 function subMenu($uid, $objSuffix='') { 01353 01354 // Setting alternative menu item array if _SUB_MENU has been defined in the current ->menuArr 01355 $altArray = ''; 01356 if (is_array($this->menuArr[$this->I['key']]['_SUB_MENU']) && count($this->menuArr[$this->I['key']]['_SUB_MENU'])) { 01357 $altArray = $this->menuArr[$this->I['key']]['_SUB_MENU']; 01358 } 01359 01360 // Make submenu if the page is the next active 01361 $cls = strtolower($this->conf[($this->menuNumber+1).$objSuffix]); 01362 $subLevelClass = ($cls && t3lib_div::inList($this->tmpl->menuclasses,$cls)) ? $cls : ''; 01363 01364 // stdWrap for expAll 01365 if (isset($this->mconf['expAll.'])) { 01366 $this->mconf['expAll'] = $this->parent_cObj->stdWrap($this->mconf['expAll'], $this->mconf['expAll.']); 01367 } 01368 01369 if ($subLevelClass && ($this->mconf['expAll'] || $this->isNext($uid, $this->getMPvar($this->I['key'])) || is_array($altArray)) && !$this->mconf['sectionIndex']) { 01370 $submenu = t3lib_div::makeInstance('tslib_'.$subLevelClass); 01371 $submenu->entryLevel = $this->entryLevel+1; 01372 $submenu->rL_uidRegister = $this->rL_uidRegister; 01373 $submenu->MP_array = $this->MP_array; 01374 if ($this->menuArr[$this->I['key']]['_MP_PARAM']) { 01375 $submenu->MP_array[] = $this->menuArr[$this->I['key']]['_MP_PARAM']; 01376 } 01377 01378 // especially scripts that build the submenu needs the parent data 01379 $submenu->parent_cObj = $this->parent_cObj; 01380 $submenu->parentMenuArr = $this->menuArr; 01381 01382 // Setting alternativeMenuTempArray (will be effective only if an array) 01383 if (is_array($altArray)) { 01384 $submenu->alternativeMenuTempArray = $altArray; 01385 } 01386 01387 if ($submenu->start($this->tmpl, $this->sys_page, $uid, $this->conf, $this->menuNumber+1, $objSuffix)) { 01388 $submenu->makeMenu(); 01389 // Memorize the current menu item count 01390 $tempCountMenuObj = $GLOBALS['TSFE']->register['count_MENUOBJ']; 01391 // Reset the menu item count for the submenu 01392 $GLOBALS['TSFE']->register['count_MENUOBJ'] = 0; 01393 $content = $submenu->writeMenu(); 01394 // Restore the item count now that the submenu has been handled 01395 $GLOBALS['TSFE']->register['count_MENUOBJ'] = $tempCountMenuObj; 01396 $GLOBALS['TSFE']->register['count_menuItems'] = count($this->menuArr); 01397 return $content; 01398 } 01399 } 01400 } 01401 01402 /** 01403 * Returns true if the page with UID $uid is the NEXT page in root line (which means a submenu should be drawn) 01404 * 01405 * @param integer Page uid to evaluate. 01406 * @param string MPvar for the current position of item. 01407 * @return boolean True if page with $uid is active 01408 * @access private 01409 * @see subMenu() 01410 */ 01411 function isNext($uid, $MPvar='') { 01412 01413 // Check for always active PIDs: 01414 if (count($this->alwaysActivePIDlist) && in_array($uid,$this->alwaysActivePIDlist)) { 01415 return TRUE; 01416 } 01417 01418 $testUid = $uid.($MPvar?':'.$MPvar:''); 01419 if ($uid && $testUid==$this->nextActive) { 01420 return TRUE; 01421 } 01422 } 01423 01424 /** 01425 * Returns true if the page with UID $uid is active (in the current rootline) 01426 * 01427 * @param integer Page uid to evaluate. 01428 * @param string MPvar for the current position of item. 01429 * @return boolean True if page with $uid is active 01430 * @access private 01431 */ 01432 function isActive($uid, $MPvar='') { 01433 01434 // Check for always active PIDs: 01435 if (count($this->alwaysActivePIDlist) && in_array($uid,$this->alwaysActivePIDlist)) { 01436 return TRUE; 01437 } 01438 01439 $testUid = $uid.($MPvar?':'.$MPvar:''); 01440 if ($uid && in_array('ITEM:'.$testUid, $this->rL_uidRegister)) { 01441 return TRUE; 01442 } 01443 } 01444 01445 /** 01446 * Returns true if the page with UID $uid is the CURRENT page (equals $GLOBALS['TSFE']->id) 01447 * 01448 * @param integer Page uid to evaluate. 01449 * @param string MPvar for the current position of item. 01450 * @return boolean True if page $uid = $GLOBALS['TSFE']->id 01451 * @access private 01452 */ 01453 function isCurrent($uid, $MPvar='') { 01454 $testUid = $uid.($MPvar?':'.$MPvar:''); 01455 if ($uid && !strcmp(end($this->rL_uidRegister),'ITEM:'.$testUid)) { 01456 return TRUE; 01457 } 01458 } 01459 01460 /** 01461 * Returns true if there is a submenu with items for the page id, $uid 01462 * Used by the item states "IFSUB", "ACTIFSUB" and "CURIFSUB" to check if there is a submenu 01463 * 01464 * @param integer Page uid for which to search for a submenu 01465 * @return boolean Returns true if there was a submenu with items found 01466 * @access private 01467 */ 01468 function isSubMenu($uid) { 01469 01470 // Looking for a mount-pid for this UID since if that exists we should look for a subpages THERE and not in the input $uid; 01471 $mount_info = $this->sys_page->getMountPointInfo($uid); 01472 if (is_array($mount_info)) { 01473 $uid = $mount_info['mount_pid']; 01474 } 01475 01476 $recs = $this->sys_page->getMenu($uid,'uid,pid,doktype,mount_pid,mount_pid_ol,nav_hide,shortcut,shortcut_mode'); 01477 foreach($recs as $theRec) { 01478 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!) 01479 return TRUE; 01480 } 01481 } 01482 } 01483 01484 /** 01485 * Used by procesItemStates() to evaluate if a menu item (identified by $key) is in a certain state. 01486 * 01487 * @param string The item state to evaluate (SPC, IFSUB, ACT etc... but no xxxRO states of course) 01488 * @param integer Key pointing to menu item from ->menuArr 01489 * @return boolean True (integer!=0) if match, otherwise false (=0, zero) 01490 * @access private 01491 * @see procesItemStates() 01492 */ 01493 function isItemState($kind,$key) { 01494 $natVal=0; 01495 if ($this->menuArr[$key]['ITEM_STATE']) { // If any value is set for ITEM_STATE the normal evaluation is discarded 01496 if (!strcmp($this->menuArr[$key]['ITEM_STATE'],$kind)) {$natVal=1;} 01497 } else { 01498 switch($kind) { 01499 case 'SPC': 01500 $natVal = $this->menuArr[$key]['isSpacer']; 01501 break; 01502 case 'IFSUB': 01503 $natVal = $this->isSubMenu($this->menuArr[$key]['uid']); 01504 break; 01505 case 'ACT': 01506 $natVal = $this->isActive($this->menuArr[$key]['uid'], $this->getMPvar($key)); 01507 break; 01508 case 'ACTIFSUB': 01509 $natVal = $this->isActive($this->menuArr[$key]['uid'], $this->getMPvar($key)) && $this->isSubMenu($this->menuArr[$key]['uid']); 01510 break; 01511 case 'CUR': 01512 $natVal = $this->isCurrent($this->menuArr[$key]['uid'], $this->getMPvar($key)); 01513 break; 01514 case 'CURIFSUB': 01515 $natVal = $this->isCurrent($this->menuArr[$key]['uid'], $this->getMPvar($key)) && $this->isSubMenu($this->menuArr[$key]['uid']); 01516 break; 01517 case 'USR': 01518 $natVal = $this->menuArr[$key]['fe_group']; 01519 break; 01520 } 01521 } 01522 01523 return $natVal; 01524 } 01525 01526 /** 01527 * Creates an access-key for a TMENU/GMENU menu item based on the menu item titles first letter 01528 * 01529 * @param string Menu item title. 01530 * @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 01531 * @access private 01532 */ 01533 function accessKey($title) { 01534 // The global array ACCESSKEY is used to globally control if letters are already used!! 01535 $result = Array(); 01536 01537 $title = trim(strip_tags($title)); 01538 $titleLen = strlen($title); 01539 for ($a=0;$a<$titleLen;$a++) { 01540 $key = strtoupper(substr($title,$a,1)); 01541 if (preg_match('/[A-Z]/', $key) && !isset($GLOBALS['TSFE']->accessKey[$key])) { 01542 $GLOBALS['TSFE']->accessKey[$key] = 1; 01543 $result['code'] = ' accesskey="'.$key.'"'; 01544 $result['alt'] = ' (ALT+'.$key.')'; 01545 $result['key'] = $key; 01546 break; 01547 } 01548 } 01549 return $result; 01550 } 01551 01552 /** 01553 * Calls a user function for processing of internal data. 01554 * Used for the properties "IProcFunc" and "itemArrayProcFunc" 01555 * 01556 * @param string Key pointing for the property in the current ->mconf array holding possibly parameters to pass along to the function/method. Currently the keys used are "IProcFunc" and "itemArrayProcFunc". 01557 * @param mixed A variable to pass to the user function and which should be returned again from the user function. The idea is that the user function modifies this variable according to what you want to achieve and then returns it. For "itemArrayProcFunc" this variable is $this->menuArr, for "IProcFunc" it is $this->I 01558 * @return mixed The processed $passVar 01559 * @access private 01560 */ 01561 function userProcess($mConfKey,$passVar) { 01562 if ($this->mconf[$mConfKey]) { 01563 $funcConf = $this->mconf[$mConfKey.'.']; 01564 $funcConf['parentObj'] = $this; 01565 $passVar = $this->parent_cObj->callUserFunction($this->mconf[$mConfKey], $funcConf, $passVar); 01566 } 01567 return $passVar; 01568 } 01569 01570 /** 01571 * Creates the <A> tag parts for the current item (in $this->I, [A1] and [A2]) based on other information in this array (like $this->I['linkHREF']) 01572 * 01573 * @return void 01574 * @access private 01575 */ 01576 function setATagParts() { 01577 $this->I['A1'] = '<a '.t3lib_div::implodeAttributes($this->I['linkHREF'],1).' '.$this->I['val']['ATagParams'].$this->I['accessKey']['code'].'>'; 01578 $this->I['A2'] = '</a>'; 01579 } 01580 01581 /** 01582 * Returns the title for the navigation 01583 * 01584 * @param string The current page title 01585 * @param string The current value of the navigation title 01586 * @return string Returns the navigation title if it is NOT blank, otherwise the page title. 01587 * @access private 01588 */ 01589 function getPageTitle($title,$nav_title) { 01590 return strcmp(trim($nav_title),'') ? $nav_title : $title; 01591 } 01592 01593 /** 01594 * Return MPvar string for entry $key in ->menuArr 01595 * 01596 * @param integer Pointer to element in ->menuArr 01597 * @param string Implode token. 01598 * @return string MP vars for element. 01599 * @see link() 01600 */ 01601 function getMPvar($key) { 01602 if ($GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids']) { 01603 $localMP_array = $this->MP_array; 01604 if ($this->menuArr[$key]['_MP_PARAM']) $localMP_array[] = $this->menuArr[$key]['_MP_PARAM']; // NOTICE: "_MP_PARAM" is allowed to be a commalist of PID pairs! 01605 $MP_params = count($localMP_array) ? implode(',',$localMP_array) : ''; 01606 return $MP_params; 01607 } 01608 } 01609 01610 /** 01611 * Returns where clause part to exclude 'not in menu' pages 01612 * 01613 * @return string where clause part. 01614 * @access private 01615 */ 01616 function getDoktypeExcludeWhere() { 01617 return $this->doktypeExcludeList ? ' AND pages.doktype NOT IN ('.$this->doktypeExcludeList.')' : ''; 01618 } 01619 01620 /** 01621 * Returns an array of banned UIDs (from excludeUidList) 01622 * 01623 * @return array Array of banned UIDs 01624 * @access private 01625 */ 01626 function getBannedUids() { 01627 $banUidArray = array(); 01628 01629 if (trim($this->conf['excludeUidList'])) { 01630 $banUidList = str_replace('current', $GLOBALS['TSFE']->page['uid'], $this->conf['excludeUidList']); 01631 $banUidArray = t3lib_div::intExplode(',', $banUidList); 01632 } 01633 01634 return $banUidArray; 01635 } 01636 01637 /** 01638 * Calls typolink to create menu item links. 01639 * 01640 * @param array $page Page record (uid points where to link to) 01641 * @param string $oTarget Target frame/window 01642 * @param boolean $no_cache true if caching should be disabled 01643 * @param string $script Alternative script name 01644 * @param array $overrideArray Array to override values in $page 01645 * @param string $addParams Parameters to add to URL 01646 * @param array $typeOverride "type" value 01647 * @return array See linkData 01648 */ 01649 function menuTypoLink($page, $oTarget, $no_cache, $script, $overrideArray = '', $addParams = '', $typeOverride = '') { 01650 $conf = array( 01651 'parameter' => is_array($overrideArray) && $overrideArray['uid'] ? $overrideArray['uid'] : $page['uid'], 01652 ); 01653 if ($typeOverride && t3lib_div::testInt($typeOverride)) { 01654 $conf['parameter'] .= ',' . $typeOverride; 01655 } 01656 if ($addParams) { 01657 $conf['additionalParams'] = $addParams; 01658 } 01659 if ($no_cache) { 01660 $conf['no_cache'] = true; 01661 } 01662 if ($oTarget) { 01663 $conf['target'] = $oTarget; 01664 } 01665 if ($page['sectionIndex_uid']) { 01666 $conf['section'] = $page['sectionIndex_uid']; 01667 } 01668 01669 $this->parent_cObj->typoLink('|', $conf); 01670 $LD = $this->parent_cObj->lastTypoLinkLD; 01671 $LD['totalURL'] = $this->parent_cObj->lastTypoLinkUrl; 01672 return $LD; 01673 } 01674 01675 } 01676 01677 01678 01679 01680 01681 01682 01683 01684 01685 01686 01687 01688 01689 01690 01691 01692 01693 01694 01695 /** 01696 * Extension class creating text based menus 01697 * 01698 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 01699 * @package TYPO3 01700 * @subpackage tslib 01701 */ 01702 class tslib_tmenu extends tslib_menu { 01703 01704 /** 01705 * Calls procesItemStates() so that the common configuration for the menu items are resolved into individual configuration per item. 01706 * Sets the result for the new "normal state" in $this->result 01707 * 01708 * @return void 01709 * @see tslib_menu::procesItemStates() 01710 */ 01711 function generate() { 01712 $splitCount = count($this->menuArr); 01713 if ($splitCount) { 01714 list($NOconf) = $this->procesItemStates($splitCount); 01715 } 01716 if ($this->mconf['debugItemConf']) {echo '<h3>$NOconf:</h3>'; debug($NOconf); } 01717 $this->result = $NOconf; 01718 } 01719 01720 /** 01721 * Traverses the ->result array of menu items configuration (made by ->generate()) and renders each item. 01722 * During the execution of this function many internal methods prefixed "extProc_" from this class is called and many of these are for now dummy functions. But they can be used for processing as they are used by the TMENU_LAYERS 01723 * An instance of tslib_cObj is also made and for each menu item rendered it is loaded with the record for that page so that any stdWrap properties that applies will have the current menu items record available. 01724 * 01725 * @return string The HTML for the menu (returns result through $this->extProc_finish(); ) 01726 */ 01727 function writeMenu() { 01728 if (is_array($this->result) && count($this->result)) { 01729 $this->WMcObj = t3lib_div::makeInstance('tslib_cObj'); // Create new tslib_cObj for our use 01730 $this->WMresult = ''; 01731 $this->INPfixMD5 = substr(md5(microtime().'tmenu'),0,4); 01732 $this->WMmenuItems = count($this->result); 01733 01734 $this->WMsubmenuObjSuffixes = $this->tmpl->splitConfArray(array('sOSuffix'=>$this->mconf['submenuObjSuffixes']),$this->WMmenuItems); 01735 01736 $this->extProc_init(); 01737 foreach ($this->result as $key => $val) { 01738 $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ']++; 01739 $GLOBALS['TSFE']->register['count_MENUOBJ']++; 01740 01741 $this->WMcObj->start($this->menuArr[$key],'pages'); // Initialize the cObj with the page record of the menu item 01742 01743 $this->I = array(); 01744 $this->I['key'] = $key; 01745 $this->I['INPfix'] = ($this->imgNameNotRandom ? '' : '_'.$this->INPfixMD5).'_'.$key; 01746 $this->I['val'] = $val; 01747 $this->I['title'] = isset($this->I['val']['stdWrap.']) 01748 ? $this->WMcObj->stdWrap($this->getPageTitle($this->menuArr[$key]['title'], $this->menuArr[$key]['nav_title']), $this->I['val']['stdWrap.']) 01749 : $this->getPageTitle($this->menuArr[$key]['title'],$this->menuArr[$key]['nav_title']); 01750 $this->I['uid'] = $this->menuArr[$key]['uid']; 01751 $this->I['mount_pid'] = $this->menuArr[$key]['mount_pid']; 01752 $this->I['pid'] = $this->menuArr[$key]['pid']; 01753 $this->I['spacer'] = $this->menuArr[$key]['isSpacer']; 01754 01755 // Set access key 01756 if ($this->mconf['accessKey']) { 01757 $this->I['accessKey'] = $this->accessKey($this->I['title']); 01758 } else { 01759 $this->I['accessKey'] = Array(); 01760 } 01761 01762 // Make link tag 01763 $this->I['val']['ATagParams'] = $this->WMcObj->getATagParams($this->I['val']); 01764 if(isset($this->I['val']['additionalParams.'])) { 01765 $this->I['val']['additionalParams'] = $this->WMcObj->stdWrap($this->I['val']['additionalParams'], $this->I['val']['additionalParams.']); 01766 } 01767 $this->I['linkHREF'] = $this->link($key,$this->I['val']['altTarget'],$this->mconf['forceTypeValue']); 01768 01769 // Title attribute of links: 01770 $titleAttrValue = isset($this->I['val']['ATagTitle.']) 01771 ? $this->WMcObj->stdWrap($this->I['val']['ATagTitle'], $this->I['val']['ATagTitle.']) . $this->I['accessKey']['alt'] 01772 : $this->I['val']['ATagTitle'].$this->I['accessKey']['alt']; 01773 if (strlen($titleAttrValue)) { 01774 $this->I['linkHREF']['title'] = $titleAttrValue; 01775 } 01776 01777 // Setting "blurlink()" function: 01778 if (!$this->mconf['noBlur']) { 01779 $this->I['linkHREF']['onFocus']='blurLink(this);'; 01780 } 01781 01782 // Make link: 01783 if ($this->I['val']['RO']) { 01784 $this->I['theName'] = $this->imgNamePrefix.$this->I['uid'].$this->I['INPfix']; 01785 $over=''; 01786 $out =''; 01787 if ($this->I['val']['beforeROImg']) { 01788 $over.= $this->WMfreezePrefix."over('".$this->I['theName']."before');"; 01789 $out.= $this->WMfreezePrefix."out('".$this->I['theName']."before');"; 01790 } 01791 if ($this->I['val']['afterROImg']) { 01792 $over.= $this->WMfreezePrefix."over('".$this->I['theName']."after');"; 01793 $out.= $this->WMfreezePrefix."out('".$this->I['theName']."after');"; 01794 } 01795 $this->I['linkHREF']['onMouseover']=$over; 01796 $this->I['linkHREF']['onMouseout']=$out; 01797 if ($over || $out) $GLOBALS['TSFE']->setJS('mouseOver'); 01798 01799 // Change background color: 01800 if ($this->I['val']['RO_chBgColor']) { 01801 $this->addJScolorShiftFunction(); 01802 $chBgP = t3lib_div::trimExplode('|',$this->I['val']['RO_chBgColor']); 01803 $this->I['linkHREF']['onMouseover'].="changeBGcolor('".$chBgP[2].$this->I['uid']."','".$chBgP[0]."');"; 01804 $this->I['linkHREF']['onMouseout'].="changeBGcolor('".$chBgP[2].$this->I['uid']."','".$chBgP[1]."');"; 01805 } 01806 01807 $this->extProc_RO($key); 01808 } 01809 01810 01811 // Calling extra processing function 01812 $this->extProc_beforeLinking($key); 01813 01814 // stdWrap for doNotLinkIt 01815 if (isset($this->I['val']['doNotLinkIt.'])) { 01816 $this->I['val']['doNotLinkIt'] = $this->WMcObj->stdWrap($this->I['val']['doNotLinkIt'], $this->I['val']['doNotLinkIt.']); 01817 } 01818 01819 // Compile link tag 01820 if (!$this->I['val']['doNotLinkIt']) {$this->I['val']['doNotLinkIt']=0;} 01821 if (!$this->I['spacer'] && $this->I['val']['doNotLinkIt']!=1) { 01822 $this->setATagParts(); 01823 } else { 01824 $this->I['A1'] = ''; 01825 $this->I['A2'] = ''; 01826 } 01827 01828 // ATagBeforeWrap processing: 01829 if ($this->I['val']['ATagBeforeWrap']) { 01830 $wrapPartsBefore = explode('|',$this->I['val']['linkWrap']); 01831 $wrapPartsAfter = array('',''); 01832 } else { 01833 $wrapPartsBefore = array('',''); 01834 $wrapPartsAfter = explode('|',$this->I['val']['linkWrap']); 01835 } 01836 if ($this->I['val']['stdWrap2'] || isset($this->I['val']['stdWrap2.'])) { 01837 $stdWrap2 = isset($this->I['val']['stdWrap2.']) 01838 ? $this->WMcObj->stdWrap('|', $this->I['val']['stdWrap2.']) 01839 : '|'; 01840 $wrapPartsStdWrap = explode($this->I['val']['stdWrap2'] ? $this->I['val']['stdWrap2'] : '|', $stdWrap2); 01841 } else {$wrapPartsStdWrap = array('','');} 01842 01843 // Make before, middle and after parts 01844 $this->I['parts'] = array(); 01845 $this->I['parts']['before']=$this->getBeforeAfter('before'); 01846 $this->I['parts']['stdWrap2_begin']=$wrapPartsStdWrap[0]; 01847 01848 // stdWrap for doNotShowLink 01849 if (isset($this->I['val']['doNotShowLink.'])) { 01850 $this->I['val']['doNotShowLink'] = $this->WMcObj->stdWrap($this->I['val']['doNotShowLink'], $this->I['val']['doNotShowLink.']); 01851 } 01852 01853 if (!$this->I['val']['doNotShowLink']) { 01854 $this->I['parts']['notATagBeforeWrap_begin'] = $wrapPartsAfter[0]; 01855 $this->I['parts']['ATag_begin'] = $this->I['A1']; 01856 $this->I['parts']['ATagBeforeWrap_begin'] = $wrapPartsBefore[0]; 01857 $this->I['parts']['title'] = $this->I['title']; 01858 $this->I['parts']['ATagBeforeWrap_end'] = $wrapPartsBefore[1]; 01859 $this->I['parts']['ATag_end'] = $this->I['A2']; 01860 $this->I['parts']['notATagBeforeWrap_end'] = $wrapPartsAfter[1]; 01861 } 01862 $this->I['parts']['stdWrap2_end']=$wrapPartsStdWrap[1]; 01863 $this->I['parts']['after']=$this->getBeforeAfter('after'); 01864 01865 // Passing I to a user function 01866 if ($this->mconf['IProcFunc']) { 01867 $this->I = $this->userProcess('IProcFunc',$this->I); 01868 } 01869 01870 // Merge parts + beforeAllWrap 01871 $this->I['theItem']= implode('',$this->I['parts']); 01872 $this->I['theItem']= $this->extProc_beforeAllWrap($this->I['theItem'],$key); 01873 01874 // allWrap: 01875 $allWrap = isset($this->I['val']['allWrap.']) 01876 ? $this->WMcObj->stdWrap($this->I['val']['allWrap'], $this->I['val']['allWrap.']) 01877 : $this->I['val']['allWrap']; 01878 $this->I['theItem'] = $this->tmpl->wrap($this->I['theItem'],$allWrap); 01879 01880 if ($this->I['val']['subst_elementUid']) $this->I['theItem'] = str_replace('{elementUid}',$this->I['uid'],$this->I['theItem']); 01881 01882 // allStdWrap: 01883 if (is_array($this->I['val']['allStdWrap.'])) { 01884 $this->I['theItem'] = $this->WMcObj->stdWrap($this->I['theItem'], $this->I['val']['allStdWrap.']); 01885 } 01886 01887 // Calling extra processing function 01888 $this->extProc_afterLinking($key); 01889 } 01890 return $this->extProc_finish(); 01891 } 01892 } 01893 01894 /** 01895 * Generates the before* and after* images for TMENUs 01896 * 01897 * @param string Can be "before" or "after" and determines which kind of image to create (basically this is the prefix of the TypoScript properties that are read from the ->I['val'] array 01898 * @return string The resulting HTML of the image, if any. 01899 */ 01900 function getBeforeAfter($pref) { 01901 $res = ''; 01902 if ($imgInfo = $this->WMcObj->getImgResource($this->I['val'][$pref.'Img'],$this->I['val'][$pref.'Img.'])) { 01903 $imgInfo[3] = t3lib_div::png_to_gif_by_imagemagick($imgInfo[3]); 01904 if ($this->I['val']['RO'] && $this->I['val'][$pref.'ROImg'] && !$this->I['spacer']) { 01905 $imgROInfo = $this->WMcObj->getImgResource($this->I['val'][$pref.'ROImg'],$this->I['val'][$pref.'ROImg.']); 01906 $imgROInfo[3] = t3lib_div::png_to_gif_by_imagemagick($imgROInfo[3]); 01907 if ($imgROInfo) { 01908 $theName = $this->imgNamePrefix.$this->I['uid'].$this->I['INPfix'].$pref; 01909 $name = ' '.$this->nameAttribute.'="'.$theName.'"'; 01910 $GLOBALS['TSFE']->JSImgCode.= LF.$theName.'_n=new Image(); '.$theName.'_n.src = "'.$GLOBALS['TSFE']->absRefPrefix.$imgInfo[3].'"; '; 01911 $GLOBALS['TSFE']->JSImgCode.= LF.$theName.'_h=new Image(); '.$theName.'_h.src = "'.$GLOBALS['TSFE']->absRefPrefix.$imgROInfo[3].'"; '; 01912 } 01913 } 01914 $GLOBALS['TSFE']->imagesOnPage[]=$imgInfo[3]; 01915 $res='<img' . 01916 ' src="' . $GLOBALS['TSFE']->absRefPrefix . $imgInfo[3] . '"' . 01917 ' width="' . $imgInfo[0] . '"' . 01918 ' height="' . $imgInfo[1] . '"' . 01919 $name . 01920 ($this->I['val'][$pref.'ImgTagParams'] ? ' ' . $this->I['val'][$pref.'ImgTagParams'] : '') . 01921 tslib_cObj::getBorderAttr(' border="0"'); 01922 if (!strstr($res,'alt="')) { 01923 $res .= ' alt=""'; // Adding alt attribute if not set. 01924 } 01925 $res.=' />'; 01926 if ($this->I['val'][$pref.'ImgLink']) { 01927 $res=$this->I['A1'].$res.$this->I['A2']; 01928 } 01929 } 01930 $processedPref = isset($this->I['val'][$pref . '.']) 01931 ? $this->WMcObj->stdWrap($this->I['val'][$pref], $this->I['val'][$pref . '.']) 01932 : $this->I['val'][$pref]; 01933 if (isset($this->I['val'][$pref . 'Wrap'])) { 01934 return $this->tmpl->wrap($res . $processedPref, $this->I['val'][$pref . 'Wrap']); 01935 } else { 01936 return $res . $processedPref; 01937 } 01938 } 01939 01940 /** 01941 * Adds a JavaScript function to the $GLOBALS['TSFE']->additionalJavaScript array 01942 * 01943 * @return void 01944 * @access private 01945 * @see writeMenu() 01946 */ 01947 function addJScolorShiftFunction() { 01948 $GLOBALS['TSFE']->additionalJavaScript['TMENU:changeBGcolor()']=' 01949 function changeBGcolor(id,color) { // 01950 if (document.getElementById && document.getElementById(id)) { 01951 document.getElementById(id).style.background = color; 01952 return true; 01953 } else if (document.layers && document.layers[id]) { 01954 document.layers[id].bgColor = color; 01955 return true; 01956 } 01957 } 01958 '; 01959 } 01960 01961 /** 01962 * Called right before the traversing of $this->result begins. 01963 * Can be used for various initialization 01964 * 01965 * @return void 01966 * @access private 01967 * @see writeMenu(), tslib_tmenu_layers::extProc_init() 01968 */ 01969 function extProc_init() { 01970 } 01971 01972 /** 01973 * Called after all processing for RollOver of an element has been done. 01974 * 01975 * @param integer Pointer to $this->menuArr[$key] where the current menu element record is found 01976 * @return void 01977 * @access private 01978 * @see writeMenu(), tslib_tmenu_layers::extProc_RO() 01979 */ 01980 function extProc_RO($key) { 01981 } 01982 01983 /** 01984 * Called right before the creation of the link for the menu item 01985 * 01986 * @param integer Pointer to $this->menuArr[$key] where the current menu element record is found 01987 * @return void 01988 * @access private 01989 * @see writeMenu(), tslib_tmenu_layers::extProc_beforeLinking() 01990 */ 01991 function extProc_beforeLinking($key) { 01992 } 01993 01994 /** 01995 * Called right after the creation of links for the menu item. This is also the last function call before the while-loop traversing menu items goes to the next item. 01996 * This function MUST set $this->WMresult.=[HTML for menu item] to add the generated menu item to the internal accumulation of items. 01997 * 01998 * @param integer Pointer to $this->menuArr[$key] where the current menu element record is found 01999 * @return void 02000 * @access private 02001 * @see writeMenu(), tslib_tmenu_layers::extProc_afterLinking() 02002 */ 02003 function extProc_afterLinking($key) { 02004 // Add part to the accumulated result + fetch submenus 02005 if (!$this->I['spacer']) { 02006 $this->I['theItem'].= $this->subMenu($this->I['uid'], $this->WMsubmenuObjSuffixes[$key]['sOSuffix']); 02007 } 02008 $part = isset($this->I['val']['wrapItemAndSub.']) 02009 ? $this->WMcObj->stdWrap($this->I['val']['wrapItemAndSub'], $this->I['val']['wrapItemAndSub.']) 02010 : $this->I['val']['wrapItemAndSub']; 02011 $this->WMresult.= $part ? $this->tmpl->wrap($this->I['theItem'],$part) : $this->I['theItem']; 02012 } 02013 02014 /** 02015 * Called before the "allWrap" happens on the menu item. 02016 * 02017 * @param string The current content of the menu item, $this->I['theItem'], passed along. 02018 * @param integer Pointer to $this->menuArr[$key] where the current menu element record is found 02019 * @return string The modified version of $item, going back into $this->I['theItem'] 02020 * @access private 02021 * @see writeMenu(), tslib_tmenu_layers::extProc_beforeAllWrap() 02022 */ 02023 function extProc_beforeAllWrap($item,$key) { 02024 return $item; 02025 } 02026 02027 /** 02028 * Called before the writeMenu() function returns (only if a menu was generated) 02029 * 02030 * @return string The total menu content should be returned by this function 02031 * @access private 02032 * @see writeMenu(), tslib_tmenu_layers::extProc_finish() 02033 */ 02034 function extProc_finish() { 02035 // stdWrap: 02036 if (is_array($this->mconf['stdWrap.'])) { 02037 $this->WMresult = $this->WMcObj->stdWrap($this->WMresult, $this->mconf['stdWrap.']); 02038 } 02039 return $this->tmpl->wrap($this->WMresult,$this->mconf['wrap']).$this->WMextraScript; 02040 } 02041 } 02042 02043 02044 02045 02046 02047 02048 02049 02050 02051 02052 02053 02054 02055 02056 02057 02058 02059 02060 02061 02062 02063 02064 02065 02066 /** 02067 * Extension class creating graphic based menus (PNG or GIF files) 02068 * 02069 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 02070 * @package TYPO3 02071 * @subpackage tslib 02072 */ 02073 class tslib_gmenu extends tslib_menu { 02074 02075 /** 02076 * Calls procesItemStates() so that the common configuration for the menu items are resolved into individual configuration per item. 02077 * Calls makeGifs() for all "normal" items and if configured for, also the "rollover" items. 02078 * 02079 * @return void 02080 * @see tslib_menu::procesItemStates(), makeGifs() 02081 */ 02082 function generate() { 02083 $splitCount = count($this->menuArr); 02084 if ($splitCount) { 02085 list($NOconf,$ROconf) = $this->procesItemStates($splitCount); 02086 02087 //store initial count value 02088 $temp_HMENU_MENUOBJ = $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ']; 02089 $temp_MENUOBJ = $GLOBALS['TSFE']->register['count_MENUOBJ']; 02090 // Now we generate the giffiles: 02091 $this->makeGifs($NOconf,'NO'); 02092 // store count from NO obj 02093 $tempcnt_HMENU_MENUOBJ = $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ']; 02094 $tempcnt_MENUOBJ = $GLOBALS['TSFE']->register['count_MENUOBJ']; 02095 02096 if ($this->mconf['debugItemConf']) {echo '<h3>$NOconf:</h3>'; debug($NOconf); } 02097 if ($ROconf) { // RollOver 02098 //start recount for rollover with initial values 02099 $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ']= $temp_HMENU_MENUOBJ; 02100 $GLOBALS['TSFE']->register['count_MENUOBJ']= $temp_MENUOBJ; 02101 $this->makeGifs($ROconf,'RO'); 02102 if ($this->mconf['debugItemConf']) {echo '<h3>$ROconf:</h3>'; debug($ROconf); } 02103 } 02104 // use count from NO obj 02105 $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ'] = $tempcnt_HMENU_MENUOBJ; 02106 $GLOBALS['TSFE']->register['count_MENUOBJ'] = $tempcnt_MENUOBJ; 02107 } 02108 } 02109 02110 /** 02111 * Will traverse input array with configuratoin per-item and create corresponding GIF files for the menu. 02112 * The data of the files are stored in $this->result 02113 * 02114 * @param array Array with configuration for each item. 02115 * @param string Type of images: normal ("NO") or rollover ("RO"). Valid values are "NO" and "RO" 02116 * @return void 02117 * @access private 02118 * @see generate() 02119 */ 02120 function makeGifs($conf, $resKey) { 02121 $isGD = $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']; 02122 02123 if (!is_array($conf)) { 02124 $conf = Array(); 02125 } 02126 02127 $totalWH=array(); 02128 $items = count($conf); 02129 if ($isGD) { 02130 // generate the gif-files. the $menuArr is filled with some values like output_w, output_h, output_file 02131 $Hcounter = 0; 02132 $Wcounter = 0; 02133 $Hobjs = $this->mconf['applyTotalH']; 02134 if ($Hobjs) {$Hobjs = t3lib_div::intExplode(',',$Hobjs);} 02135 $Wobjs = $this->mconf['applyTotalW']; 02136 if ($Wobjs) {$Wobjs = t3lib_div::intExplode(',',$Wobjs);} 02137 $minDim = $this->mconf['min']; 02138 if ($minDim) {$minDim = tslib_cObj::calcIntExplode(',',$minDim.',');} 02139 $maxDim = $this->mconf['max']; 02140 if ($maxDim) {$maxDim = tslib_cObj::calcIntExplode(',',$maxDim.',');} 02141 02142 if ($minDim) { 02143 $conf[$items]=$conf[$items-1]; 02144 $this->menuArr[$items]=Array(); 02145 $items = count($conf); 02146 } 02147 02148 // TOTAL width 02149 if ($this->mconf['useLargestItemX'] || $this->mconf['useLargestItemY'] || $this->mconf['distributeX'] || $this->mconf['distributeY']) { 02150 $totalWH = $this->findLargestDims($conf,$items,$Hobjs,$Wobjs,$minDim,$maxDim); 02151 } 02152 } 02153 02154 $c=0; 02155 $maxFlag=0; 02156 $distributeAccu=array('H'=>0,'W'=>0); 02157 foreach ($conf as $key => $val) { 02158 $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ']++; 02159 $GLOBALS['TSFE']->register['count_MENUOBJ']++; 02160 02161 if ($items==($c+1) && $minDim) { 02162 $Lobjs = $this->mconf['removeObjectsOfDummy']; 02163 if ($Lobjs) { 02164 $Lobjs = t3lib_div::intExplode(',',$Lobjs); 02165 foreach ($Lobjs as $remItem) { 02166 unset($val[$remItem]); 02167 unset($val[$remItem.'.']); 02168 } 02169 } 02170 02171 $flag =0; 02172 $tempXY = explode(',',$val['XY']); 02173 if ($Wcounter<$minDim[0]) {$tempXY[0]=$minDim[0]-$Wcounter; $flag=1;} 02174 if ($Hcounter<$minDim[1]) {$tempXY[1]=$minDim[1]-$Hcounter; $flag=1;} 02175 $val['XY'] = implode(',',$tempXY); 02176 if (!$flag){break;} 02177 } 02178 $c++; 02179 02180 02181 if ($isGD) { 02182 // Pre-working the item 02183 $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder'); 02184 $gifCreator->init(); 02185 $gifCreator->start($val,$this->menuArr[$key]); 02186 02187 // If useLargestItemH/W is specified 02188 if (count($totalWH) && ($this->mconf['useLargestItemX'] || $this->mconf['useLargestItemY'])) { 02189 $tempXY = explode(',',$gifCreator->setup['XY']); 02190 if ($this->mconf['useLargestItemX']) {$tempXY[0] = max($totalWH['W']);} 02191 if ($this->mconf['useLargestItemY']) {$tempXY[1] = max($totalWH['H']);} 02192 // regenerate the new values... 02193 $val['XY'] = implode(',',$tempXY); 02194 $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder'); 02195 $gifCreator->init(); 02196 $gifCreator->start($val,$this->menuArr[$key]); 02197 } 02198 02199 // If distributeH/W is specified 02200 if (count($totalWH) && ($this->mconf['distributeX'] || $this->mconf['distributeY'])) { 02201 $tempXY = explode(',',$gifCreator->setup['XY']); 02202 02203 if ($this->mconf['distributeX']) { 02204 $diff = $this->mconf['distributeX']-$totalWH['W_total']-$distributeAccu['W']; 02205 $compensate = round($diff /($items-$c+1)); 02206 $distributeAccu['W']+=$compensate; 02207 $tempXY[0] = $totalWH['W'][$key]+$compensate; 02208 } 02209 if ($this->mconf['distributeY']) { 02210 $diff = $this->mconf['distributeY']-$totalWH['H_total']-$distributeAccu['H']; 02211 $compensate = round($diff /($items-$c+1)); 02212 $distributeAccu['H']+=$compensate; 02213 $tempXY[1] = $totalWH['H'][$key]+$compensate; 02214 } 02215 // regenerate the new values... 02216 $val['XY'] = implode(',',$tempXY); 02217 $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder'); 02218 $gifCreator->init(); 02219 $gifCreator->start($val,$this->menuArr[$key]); 02220 } 02221 02222 // If max dimensions are specified 02223 if ($maxDim) { 02224 $tempXY = explode(',',$val['XY']); 02225 if ($maxDim[0] && $Wcounter+$gifCreator->XY[0]>=$maxDim[0]) {$tempXY[0]==$maxDim[0]-$Wcounter; $maxFlag=1;} 02226 if ($maxDim[1] && $Hcounter+$gifCreator->XY[1]>=$maxDim[1]) {$tempXY[1]=$maxDim[1]-$Hcounter; $maxFlag=1;} 02227 if ($maxFlag) { 02228 $val['XY'] = implode(',',$tempXY); 02229 $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder'); 02230 $gifCreator->init(); 02231 $gifCreator->start($val,$this->menuArr[$key]); 02232 } 02233 } 02234 02235 02236 02237 02238 // displace 02239 if ($Hobjs) { 02240 foreach ($Hobjs as $index) { 02241 if ($gifCreator->setup[$index] && $gifCreator->setup[$index.'.']) { 02242 $oldOffset = explode(',',$gifCreator->setup[$index.'.']['offset']); 02243 $gifCreator->setup[$index.'.']['offset'] = implode(',',$gifCreator->applyOffset($oldOffset,Array(0,-$Hcounter))); 02244 } 02245 } 02246 } 02247 02248 if ($Wobjs) { 02249 foreach ($Wobjs as $index) { 02250 if ($gifCreator->setup[$index] && $gifCreator->setup[$index.'.']) { 02251 $oldOffset = explode(',',$gifCreator->setup[$index.'.']['offset']); 02252 $gifCreator->setup[$index.'.']['offset'] = implode(',',$gifCreator->applyOffset($oldOffset,Array(-$Wcounter,0))); 02253 } 02254 } 02255 } 02256 } 02257 02258 // Finding alternative GIF names if any (by altImgResource) 02259 $gifFileName=''; 02260 if ($conf[$key]['altImgResource'] || is_array($conf[$key]['altImgResource.'])) { 02261 if (!is_object($cObj)) {$cObj=t3lib_div::makeInstance('tslib_cObj');} 02262 $cObj->start($this->menuArr[$key],'pages'); 02263 $altImgInfo = $cObj->getImgResource($conf[$key]['altImgResource'],$conf[$key]['altImgResource.']); 02264 $gifFileName=$altImgInfo[3]; 02265 } 02266 02267 // If an alternative name was NOT given, find the GIFBUILDER name. 02268 if (!$gifFileName && $isGD) { 02269 $gifCreator->createTempSubDir('menu/'); 02270 $gifFileName = $gifCreator->fileName('menu/'); 02271 } 02272 02273 $this->result[$resKey][$key] = $conf[$key]; 02274 02275 // Generation of image file: 02276 if (file_exists($gifFileName)) { // File exists 02277 $info = @getimagesize($gifFileName); 02278 $this->result[$resKey][$key]['output_w']=intval($info[0]); 02279 $this->result[$resKey][$key]['output_h']=intval($info[1]); 02280 $this->result[$resKey][$key]['output_file'] = $gifFileName; 02281 } elseif ($isGD) { // file is generated 02282 $gifCreator->make(); 02283 $this->result[$resKey][$key]['output_w']=$gifCreator->w; 02284 $this->result[$resKey][$key]['output_h']=$gifCreator->h; 02285 $this->result[$resKey][$key]['output_file'] = $gifFileName; 02286 $gifCreator->output($this->result[$resKey][$key]['output_file']); 02287 $gifCreator->destroy(); 02288 } 02289 02290 $this->result[$resKey][$key]['output_file'] = t3lib_div::png_to_gif_by_imagemagick($this->result[$resKey][$key]['output_file']); 02291 02292 $Hcounter+=$this->result[$resKey][$key]['output_h']; // counter is increased 02293 $Wcounter+=$this->result[$resKey][$key]['output_w']; // counter is increased 02294 02295 if ($maxFlag) break; 02296 } 02297 } 02298 02299 /** 02300 * Function searching for the largest width and height of the menu items to be generated. 02301 * Uses some of the same code as makeGifs and even instantiates some gifbuilder objects BUT does not render the images - only reading out which width they would have. 02302 * Remember to upgrade the code in here if the makeGifs function is updated. 02303 * 02304 * @param array Same configuration array as passed to makeGifs() 02305 * @param integer The number of menu items 02306 * @param array Array with "applyTotalH" numbers 02307 * @param array Array with "applyTotalW" numbers 02308 * @param array Array with "min" x/y 02309 * @param array Array with "max" x/y 02310 * @return array Array with keys "H" and "W" which are in themselves arrays with the heights and widths of menu items inside. This can be used to find the max/min size of the menu items. 02311 * @access private 02312 * @see makeGifs() 02313 */ 02314 function findLargestDims($conf,$items,$Hobjs,$Wobjs,$minDim,$maxDim) { 02315 $totalWH = array( 02316 'W' => array(), 02317 'H' => array(), 02318 'W_total' => 0, 02319 'H_total' => 0 02320 ); 02321 02322 $Hcounter = 0; 02323 $Wcounter = 0; 02324 $c=0; 02325 $maxFlag=0; 02326 foreach ($conf as $key => $val) { 02327 // SAME CODE AS makeGifs()! BEGIN 02328 if ($items==($c+1) && $minDim) { 02329 $Lobjs = $this->mconf['removeObjectsOfDummy']; 02330 if ($Lobjs) { 02331 $Lobjs = t3lib_div::intExplode(',',$Lobjs); 02332 foreach ($Lobjs as $remItem) { 02333 unset($val[$remItem]); 02334 unset($val[$remItem.'.']); 02335 } 02336 } 02337 02338 $flag =0; 02339 $tempXY = explode(',',$val['XY']); 02340 if ($Wcounter<$minDim[0]) {$tempXY[0]=$minDim[0]-$Wcounter; $flag=1;} 02341 if ($Hcounter<$minDim[1]) {$tempXY[1]=$minDim[1]-$Hcounter; $flag=1;} 02342 $val['XY'] = implode(',',$tempXY); 02343 if (!$flag){break;} 02344 } 02345 $c++; 02346 02347 $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder'); 02348 $gifCreator->init(); 02349 $gifCreator->start($val,$this->menuArr[$key]); 02350 if ($maxDim) { 02351 $tempXY = explode(',',$val['XY']); 02352 if ($maxDim[0] && $Wcounter+$gifCreator->XY[0]>=$maxDim[0]) {$tempXY[0]==$maxDim[0]-$Wcounter; $maxFlag=1;} 02353 if ($maxDim[1] && $Hcounter+$gifCreator->XY[1]>=$maxDim[1]) {$tempXY[1]=$maxDim[1]-$Hcounter; $maxFlag=1;} 02354 if ($maxFlag) { 02355 $val['XY'] = implode(',',$tempXY); 02356 $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder'); 02357 $gifCreator->init(); 02358 $gifCreator->start($val,$this->menuArr[$key]); 02359 } 02360 } 02361 // SAME CODE AS makeGifs()! END 02362 02363 // Setting the width/height 02364 $totalWH['W'][$key]=$gifCreator->XY[0]; 02365 $totalWH['H'][$key]=$gifCreator->XY[1]; 02366 $totalWH['W_total']+=$gifCreator->XY[0]; 02367 $totalWH['H_total']+=$gifCreator->XY[1]; 02368 // ---- // 02369 02370 $Hcounter+=$gifCreator->XY[1]; // counter is increased 02371 $Wcounter+=$gifCreator->XY[0]; // counter is increased 02372 02373 if ($maxFlag){break;} 02374 } 02375 return $totalWH; 02376 } 02377 02378 /** 02379 * Traverses the ->result['NO'] array of menu items configuration (made by ->generate()) and renders the HTML of each item (the images themselves was made with makeGifs() before this. See ->generate()) 02380 * During the execution of this function many internal methods prefixed "extProc_" from this class is called and many of these are for now dummy functions. But they can be used for processing as they are used by the GMENU_LAYERS 02381 * 02382 * @return string The HTML for the menu (returns result through $this->extProc_finish(); ) 02383 */ 02384 function writeMenu() { 02385 if (is_array($this->menuArr) && is_array($this->result) && count($this->result) && is_array($this->result['NO'])) { 02386 $this->WMcObj = t3lib_div::makeInstance('tslib_cObj'); // Create new tslib_cObj for our use 02387 $this->WMresult = ''; 02388 $this->INPfixMD5 = substr(md5(microtime().$this->GMENU_fixKey),0,4); 02389 $this->WMmenuItems = count($this->result['NO']); 02390 02391 $this->WMsubmenuObjSuffixes = $this->tmpl->splitConfArray(array('sOSuffix'=>$this->mconf['submenuObjSuffixes']),$this->WMmenuItems); 02392 02393 $this->extProc_init(); 02394 for ($key=0;$key<$this->WMmenuItems;$key++) { 02395 if ($this->result['NO'][$key]['output_file']) { 02396 $this->WMcObj->start($this->menuArr[$key],'pages'); // Initialize the cObj with the page record of the menu item 02397 02398 $this->I = array(); 02399 $this->I['key'] = $key; 02400 $this->I['INPfix']= ($this->imgNameNotRandom ? '' : '_'.$this->INPfixMD5).'_'.$key; 02401 $this->I['val'] = $this->result['NO'][$key]; 02402 $this->I['title'] = $this->getPageTitle($this->menuArr[$key]['title'],$this->menuArr[$key]['nav_title']); 02403 $this->I['uid'] = $this->menuArr[$key]['uid']; 02404 $this->I['mount_pid'] = $this->menuArr[$key]['mount_pid']; 02405 $this->I['pid'] = $this->menuArr[$key]['pid']; 02406 $this->I['spacer'] = $this->menuArr[$key]['isSpacer']; 02407 if (!$this->I['uid'] && !$this->menuArr[$key]['_OVERRIDE_HREF']) {$this->I['spacer']=1;} 02408 $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 02409 $this->I['name'] = ''; 02410 02411 // Set access key 02412 if ($this->mconf['accessKey']) { 02413 $this->I['accessKey'] = $this->accessKey($this->I['title']); 02414 } else { 02415 $this->I['accessKey'] = array(); 02416 } 02417 02418 // Make link tag 02419 $this->I['val']['ATagParams'] = $this->WMcObj->getATagParams($this->I['val']); 02420 if (isset($this->I['val']['additionalParams.'])) { 02421 $this->I['val']['additionalParams'] = $this->WMcObj->stdWrap($this->I['val']['additionalParams'], $this->I['val']['additionalParams.']); 02422 } 02423 $this->I['linkHREF'] = $this->link($key,$this->I['val']['altTarget'],$this->mconf['forceTypeValue']); 02424 02425 // Title attribute of links: 02426 $titleAttrValue = isset($this->I['val']['ATagTitle.']) 02427 ? $this->WMcObj->stdWrap($this->I['val']['ATagTitle'], $this->I['val']['ATagTitle.']) . $this->I['accessKey']['alt'] 02428 : $this->I['val']['ATagTitle'].$this->I['accessKey']['alt']; 02429 if (strlen($titleAttrValue)) { 02430 $this->I['linkHREF']['title'] = $titleAttrValue; 02431 } 02432 // Setting "blurlink()" function: 02433 if (!$this->mconf['noBlur']) { 02434 $this->I['linkHREF']['onFocus']='blurLink(this);'; 02435 } 02436 02437 // Set rollover 02438 if ($this->result['RO'][$key] && !$this->I['noLink']) { 02439 $this->I['theName'] = $this->imgNamePrefix.$this->I['uid'].$this->I['INPfix']; 02440 $this->I['name'] = ' '.$this->nameAttribute.'="'.$this->I["theName"].'"'; 02441 $this->I['linkHREF']['onMouseover']=$this->WMfreezePrefix.'over(\''.$this->I['theName'].'\');'; 02442 $this->I['linkHREF']['onMouseout']=$this->WMfreezePrefix.'out(\''.$this->I['theName'].'\');'; 02443 $GLOBALS['TSFE']->JSImgCode.= LF.$this->I['theName'].'_n=new Image(); '.$this->I['theName'].'_n.src = "'.$GLOBALS['TSFE']->absRefPrefix.$this->I['val']['output_file'].'"; '; 02444 $GLOBALS['TSFE']->JSImgCode.= LF.$this->I['theName'].'_h=new Image(); '.$this->I['theName'].'_h.src = "'.$GLOBALS['TSFE']->absRefPrefix.$this->result['RO'][$key]['output_file'].'"; '; 02445 $GLOBALS['TSFE']->imagesOnPage[]=$this->result['RO'][$key]['output_file']; 02446 $GLOBALS['TSFE']->setJS('mouseOver'); 02447 $this->extProc_RO($key); 02448 } 02449 02450 // Set altText 02451 $this->I['altText'] = $this->I['title'].$this->I['accessKey']['alt']; 02452 02453 // Calling extra processing function 02454 $this->extProc_beforeLinking($key); 02455 02456 // Set linking 02457 if (!$this->I['noLink']) { 02458 $this->setATagParts(); 02459 } else { 02460 $this->I['A1'] = ''; 02461 $this->I['A2'] = ''; 02462 } 02463 $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']:'').' />'; 02464 02465 // Make before, middle and after parts 02466 $this->I['parts'] = array(); 02467 $this->I['parts']['ATag_begin'] = $this->I['A1']; 02468 $this->I['parts']['image'] = $this->I['IMG']; 02469 $this->I['parts']['ATag_end'] = $this->I['A2']; 02470 02471 // Passing I to a user function 02472 if ($this->mconf['IProcFunc']) { 02473 $this->I = $this->userProcess('IProcFunc',$this->I); 02474 } 02475 02476 // Putting the item together. 02477 // Merge parts + beforeAllWrap 02478 $this->I['theItem']= implode('',$this->I['parts']); 02479 $this->I['theItem']= $this->extProc_beforeAllWrap($this->I['theItem'],$key); 02480 02481 // wrap: 02482 $this->I['theItem']= $this->tmpl->wrap($this->I['theItem'],$this->I['val']['wrap']); 02483 02484 // allWrap: 02485 $allWrap = isset($this->I['val']['allWrap.']) 02486 ? $this->WMcObj->stdWrap($this->I['val']['allWrap'], $this->I['val']['allWrap.']) 02487 : $this->I['val']['allWrap']; 02488 $this->I['theItem'] = $this->tmpl->wrap($this->I['theItem'],$allWrap); 02489 02490 if ($this->I['val']['subst_elementUid']) $this->I['theItem'] = str_replace('{elementUid}',$this->I['uid'],$this->I['theItem']); 02491 02492 // allStdWrap: 02493 if (is_array($this->I['val']['allStdWrap.'])) { 02494 $this->I['theItem'] = $this->WMcObj->stdWrap($this->I['theItem'], $this->I['val']['allStdWrap.']); 02495 } 02496 02497 $GLOBALS['TSFE']->imagesOnPage[]=$this->I['val']['output_file']; 02498 02499 $this->extProc_afterLinking($key); 02500 } 02501 } 02502 return $this->extProc_finish(); 02503 } 02504 } 02505 02506 /** 02507 * Called right before the traversing of $this->result begins. 02508 * Can be used for various initialization 02509 * 02510 * @return void 02511 * @access private 02512 * @see writeMenu(), tslib_gmenu_layers::extProc_init() 02513 */ 02514 function extProc_init() { 02515 } 02516 02517 /** 02518 * Called after all processing for RollOver of an element has been done. 02519 * 02520 * @param integer Pointer to $this->menuArr[$key] where the current menu element record is found OR $this->result['RO'][$key] where the configuration for that elements RO version is found! 02521 * @return void 02522 * @access private 02523 * @see writeMenu(), tslib_gmenu_layers::extProc_RO() 02524 */ 02525 function extProc_RO($key) { 02526 } 02527 02528 /** 02529 * Called right before the creation of the link for the menu item 02530 * 02531 * @param integer Pointer to $this->menuArr[$key] where the current menu element record is found 02532 * @return void 02533 * @access private 02534 * @see writeMenu(), tslib_gmenu_layers::extProc_beforeLinking() 02535 */ 02536 function extProc_beforeLinking($key) { 02537 } 02538 02539 /** 02540 * Called right after the creation of links for the menu item. This is also the last function call before the for-loop traversing menu items goes to the next item. 02541 * This function MUST set $this->WMresult.=[HTML for menu item] to add the generated menu item to the internal accumulation of items. 02542 * Further this calls the subMenu function in the parent class to create any submenu there might be. 02543 * 02544 * @param integer Pointer to $this->menuArr[$key] where the current menu element record is found 02545 * @return void 02546 * @access private 02547 * @see writeMenu(), tslib_gmenu_layers::extProc_afterLinking(), tslib_menu::subMenu() 02548 */ 02549 function extProc_afterLinking($key) { 02550 // Add part to the accumulated result + fetch submenus 02551 if (!$this->I['spacer']) { 02552 $this->I['theItem'].= $this->subMenu($this->I['uid'], $this->WMsubmenuObjSuffixes[$key]['sOSuffix']); 02553 } 02554 $part = isset($this->I['val']['wrapItemAndSub.']) 02555 ? $this->WMcObj->stdWrap($this->I['val']['wrapItemAndSub'], $this->I['val']['wrapItemAndSub.']) 02556 : $this->I['val']['wrapItemAndSub']; 02557 $this->WMresult.= $part ? $this->tmpl->wrap($this->I['theItem'],$part) : $this->I['theItem']; 02558 } 02559 02560 02561 /** 02562 * Called before the "wrap" happens on the menu item. 02563 * 02564 * @param string The current content of the menu item, $this->I['theItem'], passed along. 02565 * @param integer Pointer to $this->menuArr[$key] where the current menu element record is found 02566 * @return string The modified version of $item, going back into $this->I['theItem'] 02567 * @access private 02568 * @see writeMenu(), tslib_gmenu_layers::extProc_beforeAllWrap() 02569 */ 02570 function extProc_beforeAllWrap($item,$key) { 02571 return $item; 02572 } 02573 02574 /** 02575 * Called before the writeMenu() function returns (only if a menu was generated) 02576 * 02577 * @return string The total menu content should be returned by this function 02578 * @access private 02579 * @see writeMenu(), tslib_gmenu_layers::extProc_finish() 02580 */ 02581 function extProc_finish() { 02582 // stdWrap: 02583 if (is_array($this->mconf['stdWrap.'])) { 02584 $this->WMresult = $this->WMcObj->stdWrap($this->WMresult, $this->mconf['stdWrap.']); 02585 } 02586 return $this->tmpl->wrap($this->WMresult,$this->mconf['wrap']).$this->WMextraScript; 02587 } 02588 } 02589 02590 02591 02592 02593 02594 02595 02596 02597 02598 02599 02600 02601 02602 02603 02604 02605 02606 02607 02608 02609 02610 02611 /** 02612 * ImageMap based menus 02613 * 02614 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 02615 * @package TYPO3 02616 * @subpackage tslib 02617 */ 02618 class tslib_imgmenu extends tslib_menu { 02619 02620 /** 02621 * Calls procesItemStates() so that the common configuration for the menu items are resolved into individual configuration per item. 02622 * Calls makeImageMap() to generate the image map image-file 02623 * 02624 * @return void 02625 * @see tslib_menu::procesItemStates(), makeImageMap() 02626 */ 02627 function generate() { 02628 $splitCount = count($this->menuArr); 02629 if ($splitCount) { 02630 list($NOconf) = $this->procesItemStates($splitCount); 02631 } 02632 if ($this->mconf['debugItemConf']) {echo '<h3>$NOconf:</h3>'; debug($NOconf); } 02633 $this->makeImageMap($NOconf); 02634 } 02635 02636 /** 02637 * Will traverse input array with configuratoin per-item and create corresponding GIF files for the menu. 02638 * The data of the files are stored in $this->result 02639 * 02640 * @param array Array with configuration for each item. 02641 * @return void 02642 * @access private 02643 * @see generate() 02644 */ 02645 function makeImageMap($conf) { 02646 if (!is_array($conf)) { 02647 $conf = Array(); 02648 } 02649 if (is_array($this->mconf['main.'])) { 02650 $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder'); 02651 $gifCreator->init(); 02652 02653 $itemsConf = $conf; 02654 $conf = $this->mconf['main.']; 02655 if (is_array($conf)) { 02656 $gifObjCount = 0; 02657 02658 $sKeyArray=t3lib_TStemplate::sortedKeyList($conf); 02659 $gifObjCount=intval(end($sKeyArray)); 02660 02661 $lastOriginal = $gifObjCount; 02662 02663 // Now we add graphical objects to the gifbuilder-setup 02664 $waArr = Array(); 02665 foreach ($itemsConf as $key => $val) { 02666 if (is_array($val)) { 02667 $gifObjCount++; 02668 $waArr[$key]['free']=$gifObjCount; 02669 02670 $sKeyArray=t3lib_TStemplate::sortedKeyList($val); 02671 02672 foreach($sKeyArray as $theKey) { 02673 $theValue=$val[$theKey]; 02674 02675 02676 if (intval($theKey) && $theValArr=$val[$theKey.'.']) { 02677 $cObjData = $this->menuArr[$key] ? $this->menuArr[$key] : Array(); 02678 02679 $gifObjCount++; 02680 if ($theValue=='TEXT') { 02681 $waArr[$key]['textNum']=$gifObjCount; 02682 02683 $gifCreator->data = $cObjData; 02684 $theValArr = $gifCreator->checkTextObj($theValArr); 02685 unset($theValArr['text.']); // if this is not done it seems that imageMaps will be rendered wrong!! 02686 // check links 02687 02688 $LD = $this->menuTypoLink($this->menuArr[$key],$this->mconf['target'],'','',array(),'',$this->mconf['forceTypeValue']); 02689 02690 // If access restricted pages should be shown in menus, change the link of such pages to link to a redirection page: 02691 $this->changeLinksForAccessRestrictedPages($LD, $this->menuArr[$key], $this->mconf['target'], $this->mconf['forceTypeValue']); 02692 02693 // Overriding URL / Target if set to do so: 02694 if ($this->menuArr[$key]['_OVERRIDE_HREF']) { 02695 $LD['totalURL'] = $this->menuArr[$key]['_OVERRIDE_HREF']; 02696 if ($this->menuArr[$key]['_OVERRIDE_TARGET']) $LD['target'] = $this->menuArr[$key]['_OVERRIDE_TARGET']; 02697 } 02698 02699 // Setting target/url for Image Map: 02700 if ($theValArr['imgMap.']['url']=='') { 02701 $theValArr['imgMap.']['url'] = $LD['totalURL']; 02702 } 02703 if ($theValArr['imgMap.']['target']=='') { 02704 $theValArr['imgMap.']['target'] = $LD['target']; 02705 } 02706 if ($theValArr['imgMap.']['noBlur']=='') { 02707 $theValArr['imgMap.']['noBlur'] = $this->mconf['noBlur']; 02708 } 02709 if (is_array($theValArr['imgMap.']['altText.'])) { 02710 $cObj =t3lib_div::makeInstance('tslib_cObj'); 02711 $cObj->start($cObjData,'pages'); 02712 if(isset($theValArr['imgMap.']['altText.'])) { 02713 $theValArr['imgMap.']['altText'] = $cObj->stdWrap($theValArr['imgMap.']['altText'], $theValArr['imgMap.']['altText.']); 02714 } 02715 unset($theValArr['imgMap.']['altText.']); 02716 } 02717 if (is_array($theValArr['imgMap.']['titleText.'])) { 02718 $cObj =t3lib_div::makeInstance('tslib_cObj'); 02719 $cObj->start($cObjData,'pages'); 02720 if(isset($theValArr['imgMap.']['titleText.'])) { 02721 $theValArr['imgMap.']['titleText'] = $cObj->stdWrap($theValArr['imgMap.']['titleText'], $theValArr['imgMap.']['titleText.']); 02722 } 02723 unset($theValArr['imgMap.']['titleText.']); 02724 } 02725 } 02726 // This code goes one level in if the object is an image. If 'file' and/or 'mask' appears to be GIFBUILDER-objects, they are both searched for TEXT objects, and if a textobj is found, it's checked with the currently loaded record!! 02727 if ($theValue=='IMAGE') { 02728 if ($theValArr['file']=='GIFBUILDER') { 02729 $temp_sKeyArray=t3lib_TStemplate::sortedKeyList($theValArr['file.']); 02730 foreach ($temp_sKeyArray as $temp_theKey) { 02731 if ($theValArr['mask.'][$temp_theKey]=='TEXT') { 02732 $gifCreator->data = $this->menuArr[$key] ? $this->menuArr[$key] : Array(); 02733 $theValArr['mask.'][$temp_theKey.'.'] = $gifCreator->checkTextObj($theValArr['mask.'][$temp_theKey.'.']); 02734 unset($theValArr['mask.'][$temp_theKey.'.']['text.']); // if this is not done it seems that imageMaps will be rendered wrong!! 02735 } 02736 } 02737 } 02738 if ($theValArr['mask']=='GIFBUILDER') { 02739 $temp_sKeyArray=t3lib_TStemplate::sortedKeyList($theValArr['mask.']); 02740 foreach ($temp_sKeyArray as $temp_theKey) { 02741 if ($theValArr['mask.'][$temp_theKey]=='TEXT') { 02742 $gifCreator->data = $this->menuArr[$key] ? $this->menuArr[$key] : Array(); 02743 $theValArr['mask.'][$temp_theKey.'.'] = $gifCreator->checkTextObj($theValArr['mask.'][$temp_theKey.'.']); 02744 unset($theValArr['mask.'][$temp_theKey.'.']['text.']); // if this is not done it seems that imageMaps will be rendered wrong!! 02745 } 02746 } 02747 } 02748 } 02749 02750 // Checks if disabled is set... 02751 $setObjFlag=1; 02752 if ($theValArr['if.']) { 02753 $cObj =t3lib_div::makeInstance('tslib_cObj'); 02754 $cObj->start($cObjData,'pages'); 02755 if (!$cObj->checkIf($theValArr['if.'])) { 02756 $setObjFlag=0; 02757 } 02758 unset($theValArr['if.']); 02759 } 02760 // Set the object! 02761 if ($setObjFlag) { 02762 $conf[$gifObjCount] = $theValue; 02763 $conf[$gifObjCount.'.'] = $theValArr; 02764 } 02765 } 02766 } 02767 } 02768 } 02769 02770 $gifCreator->start($conf,$GLOBALS['TSFE']->page); 02771 // calculations 02772 02773 $sum=Array(0,0,0,0); 02774 foreach ($waArr as $key => $val) { 02775 if (($dConf[$key] = $itemsConf[$key]['distrib'])) { 02776 $textBB = $gifCreator->objBB[$val['textNum']]; 02777 $dConf[$key] = str_replace('textX',$textBB[0],$dConf[$key]); 02778 $dConf[$key] = str_replace('textY',$textBB[1],$dConf[$key]); 02779 $dConf[$key] = t3lib_div::intExplode(',',$gifCreator->calcOffset($dConf[$key])); 02780 } 02781 } 02782 $workArea = t3lib_div::intExplode(',',$gifCreator->calcOffset($this->mconf['dWorkArea'])); 02783 foreach ($waArr as $key => $val) { 02784 $index = $val['free']; 02785 $gifCreator->setup[$index] = 'WORKAREA'; 02786 $workArea[2] = $dConf[$key][2] ? $dConf[$key][2] : $dConf[$key][0]; 02787 $workArea[3] = $dConf[$key][3] ? $dConf[$key][3] : $dConf[$key][1]; 02788 02789 $gifCreator->setup[$index.'.']['set'] = implode(',',$workArea); 02790 $workArea[0]+=$dConf[$key][0]; 02791 $workArea[1]+=$dConf[$key][1]; 02792 } 02793 02794 if ($this->mconf['debugRenumberedObject']) {echo '<h3>Renumbered GIFBUILDER object:</h3>'; debug($gifCreator->setup);} 02795 02796 $gifCreator->createTempSubDir('menu/'); 02797 $gifFileName = $gifCreator->fileName('menu/'); 02798 02799 // Gets the ImageMap from the cache... 02800 $imgHash = md5($gifFileName); 02801 $imgMap = $this->sys_page->getHash($imgHash); 02802 02803 if ($imgMap && file_exists($gifFileName)) { // File exists 02804 $info = @getimagesize($gifFileName); 02805 $w=$info[0]; 02806 $h=$info[1]; 02807 } else { // file is generated 02808 $gifCreator->make(); 02809 $w=$gifCreator->w; 02810 $h=$gifCreator->h; 02811 $gifCreator->output($gifFileName); 02812 $gifCreator->destroy(); 02813 $imgMap=$gifCreator->map; 02814 $this->sys_page->storeHash($imgHash, $imgMap, 'MENUIMAGEMAP'); 02815 } 02816 $imgMap.=$this->mconf['imgMapExtras']; 02817 02818 $gifFileName = t3lib_div::png_to_gif_by_imagemagick($gifFileName); 02819 $this->result = Array('output_file'=>$gifFileName, 'output_w'=>$w, 'output_h'=>$h, 'imgMap'=>$imgMap); 02820 } 02821 } 02822 } 02823 02824 /** 02825 * Returns the HTML for the image map menu. 02826 * If ->result is true it will create the HTML for the image map menu. 02827 * 02828 * @return string The HTML for the menu 02829 */ 02830 function writeMenu() { 02831 if ($this->result) { 02832 $res = &$this->result; 02833 $menuName = 'menu_'.t3lib_div::shortMD5($res['imgMap']); // shortMD5 260900 02834 $result = '<img src="'.$GLOBALS['TSFE']->absRefPrefix.$res['output_file'].'" width="'.$res['output_w'].'" height="'.$res['output_h'].'" usemap="#'.$menuName.'" border="0" '.$this->mconf['params']; 02835 if (!strstr($result,'alt="')) $result.=' alt="Menu Image Map"'; // Adding alt attribute if not set. 02836 $result.= ' /><map name="'.$menuName.'" id="'.$menuName.'">'.$res['imgMap'].'</map>'; 02837 02838 $GLOBALS['TSFE']->imagesOnPage[]=$res['output_file']; 02839 02840 return $this->tmpl->wrap($result,$this->mconf['wrap']); 02841 } 02842 } 02843 } 02844 02845 02846 02847 02848 02849 02850 02851 02852 02853 02854 02855 02856 02857 02858 02859 02860 02861 02862 02863 02864 02865 /** 02866 * JavaScript/Selectorbox based menus 02867 * 02868 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 02869 * @package TYPO3 02870 * @subpackage tslib 02871 */ 02872 class tslib_jsmenu extends tslib_menu { 02873 02874 /** 02875 * Dummy. Should do nothing, because we don't use the result-array here! 02876 * 02877 * @return void 02878 */ 02879 function generate() { 02880 } 02881 02882 /** 02883 * Creates the HTML (mixture of a <form> and a JavaScript section) for the JavaScript menu (basically an array of selector boxes with onchange handlers) 02884 * 02885 * @return string The HTML code for the menu 02886 */ 02887 function writeMenu() { 02888 if ($this->id) { 02889 // Making levels: 02890 $levels = t3lib_div::intInRange($this->mconf['levels'],1,5); 02891 $this->levels = $levels; 02892 $uniqueParam = t3lib_div::shortMD5(microtime(), 5); 02893 $this->JSVarName = 'eid' . $uniqueParam; 02894 $this->JSMenuName = ($this->mconf['menuName'] ? $this->mconf['menuName'] : 'JSmenu' . $uniqueParam); 02895 02896 $JScode="\n var ".$this->JSMenuName." = new JSmenu(".$levels.",'".$this->JSMenuName."Form');"; 02897 02898 for ($a=1;$a<=$levels;$a++) { 02899 $JScode.="\n var ".$this->JSVarName.$a."=0;"; 02900 } 02901 $JScode.= $this->generate_level($levels,1,$this->id,$this->menuArr,$this->MP_array).LF; 02902 02903 $GLOBALS['TSFE']->additionalHeaderData['JSMenuCode']='<script type="text/javascript" src="'.$GLOBALS['TSFE']->absRefPrefix.'t3lib/jsfunc.menu.js"></script>'; 02904 $GLOBALS['TSFE']->JSCode.=$JScode; 02905 02906 // Printing: 02907 $allFormCode=""; 02908 for ($a=1;$a<=$this->levels;$a++) { 02909 $formCode=''; 02910 $levelConf = $this->mconf[$a.'.']; 02911 $length = $levelConf['width'] ? $levelConf['width'] : 14; 02912 $lenghtStr=''; 02913 for ($b=0;$b<$length;$b++) { 02914 $lenghtStr.='_'; 02915 } 02916 $height = $levelConf['elements'] ? $levelConf['elements'] : 5; 02917 02918 $formCode.= '<select name="selector'.$a.'" onchange="'.$this->JSMenuName.'.act('.$a.');"'.($levelConf['additionalParams']?' '.$levelConf['additionalParams']:'').'>'; 02919 for ($b=0;$b<$height;$b++) { 02920 $formCode.= '<option value="0">'; 02921 if ($b==0) { 02922 $formCode.= $lenghtStr; 02923 } 02924 $formCode.='</option>'; 02925 } 02926 $formCode.= '</select>'; 02927 $allFormCode.=$this->tmpl->wrap($formCode,$levelConf['wrap']); 02928 } 02929 $formCode = $this->tmpl->wrap($allFormCode,$this->mconf['wrap']); 02930 02931 $formCode= '<form action="" method="post" style="margin: 0 0 0 0;" name="'.$this->JSMenuName.'Form">'.$formCode.'</form>'; 02932 $formCode.='<script type="text/javascript"> /*<![CDATA[*/ '.$this->JSMenuName.'.writeOut(1,'.$this->JSMenuName.'.openID,1); /*]]>*/ </script>'; 02933 return $this->tmpl->wrap($formCode,$this->mconf['wrapAfterTags']); 02934 } 02935 } 02936 02937 /** 02938 * Generates a number of lines of JavaScript code for a menu level. 02939 * Calls itself recursively for additional levels. 02940 * 02941 * @param integer Number of levels to generate 02942 * @param integer Current level being generated - and if this number is less than $levels it will call itself recursively with $count incremented 02943 * @param integer Page id of the starting point. 02944 * @param array $this->menuArr passed along 02945 * @param array Previous MP vars 02946 * @return string JavaScript code lines. 02947 * @access private 02948 */ 02949 function generate_level($levels,$count,$pid,$menuItemArray='',$MP_array=array()) { 02950 $levelConf = $this->mconf[$count.'.']; 02951 02952 // Translate PID to a mount page, if any: 02953 $mount_info = $this->sys_page->getMountPointInfo($pid); 02954 if (is_array($mount_info)) { 02955 $MP_array[] = $mount_info['MPvar']; 02956 $pid = $mount_info['mount_pid']; 02957 } 02958 02959 // UIDs to ban: 02960 $banUidArray = $this->getBannedUids(); 02961 02962 // Initializing variables: 02963 $var = $this->JSVarName; 02964 $menuName = $this->JSMenuName; 02965 $parent = $count==1 ? 0 : $var.($count-1); 02966 $prev=0; 02967 $c=0; 02968 02969 $menuItems = is_array($menuItemArray) ? $menuItemArray : $this->sys_page->getMenu($pid); 02970 foreach($menuItems as $uid => $data) { 02971 02972 // $data['_MP_PARAM'] contains MP param for overlay mount points (MPs with "substitute this page" set) 02973 // if present: add param to copy of MP array (copy used for that submenu branch only) 02974 $MP_array_sub = $MP_array; 02975 if (array_key_exists('_MP_PARAM', $data) && $data['_MP_PARAM']) { 02976 $MP_array_sub[] = $data['_MP_PARAM']; 02977 } 02978 // Set "&MP=" var: 02979 $MP_var = implode(',', $MP_array_sub); 02980 $MP_params = ($MP_var ? '&MP='.rawurlencode($MP_var) : ''); 02981 02982 $spacer = (t3lib_div::inList($this->spacerIDList,$data['doktype'])?1:0); // if item is a spacer, $spacer is set 02983 if ($this->mconf['SPC'] || !$spacer) { // If the spacer-function is not enabled, spacers will not enter the $menuArr 02984 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 02985 if ($count<$levels) { 02986 $addLines = $this->generate_level($levels, $count+1, $data['uid'], '', $MP_array_sub); 02987 } else { 02988 $addLines = ''; 02989 } 02990 $title=$data['title']; 02991 $url=''; 02992 $target=''; 02993 if ((!$addLines && !$levelConf['noLink']) || $levelConf['alwaysLink']) { 02994 $LD = $this->menuTypoLink($data,$this->mconf['target'],'','',array(),$MP_params,$this->mconf['forceTypeValue']); 02995 02996 // If access restricted pages should be shown in menus, change the link of such pages to link to a redirection page: 02997 $this->changeLinksForAccessRestrictedPages($LD, $data, $this->mconf['target'], $this->mconf['forceTypeValue']); 02998 02999 $url = $GLOBALS['TSFE']->baseUrlWrap($LD['totalURL']); 03000 $target = $LD['target']; 03001 } 03002 $codeLines.=LF.$var.$count."=".$menuName.".add(".$parent.",".$prev.",0,".t3lib_div::quoteJSvalue($title, true).",".t3lib_div::quoteJSvalue($url, true).",".t3lib_div::quoteJSvalue($target, true).");"; 03003 // If the active one should be chosen... 03004 $active = ($levelConf['showActive'] && $this->isActive($data['uid'], $MP_var)); 03005 // If the first item should be shown 03006 $first = (!$c && $levelConf['showFirst']); 03007 // do it... 03008 if ($active || $first) { 03009 if ($count==1) { 03010 $codeLines.=LF.$menuName.".openID = ".$var.$count.";"; 03011 } else { 03012 $codeLines.=LF.$menuName.".entry[".$parent."].openID = ".$var.$count.";"; 03013 } 03014 } 03015 // Add submenu... 03016 $codeLines.=$addLines; 03017 03018 $prev=$var.$count; 03019 $c++; 03020 } 03021 } 03022 } 03023 if ($this->mconf['firstLabelGeneral'] && !$levelConf['firstLabel']) { 03024 $levelConf['firstLabel'] = $this->mconf['firstLabelGeneral']; 03025 } 03026 if ($levelConf['firstLabel'] && $codeLines) { 03027 $codeLines.= LF.$menuName.'.defTopTitle['.$count.'] = '.t3lib_div::quoteJSvalue($levelConf['firstLabel'], true).';'; 03028 } 03029 return $codeLines; 03030 } 03031 } 03032 03033 03034 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['tslib/class.tslib_menu.php'])) { 03035 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['tslib/class.tslib_menu.php']); 03036 } 03037 03038 ?>
1.8.0