Generally: FE charset output conversion, new localization modes in FE and FE preview...
[Packages/TYPO3.CMS.git] / typo3 / sysext / cms / tslib / class.tslib_menu.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2004 Kasper Skaarhoj (kasper@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Generating navigation / menus from TypoScript
29 *
30 * This file contains five classes, four of which are extensions to the main class, tslib_menu.
31 * 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.
32 * Notice that extension classes (like "tslib_tmenu") must have their suffix (here "tmenu") listed in $this->tmpl->menuclasses - otherwise they cannot be instantiated.
33 *
34 * $Id$
35 * Revised for TYPO3 3.6 June/2003 by Kasper Skaarhoj
36 * XHTML compliant
37 *
38 * @author Kasper Skaarhoj <kasper@typo3.com>
39 */
40 /**
41 * [CLASS/FUNCTION INDEX of SCRIPT]
42 *
43 *
44 *
45 * 141: class tslib_menu
46 * 183: function start(&$tmpl,&$sys_page,$id,$conf,$menuNumber)
47 * 294: function makeMenu()
48 * 774: function includeMakeMenu($conf,$altSortField)
49 * 791: function procesItemStates($splitCount)
50 * 978: function link($key,$altTarget='',$typeOverride='')
51 * 1032: function subMenu($uid)
52 * 1074: function isNext($uid, $MPvar='')
53 * 1089: function isActive($uid, $MPvar='')
54 * 1104: function isCurrent($uid, $MPvar='')
55 * 1119: function isSubMenu($uid)
56 * 1144: function isItemState($kind,$key)
57 * 1181: function accessKey($title)
58 * 1207: function userProcess($mConfKey,$passVar)
59 * 1222: function setATagParts()
60 * 1235: function getPageTitle($title,$nav_title)
61 * 1247: function getMPvar($key)
62 *
63 *
64 * 1283: class tslib_tmenu extends tslib_menu
65 * 1292: function generate()
66 * 1308: function writeMenu()
67 * 1438: function getBeforeAfter($pref)
68 * 1468: function addJScolorShiftFunction()
69 * 1490: function extProc_init()
70 * 1501: function extProc_RO($key)
71 * 1512: function extProc_beforeLinking($key)
72 * 1524: function extProc_afterLinking($key)
73 * 1541: function extProc_beforeAllWrap($item,$key)
74 * 1552: function extProc_finish()
75 *
76 *
77 * 1588: class tslib_gmenu extends tslib_menu
78 * 1597: function generate()
79 * 1635: function makeGifs($conf, $resKey)
80 * 1832: function findLargestDims($conf,$items,$Hobjs,$Wobjs,$minDim,$maxDim)
81 * 1904: function writeMenu()
82 * 2002: function extProc_init()
83 * 2013: function extProc_RO($key)
84 * 2024: function extProc_beforeLinking($key)
85 * 2037: function extProc_afterLinking($key)
86 * 2053: function extProc_beforeAllWrap($item,$key)
87 * 2064: function extProc_finish()
88 *
89 *
90 * 2098: class tslib_imgmenu extends tslib_menu
91 * 2107: function generate()
92 * 2125: function makeImageMap($conf)
93 * 2294: function writeMenu()
94 *
95 *
96 * 2337: class tslib_jsmenu extends tslib_menu
97 * 2344: function generate()
98 * 2352: function writeMenu()
99 * 2413: function generate_level($levels,$count,$pid,$menuItemArray='',$MP_array=array())
100 *
101 * TOTAL FUNCTIONS: 42
102 * (This index is automatically created/updated by the extension "extdeveval")
103 *
104 */
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 /**
124 * Base class. The HMENU content object uses this (or more precisely one of the extension classes).
125 * Amoung others the class generates an array of menuitems. Thereafter functions from the subclasses are called.
126 * The class is ALWAYS used through extension classes (like tslib_gmenu or tslib_tmenu which are classics) and
127 *
128 * Example of usage (from tslib_cObj):
129 *
130 * $menu = t3lib_div::makeInstance('tslib_'.$cls);
131 * $menu->parent_cObj = $this;
132 * $menu->start($GLOBALS['TSFE']->tmpl,$GLOBALS['TSFE']->sys_page,'',$conf,1);
133 * $menu->makeMenu();
134 * $content.=$menu->writeMenu();
135 *
136 * @author Kasper Skaarhoj <kasper@typo3.com>
137 * @package TYPO3
138 * @subpackage tslib
139 * @see tslib_cObj::HMENU()
140 */
141 class tslib_menu {
142 var $menuNumber = 1; // tells you which menu-number this is. This is important when getting data from the setup
143 var $entryLevel = 0; // 0 = rootFolder
144 var $subLevelClass = ''; // Points to the menu-class, that should be used for the next level
145 var $spacerIDList = '199'; // The doktype-number that defines a spacer
146 var $doktypeExcludeList = '5,6'; // doktypes that define which should not be included in a menu
147 var $imgNamePrefix = 'img';
148 var $imgNameNotRandom=0;
149 var $debug = 0;
150 var $parent_cObj =''; // Loaded with the parent cObj-object when a new HMENU is made
151 var $GMENU_fixKey='gmenu';
152 var $MP_array=array(); // accumulation of mount point data
153
154 // internal
155 var $conf = Array(); // HMENU configuration
156 var $mconf = Array(); // xMENU configuration (TMENU, GMENU etc)
157 var $tmpl; // template-object
158 var $sys_page; // sys_page-object
159 var $id; // The base page-id of the menu.
160 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.
161 var $menuArr; // The array of menuItems which is built
162 var $hash;
163 var $result = Array();
164 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)
165 var $INPfixMD5;
166 var $I;
167 var $WMresult;
168 var $WMfreezePrefix;
169 var $WMmenuItems;
170 var $WMextraScript;
171 var $alternativeMenuTempArray=''; // Can be set to contain menu item arrays for sub-levels.
172
173 /**
174 * The initialization of the object. This just sets some internal variables.
175 *
176 * @param object The $GLOBALS['TSFE']->tmpl object
177 * @param object The $GLOBALS['TSFE']->sys_page object
178 * @param integer A starting point page id. This should probably be blank since the 'entryLevel' value will be used then.
179 * @param array The TypoScript configuration for the HMENU cObject
180 * @param integer Menu number; 1,2,3. Should probably be '1'
181 * @return boolean Returns true on success
182 * @see tslib_cObj::HMENU()
183 */
184 function start(&$tmpl,&$sys_page,$id,$conf,$menuNumber) {
185
186 // Init:
187 $this->conf = $conf;
188 $this->menuNumber = $menuNumber;
189 $this->mconf = $conf[$this->menuNumber.'.'];
190 $this->debug=$GLOBALS['TSFE']->debug;
191
192 // Sets the internal vars. $tmpl MUST be the template-object. $sys_page MUST be the sys_page object
193 if ($this->conf[$this->menuNumber] && is_object($tmpl) && is_object($sys_page)) {
194 $this->tmpl = &$tmpl;
195 $this->sys_page = &$sys_page;
196
197 // 'not in menu' doktypes
198 if($this->conf['excludeDoktypes']) {
199 $this->doktypeExcludeList = $GLOBALS['TYPO3_DB']->cleanIntList($this->conf['excludeDoktypes']);
200 }
201 if($this->conf['includeNotInMenu']) {
202 $exclDoktypeArr=t3lib_div::trimExplode(',',$this->doktypeExcludeList,1);
203 $exclDoktypeArr=t3lib_div::removeArrayEntryByValue($exclDoktypeArr,'5');
204 $this->doktypeExcludeList=implode(',',$exclDoktypeArr);
205 }
206
207 // EntryLevel
208 $this->entryLevel = tslib_cObj::getKey ($conf['entryLevel'],$this->tmpl->rootLine);
209
210 // Set parent page: If $id not stated with start() then the base-id will be found from rootLine[$this->entryLevel]
211 if ($id) { // Called as the next level in a menu. It is assumed that $this->MP_array is set from parent menu.
212 $this->id = intval($id);
213 } else { // This is a BRAND NEW menu, first level. So we take ID from rootline and also find MP_array (mount points)
214 $this->id = intval($this->tmpl->rootLine[$this->entryLevel]['uid']);
215
216 // Traverse rootline to build MP_array of pages BEFORE the entryLevel
217 // (MP var for ->id is picked up in the next part of the code...)
218 foreach($this->tmpl->rootLine as $entryLevel => $levelRec) {
219 // For overlaid mount points, set the variable right now:
220 if ($levelRec['_MP_PARAM'] && $levelRec['_MOUNT_OL']) {
221 $this->MP_array[] = $levelRec['_MP_PARAM'];
222 }
223 // Break when entry level is reached:
224 if ($entryLevel>=$this->entryLevel) break;
225
226 // For normal mount points, set the variable for next level.
227 if ($levelRec['_MP_PARAM'] && !$levelRec['_MOUNT_OL']) {
228 $this->MP_array[] = $levelRec['_MP_PARAM'];
229 }
230 }
231 }
232
233 // Return false if no page ID was set (thus no menu of subpages can be made).
234 if ($this->id<=0) {
235 return FALSE;
236 }
237
238 // Check if page is a mount point, and if so set id and MP_array
239 // (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...)
240 $mount_info = $this->sys_page->getMountPointInfo($this->id);
241 if (is_array($mount_info)) {
242 $this->MP_array[] = $mount_info['MPvar'];
243 $this->id = $mount_info['mount_pid'];
244 }
245
246 // Gather list of page uids in root line (for "isActive" evaluation). Also adds the MP params in the path so Mount Points are respected.
247 // (List is specific for this rootline, so it may be supplied from parent menus for speed...)
248 if (!is_array($this->rL_uidRegister)) {
249 $rl_MParray = array();
250 foreach($this->tmpl->rootLine as $v_rl) {
251 // For overlaid mount points, set the variable right now:
252 if ($v_rl['_MP_PARAM'] && $v_rl['_MOUNT_OL']) {
253 $rl_MParray[] = $v_rl['_MP_PARAM'];
254 }
255
256 // Add to register:
257 $this->rL_uidRegister[] = 'ITEM:'.$v_rl['uid'].(count($rl_MParray) ? ':'.implode(',',$rl_MParray) : '');
258
259 // For normal mount points, set the variable for next level.
260 if ($v_rl['_MP_PARAM'] && !$v_rl['_MOUNT_OL']) {
261 $rl_MParray[] = $v_rl['_MP_PARAM'];
262 }
263 }
264 }
265
266 // 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
267 // Notice: The automatic expansion of a menu is designed to work only when no "special" modes are used.
268 if (is_array($this->tmpl->rootLine[$this->entryLevel+$this->menuNumber])) {
269 $nextMParray = $this->MP_array;
270 if ($this->tmpl->rootLine[$this->entryLevel+$this->menuNumber]['_MOUNT_OL']) { // In overlay mode, add next level MPvars as well:
271 $nextMParray[] = $this->tmpl->rootLine[$this->entryLevel+$this->menuNumber]['_MP_PARAM'];
272 }
273 $this->nextActive = $this->tmpl->rootLine[$this->entryLevel+$this->menuNumber]['uid'].
274 (count($nextMParray)?':'.implode(',',$nextMParray):'');
275 } else {
276 $this->nextActive = '';
277 }
278
279 // imgNamePrefix
280 if ($this->mconf['imgNamePrefix']) {
281 $this->imgNamePrefix=$this->mconf['imgNamePrefix'];
282 }
283 $this->imgNameNotRandom = $this->mconf['imgNameNotRandom'];
284
285 // subLevelClass
286 $cls = strtolower($this->conf[$this->menuNumber+1]);
287 if ($cls && t3lib_div::inList($this->tmpl->menuclasses,$cls)) {
288 $this->subLevelClass = $cls;
289 }
290 $retVal = TRUE;
291 } else {
292 $GLOBALS['TT']->setTSlogMessage('ERROR in menu',3);
293 $retVal = FALSE;
294 }
295 return $retVal;
296 }
297
298 /**
299 * Creates the menu in the internal variables, ready for output.
300 * Basically this will read the page records needed and fill in the internal $this->menuArr
301 * 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.
302 *
303 * @return void
304 */
305 function makeMenu() {
306 if ($this->id) {
307 $temp = array();
308 $altSortFieldValue = trim($this->mconf['alternativeSortingField']);
309 $altSortField = $altSortFieldValue ? $altSortFieldValue : 'sorting';
310 if ($this->menuNumber==1 && $this->conf['special']) { // ... only for the FIRST level of a HMENU
311 $value = $this->conf['special.']['value'];
312
313 switch($this->conf['special']) {
314 case 'userdefined':
315 $temp = $this->includeMakeMenu($this->conf['special.'],$altSortField);
316 break;
317 case 'userfunction':
318 $temp = $this->parent_cObj->callUserFunction(
319 $this->conf['special.']['userFunc'],
320 array_merge($this->conf['special.'],array('_altSortField'=>$altSortField)),
321 ''
322 );
323 if (!is_array($temp)) $temp=array();
324 break;
325 case 'directory':
326 if ($value=='') {
327 $value=$GLOBALS['TSFE']->page['uid'];
328 }
329 $items=t3lib_div::intExplode(',',$value);
330
331 foreach($items as $id) {
332 $MP = $this->tmpl->getFromMPmap($id);
333
334 // Checking if a page is a mount page and if so, change the ID and set the MP var properly.
335 $mount_info = $this->sys_page->getMountPointInfo($id);
336 if (is_array($mount_info)) {
337 if ($mount_info['overlay']) { // Overlays should already have their full MPvars calculated:
338 $MP = $this->tmpl->getFromMPmap($mount_info['mount_pid']);
339 $MP = $MP ? $MP : $mount_info['MPvar'];
340 } else {
341 $MP = ($MP ? $MP.',' : '').$mount_info['MPvar'];
342 }
343 $id = $mount_info['mount_pid'];
344 }
345
346 // Get sub-pages:
347 $res = $GLOBALS['TSFE']->cObj->exec_getQuery('pages',Array('pidInList'=>$id,'orderBy'=>$altSortField));
348 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
349
350 // Keep mount point?
351 $mount_info = $this->sys_page->getMountPointInfo($row['uid'], $row);
352 if (is_array($mount_info) && $mount_info['overlay']) { // There is a valid mount point.
353 $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!
354 if (count($mp_row)) {
355 $row = $mp_row;
356 $row['_MP_PARAM'] = $mount_info['MPvar'];
357 } 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!
358 }
359
360 // Add external MP params, then the row:
361 if (is_array($row)) {
362 if ($MP) $row['_MP_PARAM'] = $MP.($row['_MP_PARAM'] ? ','.$row['_MP_PARAM'] : '');
363 $temp[$row['uid']] = $this->sys_page->getPageOverlay($row);
364 }
365 }
366 }
367 break;
368 case 'list':
369 if ($value=='') {
370 $value=$this->id;
371 }
372 $loadDB = t3lib_div::makeInstance('FE_loadDBGroup');
373 $loadDB->start($value, 'pages');
374 $loadDB->additionalWhere['pages']=tslib_cObj::enableFields('pages');
375 $loadDB->getFromDB();
376
377 foreach($loadDB->itemArray as $val) {
378 $MP = $this->tmpl->getFromMPmap($val['id']);
379
380 // Keep mount point?
381 $mount_info = $this->sys_page->getMountPointInfo($val['id']);
382 if (is_array($mount_info) && $mount_info['overlay']) { // There is a valid mount point.
383 $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!
384 if (count($mp_row)) {
385 $row = $mp_row;
386 $row['_MP_PARAM'] = $mount_info['MPvar'];
387
388 if ($mount_info['overlay']) { // Overlays should already have their full MPvars calculated:
389 $MP = $this->tmpl->getFromMPmap($mount_info['mount_pid']);
390 if ($MP) unset($row['_MP_PARAM']);
391 }
392
393 } 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!
394 } else {
395 $row = $loadDB->results['pages'][$val['id']];
396 }
397
398 // Add external MP params, then the row:
399 if (is_array($row)) {
400 if ($MP) $row['_MP_PARAM'] = $MP.($row['_MP_PARAM'] ? ','.$row['_MP_PARAM'] : '');
401 $temp[] = $this->sys_page->getPageOverlay($row);
402 }
403 }
404 break;
405 case 'updated':
406 if ($value=='') {
407 $value=$GLOBALS['TSFE']->page['uid'];
408 }
409 $items=t3lib_div::intExplode(',',$value);
410 if (t3lib_div::testInt($this->conf['special.']['depth'])) {
411 $depth = t3lib_div::intInRange($this->conf['special.']['depth'],1,20); // Tree depth
412 } else {
413 $depth=20;
414 }
415 $limit = t3lib_div::intInRange($this->conf['special.']['limit'],0,100); // max number of items
416 $maxAge = intval(tslib_cObj::calc($this->conf['special.']['maxAge']));
417 if (!$limit) $limit=10;
418 $mode = $this->conf['special.']['mode']; // *'auto', 'manual', 'tstamp'
419 // Get id's
420 $id_list_arr = Array();
421
422 foreach($items as $id) {
423 $bA = t3lib_div::intInRange($this->conf['special.']['beginAtLevel'],0,100);
424 $id_list_arr[] = tslib_cObj::getTreeList(-1*$id,$depth-1+$bA,$bA-1);
425 }
426 $id_list = implode(',',$id_list_arr);
427 // Get sortField (mode)
428 switch($mode) {
429 case 'starttime':
430 $sortField = 'starttime';
431 break;
432 case 'lastUpdated':
433 case 'manual':
434 $sortField = 'lastUpdated';
435 break;
436 case 'tstamp':
437 $sortField = 'tstamp';
438 break;
439 case 'crdate':
440 $sortField = 'crdate';
441 break;
442 default:
443 $sortField = 'SYS_LASTCHANGED';
444 break;
445 }
446 // Get
447 $extraWhere = ' AND pages.nav_hide=0'.$this->getDoktypeExcludeWhere();
448
449 if ($this->conf['special.']['excludeNoSearchPages']) {
450 $extraWhere.= ' AND pages.no_search=0';
451 }
452 if ($maxAge>0) {
453 $extraWhere.=' AND '.$sortField.'>'.($GLOBALS['SIM_EXEC_TIME']-$maxAge);
454 }
455
456 $res = $GLOBALS['TSFE']->cObj->exec_getQuery('pages',Array('pidInList'=>'0', 'uidInList'=>$id_list, 'where'=>$sortField.'>=0'.$extraWhere, 'orderBy'=>($altSortFieldValue ? $altSortFieldValue : $sortField.' desc'),'max'=>$limit));
457 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
458 $temp[$row['uid']]=$this->sys_page->getPageOverlay($row);
459 }
460 break;
461 case 'keywords':
462 list($value)=t3lib_div::intExplode(',',$value);
463 if (!$value) {
464 $value=$GLOBALS['TSFE']->page['uid'];
465 }
466 if ($this->conf['special.']['setKeywords'] || $this->conf['special.']['setKeywords.']) {
467 $kw = $this->parent_cObj->stdWrap($this->conf['special.']['setKeywords'], $this->conf['special.']['setKeywords.']);
468 } else {
469 $value_rec=$this->sys_page->getPage($value); // The page record of the 'value'.
470
471 $kfieldSrc = $this->conf['special.']['keywordsField.']['sourceField'] ? $this->conf['special.']['keywordsField.']['sourceField'] : 'keywords';
472 $kw = trim(tslib_cObj::keywords($value_rec[$kfieldSrc])); // keywords.
473 }
474
475 $mode = $this->conf['special.']['mode']; // *'auto', 'manual', 'tstamp'
476 switch($mode) {
477 case 'starttime':
478 $sortField = 'starttime';
479 break;
480 case 'lastUpdated':
481 case 'manual':
482 $sortField = 'lastUpdated';
483 break;
484 case 'tstamp':
485 $sortField = 'tstamp';
486 break;
487 case 'crdate':
488 $sortField = 'crdate';
489 break;
490 default:
491 $sortField = 'SYS_LASTCHANGED';
492 break;
493 }
494
495 // depth, limit, extra where
496 if (t3lib_div::testInt($this->conf['special.']['depth'])) {
497 $depth = t3lib_div::intInRange($this->conf['special.']['depth'],0,20); // Tree depth
498 } else {
499 $depth=20;
500 }
501 $limit = t3lib_div::intInRange($this->conf['special.']['limit'],0,100); // max number of items
502 $extraWhere = ' AND pages.uid!='.$value.' AND pages.nav_hide=0'.$this->getDoktypeExcludeWhere();
503 if ($this->conf['special.']['excludeNoSearchPages']) {
504 $extraWhere.= ' AND pages.no_search=0';
505 }
506 // start point
507 $eLevel = tslib_cObj::getKey (intval($this->conf['special.']['entryLevel']),$this->tmpl->rootLine);
508 $startUid = intval($this->tmpl->rootLine[$eLevel]['uid']);
509
510 // which field is for keywords
511 $kfield = 'keywords';
512 if ( $this->conf['special.']['keywordsField'] ) {
513 list($kfield) = explode(' ',trim ($this->conf['special.']['keywordsField']));
514 }
515
516 // If there are keywords and the startuid is present.
517 if ($kw && $startUid) {
518 $bA = t3lib_div::intInRange($this->conf['special.']['beginAtLevel'],0,100);
519 $id_list=tslib_cObj::getTreeList(-1*$startUid,$depth-1+$bA,$bA-1);
520
521 $kwArr = explode(',',$kw);
522 foreach($kwArr as $word) {
523 $word = trim($word);
524 if ($word) {
525 $keyWordsWhereArr[] = $kfield.' LIKE "%'.$GLOBALS['TYPO3_DB']->quoteStr($word, 'pages').'%"';
526 }
527 }
528 $res = $GLOBALS['TSFE']->cObj->exec_getQuery('pages',Array('pidInList'=>'0', 'uidInList'=>$id_list, 'where'=>'('.implode(' OR ',$keyWordsWhereArr).')'.$extraWhere, 'orderBy'=>($altSortFieldValue ? $altSortFieldValue : $sortField.' desc'),'max'=>$limit));
529 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
530 $temp[$row['uid']]=$this->sys_page->getPageOverlay($row);
531 }
532 }
533 break;
534 case 'rootline':
535 $begin_end = explode('|',$this->conf['special.']['range']);
536 if (!t3lib_div::testInt($begin_end[0])) {intval($begin_end[0]);}
537 if (!t3lib_div::testInt($begin_end[1])) {$begin_end[1]=-1;}
538
539 $beginKey = tslib_cObj::getKey ($begin_end[0],$this->tmpl->rootLine);
540 $endKey = tslib_cObj::getKey ($begin_end[1],$this->tmpl->rootLine);
541 if ($endKey<$beginKey) {$endKey=$beginKey;}
542
543 $rl_MParray = array();
544 foreach($this->tmpl->rootLine as $k_rl => $v_rl) {
545 // For overlaid mount points, set the variable right now:
546 if ($v_rl['_MP_PARAM'] && $v_rl['_MOUNT_OL']) {
547 $rl_MParray[] = $v_rl['_MP_PARAM'];
548 }
549 // Traverse rootline:
550 if ($k_rl>=$beginKey && $k_rl<=$endKey) {
551 $temp_key=$k_rl;
552 $temp[$temp_key]=$this->sys_page->getPage($v_rl['uid']);
553 if (count($temp[$temp_key])) {
554 if (!$temp[$temp_key]['target']) { // If there are no specific target for the page, put the level specific target on.
555 $temp[$temp_key]['target'] = $this->conf['special.']['targets.'][$k_rl];
556 $temp[$temp_key]['_MP_PARAM'] = implode(',',$rl_MParray);
557 }
558 } else unset($temp[$temp_key]);
559 }
560 // For normal mount points, set the variable for next level.
561 if ($v_rl['_MP_PARAM'] && !$v_rl['_MOUNT_OL']) {
562 $rl_MParray[] = $v_rl['_MP_PARAM'];
563 }
564 }
565 break;
566 case 'browse':
567 list($value)=t3lib_div::intExplode(',',$value);
568 if (!$value) {
569 $value=$GLOBALS['TSFE']->page['uid'];
570 }
571 if ($value!=$this->tmpl->rootLine[0]['uid']) { // Will not work out of rootline
572 $recArr=array();
573 $value_rec=$this->sys_page->getPage($value); // The page record of the 'value'.
574 if ($value_rec['pid']) { // 'up' page cannot be outside rootline
575 $recArr['up']=$this->sys_page->getPage($value_rec['pid']); // The page record of 'up'.
576 }
577 if ($recArr['up']['pid'] && $value_rec['pid']!=$this->tmpl->rootLine[0]['uid']) { // If the 'up' item was NOT level 0 in rootline...
578 $recArr['index']=$this->sys_page->getPage($recArr['up']['pid']); // The page record of "index".
579 }
580
581 // prev / next is found
582 $prevnext_menu = $this->sys_page->getMenu($value_rec['pid'],'*',$altSortField);
583 $lastKey=0;
584 $nextActive=0;
585 reset($prevnext_menu);
586 while(list($k_b,$v_b)=each($prevnext_menu)) {
587 if ($nextActive) {
588 $recArr['next']=$v_b;
589 $nextActive=0;
590 }
591 if ($v_b['uid']==$value) {
592 if ($lastKey) {
593 $recArr['prev']=$prevnext_menu[$lastKey];
594 }
595 $nextActive=1;
596 }
597 $lastKey=$k_b;
598 }
599 reset($prevnext_menu);
600 $recArr['first']=pos($prevnext_menu);
601 end($prevnext_menu);
602 $recArr['last']=pos($prevnext_menu);
603
604 // prevsection / nextsection is found
605 if (is_array($recArr['index'])) { // You can only do this, if there is a valid page two levels up!
606 $prevnextsection_menu = $this->sys_page->getMenu($recArr['index']['uid'],'*',$altSortField);
607 $lastKey=0;
608 $nextActive=0;
609 reset($prevnextsection_menu);
610 while(list($k_b,$v_b)=each($prevnextsection_menu)) {
611 if ($nextActive) {
612 $sectionRec_temp = $this->sys_page->getMenu($v_b['uid'],'*',$altSortField);
613 if (count($sectionRec_temp)) {
614 reset($sectionRec_temp);
615 $recArr['nextsection']=pos($sectionRec_temp);
616 end ($sectionRec_temp);
617 $recArr['nextsection_last']=pos($sectionRec_temp);
618 $nextActive=0;
619 }
620 }
621 if ($v_b['uid']==$value_rec['pid']) {
622 if ($lastKey) {
623 $sectionRec_temp = $this->sys_page->getMenu($prevnextsection_menu[$lastKey]['uid'],'*',$altSortField);
624 if (count($sectionRec_temp)) {
625 reset($sectionRec_temp);
626 $recArr['prevsection']=pos($sectionRec_temp);
627 end ($sectionRec_temp);
628 $recArr['prevsection_last']=pos($sectionRec_temp);
629 }
630 }
631 $nextActive=1;
632 }
633 $lastKey=$k_b;
634 }
635 }
636 if ($this->conf['special.']['items.']['prevnextToSection']) {
637 if (!is_array($recArr['prev']) && is_array($recArr['prevsection_last'])) {
638 $recArr['prev']=$recArr['prevsection_last'];
639 }
640 if (!is_array($recArr['next']) && is_array($recArr['nextsection'])) {
641 $recArr['next']=$recArr['nextsection'];
642 }
643 }
644
645 $items = explode('|',$this->conf['special.']['items']);
646 $c=0;
647 while(list($k_b,$v_b)=each($items)) {
648 $v_b=strtolower(trim($v_b));
649 if (intval($this->conf['special.'][$v_b.'.']['uid'])) {
650 $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
651 }
652 if (is_array($recArr[$v_b])) {
653 $temp[$c]=$recArr[$v_b];
654 if ($this->conf['special.'][$v_b.'.']['target']) {
655 $temp[$c]['target']=$this->conf['special.'][$v_b.'.']['target'];
656 }
657 if (is_array($this->conf['special.'][$v_b.'.']['fields.'])) {
658 reset($this->conf['special.'][$v_b.'.']['fields.']);
659 while(list($fk,$val)=each($this->conf['special.'][$v_b.'.']['fields.'])) {
660 $temp[$c][$fk]=$val;
661 }
662 }
663 $c++;
664 }
665 }
666 }
667 break;
668 }
669 } elseif (is_array($this->alternativeMenuTempArray)) { // Setting $temp array if not level 1.
670 $temp = $this->alternativeMenuTempArray;
671 } elseif ($this->mconf['sectionIndex']) {
672 if ($GLOBALS['TSFE']->sys_language_uid && count($this->sys_page->getPageOverlay($this->id))) {
673 $sys_language_uid = intval($GLOBALS['TSFE']->sys_language_uid);
674 } else $sys_language_uid=0;
675
676 $selectSetup = Array(
677 'pidInList'=>$this->id,
678 'orderBy'=>$altSortField,
679 'where' => 'colPos=0 AND sys_language_uid='.$sys_language_uid,
680 'andWhere' => 'sectionIndex!=0'
681 );
682 switch($this->mconf['sectionIndex.']['type']) {
683 case 'all':
684 unset($selectSetup['andWhere']);
685 break;
686 case 'header':
687 $selectSetup['andWhere']='header_layout!=100 AND header!=""';
688 break;
689 }
690 $basePageRow=$this->sys_page->getPage($this->id);
691 if (is_array($basePageRow)) {
692 $res = $GLOBALS['TSFE']->cObj->exec_getQuery('tt_content', $selectSetup);
693 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
694 $temp[$row['uid']]=$basePageRow;
695 $temp[$row['uid']]['title']=$row['header'];
696 $temp[$row['uid']]['subtitle']=$row['subheader'];
697 $temp[$row['uid']]['starttime']=$row['starttime'];
698 $temp[$row['uid']]['endtime']=$row['endtime'];
699 $temp[$row['uid']]['fe_group']=$row['fe_group'];
700 $temp[$row['uid']]['media']=$row['media'];
701
702 $temp[$row['uid']]['header_layout']=$row['header_layout'];
703 $temp[$row['uid']]['bodytext']=$row['bodytext'];
704 $temp[$row['uid']]['image']=$row['image'];
705
706 $temp[$row['uid']]['sectionIndex_uid']=$row['uid'];
707 }
708 }
709 } else { // Default:
710 $temp = $this->sys_page->getMenu($this->id,'*',$altSortField); // gets the menu
711 }
712
713 $c=0;
714 $c_b=0;
715 $minItems = intval($this->mconf['minItems'] ? $this->mconf['minItems'] : $this->conf['minItems']);
716 $maxItems = intval($this->mconf['maxItems'] ? $this->mconf['maxItems'] : $this->conf['maxItems']);
717 $begin = tslib_cObj::calc($this->mconf['begin'] ? $this->mconf['begin'] : $this->conf['begin']);
718
719 $banUidArray=array();
720 if (trim($this->conf['excludeUidList'])) {
721 $banUidArray = t3lib_div::intExplode(',', $this->conf['excludeUidList']);
722 }
723
724 // Fill in the menuArr with elements that should go into the menu:
725 $this->menuArr = Array();
726 foreach($temp as $data) {
727 $spacer = t3lib_div::inList($this->spacerIDList,$data['doktype']) ? 1 : 0; // if item is a spacer, $spacer is set
728 if ($this->filterMenuPages($data, $banUidArray, $spacer)) {
729 $c_b++;
730 if ($begin<=$c_b) { // If the beginning item has been reached.
731 $this->menuArr[$c] = $data;
732 $this->menuArr[$c]['isSpacer'] = $spacer;
733 $c++;
734 if ($maxItems && $c>=$maxItems) {
735 break;
736 }
737 }
738 }
739 }
740
741 // Fill in fake items, if min-items is set.
742 if ($minItems) {
743 while($c<$minItems) {
744 $this->menuArr[$c] = Array(
745 'title' => '...',
746 'uid' => $GLOBALS['TSFE']->id
747 );
748 $c++;
749 }
750 }
751 // Setting number of menu items
752 $GLOBALS['TSFE']->register['count_menuItems'] = count($this->menuArr);
753 // Passing the menuArr through a user defined function:
754 if ($this->mconf['itemArrayProcFunc']) {
755 if (!is_array($this->parentMenuArr)) {$this->parentMenuArr=array();}
756 $this->menuArr = $this->userProcess('itemArrayProcFunc',$this->menuArr);
757 }
758 $this->hash = md5(serialize($this->menuArr).serialize($this->mconf).serialize($this->tmpl->rootLine).serialize($this->MP_array));
759
760 $serData = $this->sys_page->getHash($this->hash, 60*60*24);
761 if (!$serData) {
762 $this->generate();
763 $this->sys_page->storeHash($this->hash, serialize($this->result),'MENUDATA');
764 } else {
765 $this->result=unserialize($serData);
766 }
767 }
768 }
769
770 /**
771 * Includes the PHP script defined for the HMENU special type "userdefined".
772 * This script is supposed to populate the array $menuItemsArray with a set of page records comprising the menu.
773 * The "userdefined" type is depreciated since "userfunction" has arrived since and is a better choice for many reasons (like using classes/functions for rendering the menu)
774 *
775 * @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.
776 * @param string The sorting field. Can be used from the script in the $incFile.
777 * @return array An array with the menu items
778 * @access private
779 */
780 function includeMakeMenu($conf,$altSortField) {
781 $incFile = $GLOBALS['TSFE']->tmpl->getFileName($conf['file']);
782 if ($incFile && $GLOBALS['TSFE']->checkFileInclude($incFile)) {
783 include($incFile);
784 }
785 return is_array($menuItemsArray) ? $menuItemsArray : array();
786 }
787
788 /**
789 * 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.
790 *
791 * @param array Array of menu items
792 * @param array Array of page uids which are to be excluded
793 * @param boolean If set, then the page is a spacer.
794 * @return boolean Returns true if the page can be safely included.
795 */
796 function filterMenuPages($data,$banUidArray,$spacer) {
797 $uid = $data['uid'];
798 if ($this->mconf['SPC'] || !$spacer) { // If the spacer-function is not enabled, spacers will not enter the $menuArr
799 if (!t3lib_div::inList($this->doktypeExcludeList,$data['doktype'])) { // Page may not be 'not_in_menu' or 'Backend User Section'
800 if (!$data['nav_hide']) { // Not hidden in navigation
801 if (!t3lib_div::inArray($banUidArray,$uid)) { // not in banned uid's
802
803 // Checks if the default language version can be shown:
804 // Block page is set, if l18n_cfg allows plus: 1) Either default language or 2) another language but NO overlay record set for page!
805 $blockPage = $data['l18n_cfg']&1 && (!$GLOBALS['TSFE']->sys_language_uid || ($GLOBALS['TSFE']->sys_language_uid && !$data['_PAGES_OVERLAY']));
806 if (!$blockPage) {
807
808 // Checking if a page should be shown in the menu depending on whether a translation exists:
809 $tok = TRUE;
810 if ($GLOBALS['TSFE']->sys_language_uid && $data['l18n_cfg']&2) { // There is an alternative language active AND the current page requires a translation:
811 $olRec = $GLOBALS['TSFE']->sys_page->getPageOverlay($data['uid'], $GLOBALS['TSFE']->sys_language_uid);
812 if (!count($olRec)) {
813 $tok = FALSE;
814 }
815 }
816
817 // Continue if token is true:
818 if ($tok) {
819 return TRUE;
820 }
821 }
822 }
823 }
824 }
825 }
826 }
827
828 /**
829 * 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)
830 * 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.
831 * 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.
832 *
833 * @param integer Number of menu items in the menu
834 * @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)
835 * @access private
836 */
837 function procesItemStates($splitCount) {
838
839 // Prepare normal settings
840 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.
841 $NOconf = $this->tmpl->splitConfArray($this->mconf['NO.'],$splitCount);
842
843 // Prepare rollOver settings, overriding normal settings
844 $ROconf=array();
845 if ($this->mconf['RO']) {
846 $ROconf = $this->tmpl->splitConfArray($this->mconf['RO.'],$splitCount);
847 }
848
849 // Prepare IFSUB settings, overriding normal settings
850 // IFSUB is true if there exist submenu items to the current item
851 if ($this->mconf['IFSUB']) {
852 $IFSUBinit = 0; // Flag: If $IFSUB is generated
853 reset($NOconf);
854 while (list($key,$val)=each($NOconf)) {
855 if ($this->isItemState('IFSUB',$key)) {
856 if (!$IFSUBinit) { // if this is the first IFSUB element, we must generate IFSUB.
857 $IFSUBconf = $this->tmpl->splitConfArray($this->mconf['IFSUB.'],$splitCount);
858 if ($this->mconf['IFSUBRO']) {
859 $IFSUBROconf = $this->tmpl->splitConfArray($this->mconf['IFSUBRO.'],$splitCount);
860 }
861 $IFSUBinit = 1;
862 }
863 $NOconf[$key] = $IFSUBconf[$key]; // Substitute normal with ifsub
864 if ($ROconf) { // If rollOver on normal, we must apply a state for rollOver on the active
865 $ROconf[$key] = $IFSUBROconf[$key] ? $IFSUBROconf[$key] : $IFSUBconf[$key]; // If RollOver on active then apply this
866 }
867 }
868 }
869 }
870 // Prepare active settings, overriding normal settings
871 if ($this->mconf['ACT']) {
872 $ACTinit = 0; // Flag: If $ACT is generated
873 reset($NOconf);
874 while (list($key,$val)=each($NOconf)) { // Find active
875 if ($this->isItemState('ACT',$key)) {
876 if (!$ACTinit) { // if this is the first active, we must generate ACT.
877 $ACTconf = $this->tmpl->splitConfArray($this->mconf['ACT.'],$splitCount);
878 // Prepare active rollOver settings, overriding normal active settings
879 if ($this->mconf['ACTRO']) {
880 $ACTROconf = $this->tmpl->splitConfArray($this->mconf['ACTRO.'],$splitCount);
881 }
882 $ACTinit = 1;
883 }
884 $NOconf[$key] = $ACTconf[$key]; // Substitute normal with active
885 if ($ROconf) { // If rollOver on normal, we must apply a state for rollOver on the active
886 $ROconf[$key] = $ACTROconf[$key] ? $ACTROconf[$key] : $ACTconf[$key]; // If RollOver on active then apply this
887 }
888 }
889 }
890 }
891 // Prepare active/IFSUB settings, overriding normal settings
892 // ACTIFSUB is true if there exist submenu items to the current item and the current item is active
893 if ($this->mconf['ACTIFSUB']) {
894 $ACTIFSUBinit = 0; // Flag: If $ACTIFSUB is generated
895 reset($NOconf);
896 while (list($key,$val)=each($NOconf)) { // Find active
897 if ($this->isItemState('ACTIFSUB',$key)) {
898 if (!$ACTIFSUBinit) { // if this is the first active, we must generate ACTIFSUB.
899 $ACTIFSUBconf = $this->tmpl->splitConfArray($this->mconf['ACTIFSUB.'],$splitCount);
900 // Prepare active rollOver settings, overriding normal active settings
901 if ($this->mconf['ACTIFSUBRO']) {
902 $ACTIFSUBROconf = $this->tmpl->splitConfArray($this->mconf['ACTIFSUBRO.'],$splitCount);
903 }
904 $ACTIFSUBinit = 1;
905 }
906 $NOconf[$key] = $ACTIFSUBconf[$key]; // Substitute normal with active
907 if ($ROconf) { // If rollOver on normal, we must apply a state for rollOver on the active
908 $ROconf[$key] = $ACTIFSUBROconf[$key] ? $ACTIFSUBROconf[$key] : $ACTIFSUBconf[$key]; // If RollOver on active then apply this
909 }
910 }
911 }
912 }
913 // Prepare CUR (current) settings, overriding normal settings
914 // CUR is true if the current page equals the item here!
915 if ($this->mconf['CUR']) {
916 $CURinit = 0; // Flag: If $CUR is generated
917 reset($NOconf);
918 while (list($key,$val)=each($NOconf)) {
919 if ($this->isItemState('CUR',$key)) {
920 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)
921 $CURconf = $this->tmpl->splitConfArray($this->mconf['CUR.'],$splitCount);
922 if ($this->mconf['CURRO']) {
923 $CURROconf = $this->tmpl->splitConfArray($this->mconf['CURRO.'],$splitCount);
924 }
925 $CURinit = 1;
926 }
927 $NOconf[$key] = $CURconf[$key]; // Substitute normal with current
928 if ($ROconf) { // If rollOver on normal, we must apply a state for rollOver on the active
929 $ROconf[$key] = $CURROconf[$key] ? $CURROconf[$key] : $CURconf[$key]; // If RollOver on active then apply this
930 }
931 }
932 }
933 }
934 // Prepare active settings, overriding normal settings
935 if ($this->mconf['USR']) {
936 $USRinit = 0; // Flag: If $USR is generated
937 reset($NOconf);
938 while (list($key,$val)=each($NOconf)) { // Find active
939 if ($this->isItemState('USR',$key)) {
940 if (!$USRinit) { // if this is the first active, we must generate USR.
941 $USRconf = $this->tmpl->splitConfArray($this->mconf['USR.'],$splitCount);
942 // Prepare active rollOver settings, overriding normal active settings
943 if ($this->mconf['USRRO']) {
944 $USRROconf = $this->tmpl->splitConfArray($this->mconf['USRRO.'],$splitCount);
945 }
946 $USRinit = 1;
947 }
948 $NOconf[$key] = $USRconf[$key]; // Substitute normal with active
949 if ($ROconf) { // If rollOver on normal, we must apply a state for rollOver on the active
950 $ROconf[$key] = $USRROconf[$key] ? $USRROconf[$key] : $USRconf[$key]; // If RollOver on active then apply this
951 }
952 }
953 }
954 }
955 // Prepare spacer settings, overriding normal settings
956 if ($this->mconf['SPC']) {
957 $SPCinit = 0; // Flag: If $SPC is generated
958 reset($NOconf);
959 while (list($key,$val)=each($NOconf)) { // Find spacers
960 if ($this->isItemState('SPC',$key)) {
961 if (!$SPCinit) { // if this is the first spacer, we must generate SPC.
962 $SPCconf = $this->tmpl->splitConfArray($this->mconf['SPC.'],$splitCount);
963 $SPCinit = 1;
964 }
965 $NOconf[$key] = $SPCconf[$key]; // Substitute normal with spacer
966 }
967 }
968 }
969 // Prepare Userdefined settings
970 if ($this->mconf['USERDEF1']) {
971 $USERDEF1init = 0; // Flag: If $USERDEF1 is generated
972 reset($NOconf);
973 while (list($key,$val)=each($NOconf)) { // Find active
974 if ($this->isItemState('USERDEF1',$key)) {
975 if (!$USERDEF1init) { // if this is the first active, we must generate USERDEF1.
976 $USERDEF1conf = $this->tmpl->splitConfArray($this->mconf['USERDEF1.'],$splitCount);
977 // Prepare active rollOver settings, overriding normal active settings
978 if ($this->mconf['USERDEF1RO']) {
979 $USERDEF1ROconf = $this->tmpl->splitConfArray($this->mconf['USERDEF1RO.'],$splitCount);
980 }
981 $USERDEF1init = 1;
982 }
983 $NOconf[$key] = $USERDEF1conf[$key]; // Substitute normal with active
984 if ($ROconf) { // If rollOver on normal, we must apply a state for rollOver on the active
985 $ROconf[$key] = $USERDEF1ROconf[$key] ? $USERDEF1ROconf[$key] : $USERDEF1conf[$key]; // If RollOver on active then apply this
986 }
987 }
988 }
989 }
990 // Prepare Userdefined settings
991 if ($this->mconf['USERDEF2']) {
992 $USERDEF2init = 0; // Flag: If $USERDEF2 is generated
993 reset($NOconf);
994 while (list($key,$val)=each($NOconf)) { // Find active
995 if ($this->isItemState('USERDEF2',$key)) {
996 if (!$USERDEF2init) { // if this is the first active, we must generate USERDEF2.
997 $USERDEF2conf = $this->tmpl->splitConfArray($this->mconf['USERDEF2.'],$splitCount);
998 // Prepare active rollOver settings, overriding normal active settings
999 if ($this->mconf['USERDEF2RO']) {
1000 $USERDEF2ROconf = $this->tmpl->splitConfArray($this->mconf['USERDEF2RO.'],$splitCount);
1001 }
1002 $USERDEF2init = 1;
1003 }
1004 $NOconf[$key] = $USERDEF2conf[$key]; // Substitute normal with active
1005 if ($ROconf) { // If rollOver on normal, we must apply a state for rollOver on the active
1006 $ROconf[$key] = $USERDEF2ROconf[$key] ? $USERDEF2ROconf[$key] : $USERDEF2conf[$key]; // If RollOver on active then apply this
1007 }
1008 }
1009 }
1010 }
1011
1012 return array($NOconf,$ROconf);
1013 }
1014
1015 /**
1016 * 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
1017 * This function doesn't care about the url, because if we let the url be redirected, it will be logged in the stat!!!
1018 *
1019 * @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)
1020 * @param string Alternative target
1021 * @param integer Alternative type
1022 * @return array Returns an array with A-tag attributes as key/value pairs (HREF, TARGET and onClick)
1023 * @access private
1024 */
1025 function link($key,$altTarget='',$typeOverride='') {
1026
1027 // Mount points:
1028 $MP_var = $this->getMPvar($key);
1029 $MP_params = $MP_var ? '&MP='.rawurlencode($MP_var) : '';
1030
1031 // Setting override ID
1032 if ($this->mconf['overrideId'] || $this->menuArr[$key]['overrideId']) {
1033 $overrideArray = array();
1034 // If a user script returned the value overrideId in the menu array we use that as page id
1035 $overrideArray['uid'] = $this->mconf['overrideId']?$this->mconf['overrideId']:$this->menuArr[$key]['overrideId'];
1036 $overrideArray['alias'] = '';
1037 $MP_params = ''; // clear MP parameters since ID was changed.
1038 } else {
1039 $overrideArray='';
1040 }
1041
1042 // Setting main target:
1043 $mainTarget = $altTarget ? $altTarget : $this->mconf['target'];
1044
1045 // Creating link:
1046 if ($this->mconf['collapse'] && $this->isActive($this->menuArr[$key]['uid'], $this->getMPvar($key))) {
1047 $thePage = $this->sys_page->getPage($this->menuArr[$key]['pid']);
1048 $LD = $this->tmpl->linkData($thePage,$mainTarget,'','',$overrideArray, $this->mconf['addParams'].$MP_params, $typeOverride);
1049 } else {
1050 $LD = $this->tmpl->linkData($this->menuArr[$key],$mainTarget,'','',$overrideArray, $this->mconf['addParams'].$MP_params, $typeOverride);
1051 }
1052
1053 // Overriding URL / Target if set to do so:
1054 if ($this->menuArr[$key]['_OVERRIDE_HREF']) {
1055 $LD['totalURL'] = $this->menuArr[$key]['_OVERRIDE_HREF'];
1056 if ($this->menuArr[$key]['_OVERRIDE_TARGET']) $LD['target'] = $this->menuArr[$key]['_OVERRIDE_TARGET'];
1057 }
1058
1059 // OnClick open in windows.
1060 $onClick='';
1061 if ($this->mconf['JSWindow']) {
1062 $conf=$this->mconf['JSWindow.'];
1063 $url=$LD['totalURL'];
1064 $LD['totalURL'] = '#';
1065 $onClick= 'openPic(\''.$url.'\',\''.($conf['newWindow']?md5($url):'theNewPage').'\',\''.$conf['params'].'\'); return false;';
1066 $GLOBALS['TSFE']->setJS('openPic');
1067 }
1068 // out:
1069 $list = array();
1070 $list['HREF']=$LD['totalURL'];
1071 $list['TARGET']=$LD['target'];
1072 $list['onClick']=$onClick;
1073
1074 return $list;
1075 }
1076
1077 /**
1078 * Creates a submenu level to the current level - if configured for.
1079 *
1080 * @param integer Page id of the current page for which a submenu MAY be produced (if conditions are met)
1081 * @return string HTML content of the submenu
1082 * @access private
1083 */
1084 function subMenu($uid) {
1085
1086 // Setting alternative menu item array if _SUB_MENU has been defined in the current ->menuArr
1087 $altArray = '';
1088 if (is_array($this->menuArr[$this->I['key']]['_SUB_MENU']) && count($this->menuArr[$this->I['key']]['_SUB_MENU'])) {
1089 $altArray = $this->menuArr[$this->I['key']]['_SUB_MENU'];
1090 }
1091
1092 // Make submenu if the page is the next active
1093 if ($this->subLevelClass && ($this->mconf['expAll'] || $this->isNext($uid, $this->getMPvar($this->I['key'])) || is_array($altArray)) && !$this->mconf['sectionIndex']) {
1094 $submenu = t3lib_div::makeInstance('tslib_'.$this->subLevelClass);
1095 $submenu->entryLevel = $this->entryLevel+1;
1096 $submenu->rL_uidRegister = $this->rL_uidRegister;
1097 $submenu->MP_array = $this->MP_array;
1098 if ($this->menuArr[$this->I['key']]['_MP_PARAM']) {
1099 $submenu->MP_array[] = $this->menuArr[$this->I['key']]['_MP_PARAM'];
1100 }
1101
1102 // especially scripts that build the submenu needs the parent data
1103 $submenu->parentMenuArr = $this->menuArr;
1104
1105 // Setting alternativeMenuTempArray (will be effective only if an array)
1106 if (is_array($altArray)) {
1107 $submenu->alternativeMenuTempArray = $altArray;
1108 }
1109
1110 if ($submenu->start($this->tmpl, $this->sys_page, $uid, $this->conf, $this->menuNumber+1)) {
1111 $submenu->makeMenu();
1112 return $submenu->writeMenu();
1113 }
1114 }
1115 }
1116
1117 /**
1118 * Returns true if the page with UID $uid is the NEXT page in root line (which means a submenu should be drawn)
1119 *
1120 * @param integer Page uid to evaluate.
1121 * @param string MPvar for the current position of item.
1122 * @return boolean True if page with $uid is active
1123 * @access private
1124 * @see subMenu()
1125 */
1126 function isNext($uid, $MPvar='') {
1127 $testUid = $uid.($MPvar?':'.$MPvar:'');
1128 if ($uid && $testUid==$this->nextActive) {
1129 return TRUE;
1130 }
1131 }
1132
1133 /**
1134 * Returns true if the page with UID $uid is active (in the current rootline)
1135 *
1136 * @param integer Page uid to evaluate.
1137 * @param string MPvar for the current position of item.
1138 * @return boolean True if page with $uid is active
1139 * @access private
1140 */
1141 function isActive($uid, $MPvar='') {
1142 $testUid = $uid.($MPvar?':'.$MPvar:'');
1143 if ($uid && in_array('ITEM:'.$testUid, $this->rL_uidRegister)) {
1144 return TRUE;
1145 }
1146 }
1147
1148 /**
1149 * Returns true if the page with UID $uid is the CURRENT page (equals $GLOBALS['TSFE']->id)
1150 *
1151 * @param integer Page uid to evaluate.
1152 * @param string MPvar for the current position of item.
1153 * @return boolean True if page $uid = $GLOBALS['TSFE']->id
1154 * @access private
1155 */
1156 function isCurrent($uid, $MPvar='') {
1157 $testUid = $uid.($MPvar?':'.$MPvar:'');
1158 if ($uid && !strcmp(end($this->rL_uidRegister),'ITEM:'.$testUid)) {
1159 return TRUE;
1160 }
1161 }
1162
1163 /**
1164 * Returns true if there is a submenu with items for the page id, $uid
1165 * Used by the item states "IFSUB" and "ACTIFSUB" to check if there is a submenu
1166 *
1167 * @param integer Page uid for which to search for a submenu
1168 * @return boolean Returns true if there was a submenu with items found
1169 * @access private
1170 */
1171 function isSubMenu($uid) {
1172
1173 // 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;
1174 $mount_info = $this->sys_page->getMountPointInfo($uid);
1175 if (is_array($mount_info)) {
1176 $uid = $mount_info['mount_pid'];
1177 }
1178
1179 $recs = $this->sys_page->getMenu($uid,'uid,pid,doktype,mount_pid,mount_pid_ol');
1180 foreach($recs as $theRec) {
1181 if (!t3lib_div::inList($this->doktypeExcludeList,$theRec['doktype']) && !$theRec['nav_hide']) { // If a menu item seems to be another type than 'Not in menu', then return true (there were items!)
1182 return TRUE;
1183 }
1184 }
1185 }
1186
1187 /**
1188 * Used by procesItemStates() to evaluate if a menu item (identified by $key) is in a certain state.
1189 *
1190 * @param string The item state to evaluate (SPC, IFSUB, ACT etc... but no xxxRO states of course)
1191 * @param integer Key pointing to menu item from ->menuArr
1192 * @return boolean True (integer!=0) if match, otherwise false (=0, zero)
1193 * @access private
1194 * @see procesItemStates()
1195 */
1196 function isItemState($kind,$key) {
1197 $natVal=0;
1198 if ($this->menuArr[$key]['ITEM_STATE']) { // If any value is set for ITEM_STATE the normal evaluation is discarded
1199 if (!strcmp($this->menuArr[$key]['ITEM_STATE'],$kind)) {$natVal=1;}
1200 } else {
1201 switch($kind) {
1202 case 'SPC':
1203 $natVal = $this->menuArr[$key]['isSpacer'];
1204 break;
1205 case 'IFSUB':
1206 $natVal = $this->isSubMenu($this->menuArr[$key]['uid']);
1207 break;
1208 case 'ACT':
1209 $natVal = $this->isActive($this->menuArr[$key]['uid'], $this->getMPvar($key));
1210 break;
1211 case 'ACTIFSUB':
1212 $natVal = $this->isActive($this->menuArr[$key]['uid'], $this->getMPvar($key)) && $this->isSubMenu($this->menuArr[$key]['uid']);
1213 break;
1214 case 'CUR':
1215 $natVal = $this->isCurrent($this->menuArr[$key]['uid'], $this->getMPvar($key));
1216 break;
1217 case 'USR':
1218 $natVal = $this->menuArr[$key]['fe_group'];
1219 break;
1220 }
1221 }
1222
1223 return $natVal;
1224 }
1225
1226 /**
1227 * Creates an access-key for a GMENU menu item based on the menu item titles first letter
1228 *
1229 * @param string Menu item title.
1230 * @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
1231 * @access private
1232 */
1233 function accessKey($title) {
1234 // The global array ACCESSKEY is used to globally control if letters are already used!!
1235 $result = Array();
1236
1237 $titleLen = strlen($title);
1238 for ($a=0;$a<$titleLen;$a++) {
1239 $key = strtoupper(trim(substr($title,$a,1)));
1240 if ($key && !isset($GLOBALS['TSFE']->accessKey[$key])) {
1241 $GLOBALS['TSFE']->accessKey[$key]=1;
1242 $result['code'] = ' accesskey="'.$key.'"';
1243 $result['alt'] = ' (ALT+'.$key.')';
1244 break;
1245 }
1246 }
1247 return $result;
1248 }
1249
1250 /**
1251 * Calls a user function for processing of internal data.
1252 * Used for the properties "IProcFunc" and "itemArrayProcFunc"
1253 *
1254 * @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".
1255 * @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
1256 * @return mixed The processed $passVar
1257 * @access private
1258 */
1259 function userProcess($mConfKey,$passVar) {
1260 if ($this->mconf[$mConfKey]) {
1261 $funcConf = $this->mconf[$mConfKey.'.'];
1262 $funcConf['parentObj']=&$this;
1263 $passVar = $GLOBALS['TSFE']->cObj->callUserFunction($this->mconf[$mConfKey], $funcConf, $passVar);
1264 }
1265 return $passVar;
1266 }
1267
1268 /**
1269 * 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'])
1270 *
1271 * @return void
1272 * @access private
1273 */
1274 function setATagParts() {
1275 $this->I['A1'] = '<a '.t3lib_div::implodeAttributes($this->I['linkHREF'],1).$this->I['val']['ATagParams'].$this->I['addATagParams'].$this->I['accessKey']['code'].'>';
1276 $this->I['A2'] = '</a>';
1277 }
1278
1279 /**
1280 * Returns the title for the navigation
1281 *
1282 * @param string The current page title
1283 * @param string The current value of the naviation title
1284 * @return string Returns the navigation title if it is NOT blank, otherwise the page title.
1285 * @access private
1286 */
1287 function getPageTitle($title,$nav_title) {
1288 return strcmp(trim($nav_title),'') ? $nav_title : $title;
1289 }
1290
1291 /**
1292 * Return MPvar string for entry $key in ->menuArr
1293 *
1294 * @param integer Pointer to element in ->menuArr
1295 * @param string Implode token.
1296 * @return string MP vars for element.
1297 * @see link()
1298 */
1299 function getMPvar($key) {
1300 if ($GLOBALS['TYPO3_CONF_VARS']['FE']['enable_mount_pids']) {
1301 $localMP_array = $this->MP_array;
1302 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!
1303 $MP_params = count($localMP_array) ? implode(',',$localMP_array) : '';
1304 return $MP_params;
1305 }
1306 }
1307
1308 /**
1309 * Returns where clause part to exclude 'not in menu' pages
1310 *
1311 * @return string where clause part.
1312 * @access private
1313 */
1314 function getDoktypeExcludeWhere() {
1315 return $this->doktypeExcludeList ? ' AND pages.doktype NOT IN ('.$this->doktypeExcludeList.')' : '';
1316 }
1317
1318 }
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338 /**
1339 * Extension class creating text based menus
1340 *
1341 * @author Kasper Skaarhoj <kasper@typo3.com>
1342 * @package TYPO3
1343 * @subpackage tslib
1344 * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=387&cHash=73a3116ab8
1345 */
1346 class tslib_tmenu extends tslib_menu {
1347
1348 /**
1349 * Calls procesItemStates() so that the common configuration for the menu items are resolved into individual configuration per item.
1350 * Sets the result for the new "normal state" in $this->result
1351 *
1352 * @return void
1353 * @see tslib_menu::procesItemStates()
1354 */
1355 function generate() {
1356 $splitCount = count($this->menuArr);
1357 if ($splitCount) {
1358 list($NOconf) = $this->procesItemStates($splitCount);
1359 }
1360 if ($this->mconf['debugItemConf']) {echo '<h3>$NOconf:</h3>'; debug($NOconf); }
1361 $this->result = $NOconf;
1362 }
1363
1364 /**
1365 * Traverses the ->result array of menu items configuration (made by ->generate()) and renders each item.
1366 * 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
1367 * 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.
1368 *
1369 * @return string The HTML for the menu (returns result through $this->extProc_finish(); )
1370 */
1371 function writeMenu() {
1372 if (is_array($this->result) && count($this->result)) {
1373 $this->WMcObj =t3lib_div::makeInstance('tslib_cObj'); // Create new tslib_cObj for our use
1374 $this->WMresult='';
1375 $this->INPfixMD5 = substr(md5(microtime().'tmenu'),0,4);
1376 $this->WMmenuItems = count($this->result);
1377 $this->extProc_init();
1378 reset($this->result);
1379 while (list($key,$val)=each($this->result)) {
1380 $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ']++;
1381 $GLOBALS['TSFE']->register['count_MENUOBJ']++;
1382
1383 $this->I=array();
1384 $this->WMcObj->start($this->menuArr[$key],'pages'); // Initialize the cObj with the page record of the menu item
1385 $this->I['key'] = $key;
1386 $this->I['INPfix']= $this->imgNameNotRandom?'':'_'.$this->INPfixMD5.'_'.$key;
1387 $this->I['val'] = $val;
1388 $this->I['title'] = $this->WMcObj->stdWrap($this->getPageTitle($this->menuArr[$key]['title'],$this->menuArr[$key]['nav_title']),$this->I['val']['stdWrap.']);
1389 $this->I['uid'] = $this->menuArr[$key]['uid'];
1390 $this->I['mount_pid'] = $this->menuArr[$key]['mount_pid'];
1391 $this->I['pid'] = $this->menuArr[$key]['pid'];
1392 $this->I['spacer'] = $this->menuArr[$key]['isSpacer'];
1393
1394 // Make link tag
1395 $this->I['val']['ATagParams'] = $this->I['val']['ATagParams'] ? ' '.$this->I['val']['ATagParams'] : '';
1396 $this->I['linkHREF'] = $this->link($key,$this->I['val']['altTarget'],$this->mconf['forceTypeValue']);
1397
1398 // Title attribute of links:
1399 $titleAttrValue = $this->WMcObj->stdWrap($this->I['val']['ATagTitle'],$this->I['val']['ATagTitle.']);
1400 if (strlen($titleAttrValue)) {
1401 $this->I['linkHREF']['title'] = $titleAttrValue;
1402 }
1403
1404 // Setting "blurlink()" function:
1405 if (!$this->mconf['noBlur']) {
1406 $this->I['linkHREF']['onFocus']='blurLink(this);';
1407 }
1408
1409 // Make link:
1410 if ($this->I['val']['RO']) {
1411 $this->I['theName'] = $this->imgNamePrefix.$this->I['uid'].$this->I['INPfix'];
1412 $over='';
1413 $out ='';
1414 if ($this->I['val']['beforeROImg']) {
1415 $over.= $this->WMfreezePrefix."over('".$this->I['theName']."before');";
1416 $out.= $this->WMfreezePrefix."out('".$this->I['theName']."before');";
1417 }
1418 if ($this->I['val']['afterROImg']) {
1419 $over.= $this->WMfreezePrefix."over('".$this->I['theName']."after');";
1420 $out.= $this->WMfreezePrefix."out('".$this->I['theName']."after');";
1421 }
1422 $this->I['linkHREF']['onMouseover']=$over;
1423 $this->I['linkHREF']['onMouseout']=$out;
1424 if ($over || $out) $GLOBALS['TSFE']->setJS('mouseOver');
1425
1426 // Change background color:
1427 if ($this->I['val']['RO_chBgColor']) {
1428 $this->addJScolorShiftFunction();
1429 $chBgP = t3lib_div::trimExplode('|',$this->I['val']['RO_chBgColor']);
1430 $this->I['linkHREF']['onMouseover'].="changeBGcolor('".$chBgP[2].$this->I['uid']."','".$chBgP[0]."');";
1431 $this->I['linkHREF']['onMouseout'].="changeBGcolor('".$chBgP[2].$this->I['uid']."','".$chBgP[1]."');";
1432 }
1433
1434 $this->extProc_RO($key);
1435 }
1436
1437
1438
1439 // Calling extra processing function
1440 $this->extProc_beforeLinking($key);
1441
1442 // Compile link tag
1443 if (!$this->I['val']['doNotLinkIt']) {$this->I['val']['doNotLinkIt']=0;}
1444 if (!$this->I['val']['isSpacer'] && $this->I['val']['doNotLinkIt']!=1) {
1445 $this->setATagParts();
1446 } else {
1447 $this->I['A1'] = '';
1448 $this->I['A2'] = '';
1449 }
1450
1451 // ATAGBeforeWrap processing:
1452 if ($this->I['val']['ATagBeforeWrap']) {
1453 $wrapPartsBefore = explode('|',$this->I['val']['linkWrap']);
1454 $wrapPartsAfter = array('','');
1455 } else {
1456 $wrapPartsBefore = array('','');
1457 $wrapPartsAfter = explode('|',$this->I['val']['linkWrap']);
1458 }
1459 if ($this->I['val']['stdWrap2'] || isset($this->I['val']['stdWrap2.'])) {
1460 $wrapPartsStdWrap = explode($this->I['val']['stdWrap2']?$this->I['val']['stdWrap2']:'|',$this->WMcObj->stdWrap('|',$this->I['val']['stdWrap2.']));
1461 } else {$wrapPartsStdWrap = array('','');}
1462
1463 // Make before, middle and after parts
1464 $this->I['parts'] = array();
1465 $this->I['parts']['before']=$this->getBeforeAfter('before');
1466 $this->I['parts']['stdWrap2_begin']=$wrapPartsStdWrap[0];
1467 if (!$this->I['val']['doNotShowLink']) {
1468 $this->I['parts']['notATagBeforeWrap_begin'] = $wrapPartsAfter[0];
1469 $this->I['parts']['ATag_begin'] = $this->I['A1'];
1470 $this->I['parts']['ATagBeforeWrap_begin'] = $wrapPartsBefore[0];
1471 $this->I['parts']['title'] = $this->I['title'];
1472 $this->I['parts']['ATagBeforeWrap_end'] = $wrapPartsBefore[1];
1473 $this->I['parts']['ATag_end'] = $this->I['A2'];
1474 $this->I['parts']['notATagBeforeWrap_end'] = $wrapPartsAfter[1];
1475 }
1476 $this->I['parts']['stdWrap2_end']=$wrapPartsStdWrap[1];
1477 $this->I['parts']['after']=$this->getBeforeAfter('after');
1478
1479 // Passing I to a user function
1480 if ($this->mconf['IProcFunc']) {
1481 $this->I = $this->userProcess('IProcFunc',$this->I);
1482 }
1483
1484 // Merge parts + beforeAllWrap
1485 $this->I['theItem']= implode('',$this->I['parts']);
1486 $this->I['theItem']= $this->extProc_beforeAllWrap($this->I['theItem'],$key);
1487
1488 // allWrap:
1489 $allWrap = $this->WMcObj->stdWrap($this->I['val']['allWrap'],$this->I['val']['allWrap.']);
1490 $this->I['theItem'] = $this->tmpl->wrap($this->I['theItem'],$allWrap);
1491
1492 if ($this->I['val']['subst_elementUid']) $this->I['theItem'] = str_replace('{elementUid}',$this->I['uid'],$this->I['theItem']);
1493
1494 // allStdWrap:
1495 if (is_array($this->I['val']['allStdWrap.'])) {
1496 $this->I['theItem'] = $this->WMcObj->stdWrap($this->I['theItem'],$this->I['val']['allStdWrap.']);
1497 }
1498
1499 // Calling extra processing function
1500 $this->extProc_afterLinking($key);
1501 }
1502 return $this->extProc_finish();
1503 }
1504 }
1505
1506 /**
1507 * Generates the before* and after* images for TMENUs
1508 *
1509 * @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
1510 * @return string The resulting HTML of the image, if any.
1511 * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=388&cHash=a7486044cd
1512 */
1513 function getBeforeAfter($pref) {
1514 $res = '';
1515 if ($imgInfo = $this->WMcObj->getImgResource($this->I['val'][$pref.'Img'],$this->I['val'][$pref.'Img.'])) {
1516 $imgInfo[3] = t3lib_div::png_to_gif_by_imagemagick($imgInfo[3]);
1517 if ($this->I['val']['RO'] && $this->I['val'][$pref.'ROImg'] && !$this->I['val']['isSpacer']) {
1518 $imgROInfo = $this->WMcObj->getImgResource($this->I['val'][$pref.'ROImg'],$this->I['val'][$pref.'ROImg.']);
1519 $imgROInfo[3] = t3lib_div::png_to_gif_by_imagemagick($imgROInfo[3]);
1520 if ($imgROInfo) {
1521 $theName = $this->imgNamePrefix.$this->I['uid'].$this->I['INPfix'].$pref;
1522 $name = ' name="'.$theName.'"';
1523 $GLOBALS['TSFE']->JSImgCode.= chr(10).$theName.'_n=new Image(); '.$theName.'_n.src = "'.$GLOBALS['TSFE']->absRefPrefix.$imgInfo[3].'"; ';
1524 $GLOBALS['TSFE']->JSImgCode.= chr(10).$theName.'_h=new Image(); '.$theName.'_h.src = "'.$GLOBALS['TSFE']->absRefPrefix.$imgROInfo[3].'"; ';
1525 }
1526 }
1527 $GLOBALS['TSFE']->imagesOnPage[]=$imgInfo[3];
1528 $res='<img src="'.$GLOBALS['TSFE']->absRefPrefix.$imgInfo[3].'" width="'.$imgInfo[0].'" height="'.$imgInfo[1].'"'.$name.($this->I['val'][$pref.'ImgTagParams']?" ".$this->I['val'][$pref.'ImgTagParams']:'').' border="0"';
1529 if (!strstr($res,'alt="')) $res.=' alt=""'; // Adding alt attribute if not set.
1530 $res.=' />';
1531 if ($this->I['val'][$pref.'ImgLink']) {$res=$this->I['A1'].$res.$this->I['A2'];}
1532 }
1533 return $this->tmpl->wrap($res.$this->WMcObj->stdWrap($this->I['val'][$pref],$this->I['val'][$pref.'.']), $this->I['val'][$pref.'Wrap']);
1534 }
1535
1536 /**
1537 * Adds a JavaScript function to the $GLOBALS['TSFE']->additionalJavaScript array
1538 *
1539 * @return void
1540 * @access private
1541 * @see writeMenu()
1542 */
1543 function addJScolorShiftFunction() {
1544 $GLOBALS['TSFE']->additionalJavaScript['TMENU:changeBGcolor()']='
1545 function changeBGcolor(id,color) { //
1546 if (document.getElementById && document.getElementById(id)) {
1547 document.getElementById(id).style.background = color;
1548 return true;
1549 } else if (document.layers && document.layers[id]) {
1550 document.layers[id].bgColor = color;
1551 return true;
1552 }
1553 }
1554 ';
1555 }
1556
1557 /**
1558 * Called right before the traversing of $this->result begins.
1559 * Can be used for various initialization
1560 *
1561 * @return void
1562 * @access private
1563 * @see writeMenu(), tslib_tmenu_layers::extProc_init()
1564 */
1565 function extProc_init() {
1566 }
1567
1568 /**
1569 * Called after all processing for RollOver of an element has been done.
1570 *
1571 * @param integer Pointer to $this->menuArr[$key] where the current menu element record is found
1572 * @return void
1573 * @access private
1574 * @see writeMenu(), tslib_tmenu_layers::extProc_RO()
1575 */
1576 function extProc_RO($key) {
1577 }
1578
1579 /**
1580 * Called right before the creation of the link for the menu item
1581 *
1582 * @param integer Pointer to $this->menuArr[$key] where the current menu element record is found
1583 * @return void
1584 * @access private
1585 * @see writeMenu(), tslib_tmenu_layers::extProc_beforeLinking()
1586 */
1587 function extProc_beforeLinking($key) {
1588 }
1589
1590 /**
1591 * 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.
1592 * This function MUST set $this->WMresult.=[HTML for menu item] to add the generated menu item to the internal accumulation of items.
1593 *
1594 * @param integer Pointer to $this->menuArr[$key] where the current menu element record is found
1595 * @return void
1596 * @access private
1597 * @see writeMenu(), tslib_tmenu_layers::extProc_afterLinking()
1598 */
1599 function extProc_afterLinking($key) {
1600 // Add part to the accumulated result + fetch submenus
1601 if (!$this->I['spacer']) {
1602 $this->I['theItem'].= $this->subMenu($this->I['uid']);
1603 }
1604 $this->WMresult.= $this->I['val']['wrapItemAndSub'] ? $this->tmpl->wrap($this->I['theItem'],$this->I['val']['wrapItemAndSub']) : $this->I['theItem'];
1605 }
1606
1607 /**
1608 * Called before the "allWrap" happens on the menu item.
1609 *
1610 * @param string The current content of the menu item, $this->I['theItem'], passed along.
1611 * @param integer Pointer to $this->menuArr[$key] where the current menu element record is found
1612 * @return string The modified version of $item, going back into $this->I['theItem']
1613 * @access private
1614 * @see writeMenu(), tslib_tmenu_layers::extProc_beforeAllWrap()
1615 */
1616 function extProc_beforeAllWrap($item,$key) {
1617 return $item;
1618 }
1619
1620 /**
1621 * Called before the writeMenu() function returns (only if a menu was generated)
1622 *
1623 * @return string The total menu content should be returned by this function
1624 * @access private
1625 * @see writeMenu(), tslib_tmenu_layers::extProc_finish()
1626 */
1627 function extProc_finish() {
1628 return $this->tmpl->wrap($this->WMresult,$this->mconf['wrap']).$this->WMextraScript;
1629 }
1630 }
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655 /**
1656 * Extension class creating graphic based menus (PNG or GIF files)
1657 *
1658 * @author Kasper Skaarhoj <kasper@typo3.com>
1659 * @package TYPO3
1660 * @subpackage tslib
1661 * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=384&cHash=93a7644cba
1662 */
1663 class tslib_gmenu extends tslib_menu {
1664
1665 /**
1666 * Calls procesItemStates() so that the common configuration for the menu items are resolved into individual configuration per item.
1667 * Calls makeGifs() for all "normal" items and if configured for, also the "rollover" items.
1668 *
1669 * @return void
1670 * @see tslib_menu::procesItemStates(), makeGifs()
1671 */
1672 function generate() {
1673 $splitCount = count($this->menuArr);
1674 if ($splitCount) {
1675 list($NOconf,$ROconf) = $this->procesItemStates($splitCount);
1676
1677 //store initial count value
1678 $temp_HMENU_MENUOBJ = $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ'];
1679 $temp_MENUOBJ = $GLOBALS['TSFE']->register['count_MENUOBJ'];
1680 // Now we generate the giffiles:
1681 $this->makeGifs($NOconf,'NO');
1682 // store count from NO obj
1683 $tempcnt_HMENU_MENUOBJ = $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ'];
1684 $tempcnt_MENUOBJ = $GLOBALS['TSFE']->register['count_MENUOBJ'];
1685
1686 if ($this->mconf['debugItemConf']) {echo '<h3>$NOconf:</h3>'; debug($NOconf); }
1687 if ($ROconf) { // RollOver
1688 //start recount for rollover with initial values
1689 $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ']= $temp_HMENU_MENUOBJ;
1690 $GLOBALS['TSFE']->register['count_MENUOBJ']= $temp_MENUOBJ;
1691 $this->makeGifs($ROconf,'RO');
1692 if ($this->mconf['debugItemConf']) {echo '<h3>$ROconf:</h3>'; debug($ROconf); }
1693 }
1694 // use count from NO obj
1695 $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ'] = $tempcnt_HMENU_MENUOBJ;
1696 $GLOBALS['TSFE']->register['count_MENUOBJ'] = $tempcnt_MENUOBJ;
1697 }
1698 }
1699
1700 /**
1701 * Will traverse input array with configuratoin per-item and create corresponding GIF files for the menu.
1702 * The data of the files are stored in $this->result
1703 *
1704 * @param array Array with configuration for each item.
1705 * @param string Type of images: normal ("NO") or rollover ("RO"). Valid values are "NO" and "RO"
1706 * @return void
1707 * @access private
1708 * @see generate()
1709 */
1710 function makeGifs($conf, $resKey) {
1711 $isGD = $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'];
1712
1713 if (!is_array($conf)) {
1714 $conf = Array();
1715 }
1716
1717 $totalWH=array();
1718 $items = count($conf);
1719 if ($isGD) {
1720 // generate the gif-files. the $menuArr is filled with some values like output_w, output_h, output_file
1721 $Hcounter = 0;
1722 $Wcounter = 0;
1723 $Hobjs = $this->mconf['applyTotalH'];
1724 if ($Hobjs) {$Hobjs = t3lib_div::intExplode(',',$Hobjs);}
1725 $Wobjs = $this->mconf['applyTotalW'];
1726 if ($Wobjs) {$Wobjs = t3lib_div::intExplode(',',$Wobjs);}
1727 $minDim = $this->mconf['min'];
1728 if ($minDim) {$minDim = tslib_cObj::calcIntExplode(',',$minDim.',');}
1729 $maxDim = $this->mconf['max'];
1730 if ($maxDim) {$maxDim = tslib_cObj::calcIntExplode(',',$maxDim.',');}
1731
1732 if ($minDim) {
1733 $conf[$items]=$conf[$items-1];
1734 $this->menuArr[$items]=Array();
1735 $items = count($conf);
1736 }
1737
1738 // TOTAL width
1739 if ($this->mconf['useLargestItemX'] || $this->mconf['useLargestItemY'] || $this->mconf['distributeX'] || $this->mconf['distributeY']) {
1740 $totalWH = $this->findLargestDims($conf,$items,$Hobjs,$Wobjs,$minDim,$maxDim);
1741 }
1742 }
1743
1744 $c=0;
1745 $maxFlag=0;
1746 $distributeAccu=array('H'=>0,'W'=>0);
1747 reset($conf);
1748 while (list($key,$val)=each($conf)) {
1749 $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ']++;
1750 $GLOBALS['TSFE']->register['count_MENUOBJ']++;
1751
1752 if ($items==($c+1) && $minDim) {
1753 $Lobjs = $this->mconf['removeObjectsOfDummy'];
1754 if ($Lobjs) {
1755 $Lobjs = t3lib_div::intExplode(',',$Lobjs);
1756 reset($Lobjs);
1757 while(list(,$remItem)=each($Lobjs)) {
1758 unset($val[$remItem]);
1759 unset($val[$remItem.'.']);
1760 }
1761 }
1762
1763 $flag =0;
1764 $tempXY = explode(',',$val['XY']);
1765 if ($Wcounter<$minDim[0]) {$tempXY[0]=$minDim[0]-$Wcounter; $flag=1;}
1766 if ($Hcounter<$minDim[1]) {$tempXY[1]=$minDim[1]-$Hcounter; $flag=1;}
1767 $val['XY'] = implode(',',$tempXY);
1768 if (!$flag){break;}
1769 }
1770 $c++;
1771
1772
1773 if ($isGD) {
1774 // Pre-working the item
1775 $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder');
1776 $gifCreator->init();
1777 $gifCreator->start($val,$this->menuArr[$key]);
1778
1779 // If useLargestItemH/W is specified
1780 if (count($totalWH) && ($this->mconf['useLargestItemX'] || $this->mconf['useLargestItemY'])) {
1781 $tempXY = explode(',',$gifCreator->setup['XY']);
1782 if ($this->mconf['useLargestItemX']) {$tempXY[0] = max($totalWH['W']);}
1783 if ($this->mconf['useLargestItemY']) {$tempXY[1] = max($totalWH['H']);}
1784 // regenerate the new values...
1785 $val['XY'] = implode(',',$tempXY);
1786 $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder');
1787 $gifCreator->init();
1788 $gifCreator->start($val,$this->menuArr[$key]);
1789 }
1790
1791 // If distributeH/W is specified
1792 if (count($totalWH) && ($this->mconf['distributeX'] || $this->mconf['distributeY'])) {
1793 $tempXY = explode(',',$gifCreator->setup['XY']);
1794
1795 if ($this->mconf['distributeX']) {
1796 $diff = $this->mconf['distributeX']-$totalWH['W_total']-$distributeAccu['W'];
1797 $compensate = round($diff /($items-$c+1));
1798 $distributeAccu['W']+=$compensate;
1799 $tempXY[0] = $totalWH['W'][$key]+$compensate;
1800 }
1801 if ($this->mconf['distributeY']) {
1802 $diff = $this->mconf['distributeY']-$totalWH['H_total']-$distributeAccu['H'];
1803 $compensate = round($diff /($items-$c+1));
1804 $distributeAccu['H']+=$compensate;
1805 $tempXY[1] = $totalWH['H'][$key]+$compensate;
1806 }
1807 // regenerate the new values...
1808 $val['XY'] = implode(',',$tempXY);
1809 $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder');
1810 $gifCreator->init();
1811 $gifCreator->start($val,$this->menuArr[$key]);
1812 }
1813
1814 // If max dimensions are specified
1815 if ($maxDim) {
1816 $tempXY = explode(',',$val['XY']);
1817 if ($maxDim[0] && $Wcounter+$gifCreator->XY[0]>=$maxDim[0]) {$tempXY[0]==$maxDim[0]-$Wcounter; $maxFlag=1;}
1818 if ($maxDim[1] && $Hcounter+$gifCreator->XY[1]>=$maxDim[1]) {$tempXY[1]=$maxDim[1]-$Hcounter; $maxFlag=1;}
1819 if ($maxFlag) {
1820 $val['XY'] = implode(',',$tempXY);
1821 $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder');
1822 $gifCreator->init();
1823 $gifCreator->start($val,$this->menuArr[$key]);
1824 }
1825 }
1826
1827
1828
1829
1830 // displace
1831 if ($Hobjs) {
1832 reset($Hobjs);
1833 while(list(,$index)=each($Hobjs)) {
1834 if ($gifCreator->setup[$index] && $gifCreator->setup[$index.'.']) {
1835 $oldOffset = explode(',',$gifCreator->setup[$index.'.']['offset']);
1836 $gifCreator->setup[$index.'.']['offset'] = implode(',',$gifCreator->applyOffset($oldOffset,Array(0,-$Hcounter)));
1837 }
1838 }
1839 }
1840
1841 if ($Wobjs) {
1842 reset($Wobjs);
1843 while(list(,$index)=each($Wobjs)) {
1844 if ($gifCreator->setup[$index] && $gifCreator->setup[$index.'.']) {
1845 $oldOffset = explode(',',$gifCreator->setup[$index.'.']['offset']);
1846 $gifCreator->setup[$index.'.']['offset'] = implode(',',$gifCreator->applyOffset($oldOffset,Array(-$Wcounter,0)));
1847 }
1848 }
1849 }
1850 }
1851
1852 // Finding alternative GIF names if any (by altImgResource)
1853 $gifFileName='';
1854 if ($conf[$key]['altImgResource'] || is_array($conf[$key]['altImgResource.'])) {
1855 if (!is_object($cObj)) {$cObj=t3lib_div::makeInstance('tslib_cObj');}
1856 $cObj->start($this->menuArr[$key],'pages');
1857 $altImgInfo = $cObj->getImgResource($conf[$key]['altImgResource'],$conf[$key]['altImgResource.']);
1858 $gifFileName=$altImgInfo[3];
1859 }
1860
1861 // If an alternative name was NOT given, find the GIFBUILDER name.
1862 if (!$gifFileName && $isGD) {
1863 $gifCreator->createTempSubDir('menu/');
1864 $gifFileName = $gifCreator->fileName('menu/');
1865 }
1866
1867 // Generation of image file:
1868 if (@file_exists($gifFileName)) { // File exists
1869 $info = @getimagesize($gifFileName);
1870 $this->result[$resKey][$key]['output_w']=intval($info[0]);
1871 $this->result[$resKey][$key]['output_h']=intval($info[1]);
1872 $this->result[$resKey][$key]['output_file']=$gifFileName;
1873 } elseif ($isGD) { // file is generated
1874 $gifCreator->make();
1875 $this->result[$resKey][$key]['output_w']=$gifCreator->w;
1876 $this->result[$resKey][$key]['output_h']=$gifCreator->h;
1877 $this->result[$resKey][$key]['output_file'] = $gifFileName;
1878 $gifCreator->output($this->result[$resKey][$key]['output_file']);
1879 $gifCreator->destroy();
1880 }
1881 $this->result[$resKey][$key]['output_file'] = t3lib_div::png_to_gif_by_imagemagick($this->result[$resKey][$key]['output_file']);
1882 $this->result[$resKey][$key]['noLink']=$conf[$key]['noLink'];
1883 $this->result[$resKey][$key]['altTarget']=$conf[$key]['altTarget'];
1884 $this->result[$resKey][$key]['imgParams']=$conf[$key]['imgParams'];
1885 $this->result[$resKey][$key]['ATagTitle'] = $conf[$key]['ATagTitle'];
1886 $this->result[$resKey][$key]['ATagTitle.'] = $conf[$key]['ATagTitle.'];
1887 $this->result[$resKey][$key]['wrap'] = $conf[$key]['wrap'];
1888 $this->result[$resKey][$key]['allWrap'] = $conf[$key]['allWrap'];
1889 $this->result[$resKey][$key]['allWrap.'] = $conf[$key]['allWrap.'];
1890 $this->result[$resKey][$key]['subst_elementUid'] = $conf[$key]['subst_elementUid'];
1891 $this->result[$resKey][$key]['allStdWrap.'] = $conf[$key]['allStdWrap.'];
1892
1893 $Hcounter+=$this->result[$resKey][$key]['output_h']; // counter is increased
1894 $Wcounter+=$this->result[$resKey][$key]['output_w']; // counter is increased
1895
1896 if ($maxFlag){break;}
1897 }
1898 }
1899
1900 /**
1901 * Function searching for the largest width and height of the menu items to be generated.
1902 * 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.
1903 * Remember to upgrade the code in here if the makeGifs function is updated.
1904 *
1905 * @param array Same configuration array as passed to makeGifs()
1906 * @param integer The number of menu items
1907 * @param array Array with "applyTotalH" numbers
1908 * @param array Array with "applyTotalW" numbers
1909 * @param array Array with "min" x/y
1910 * @param array Array with "max" x/y
1911 * @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.
1912 * @access private
1913 * @see makeGifs()
1914 */
1915 function findLargestDims($conf,$items,$Hobjs,$Wobjs,$minDim,$maxDim) {
1916 $totalWH = array(
1917 'W' => array(),
1918 'H' => array(),
1919 'W_total' => 0,
1920 'H_total' => 0
1921 );
1922
1923 $Hcounter = 0;
1924 $Wcounter = 0;
1925 $c=0;
1926 $maxFlag=0;
1927 reset($conf);
1928 while (list($key,$val)=each($conf)) {
1929 // SAME CODE AS makeGifs()! BEGIN
1930 if ($items==($c+1) && $minDim) {
1931 $Lobjs = $this->mconf['removeObjectsOfDummy'];
1932 if ($Lobjs) {
1933 $Lobjs = t3lib_div::intExplode(',',$Lobjs);
1934 reset($Lobjs);
1935 while(list(,$remItem)=each($Lobjs)) {
1936 unset($val[$remItem]);
1937 unset($val[$remItem.'.']);
1938 }
1939 }
1940
1941 $flag =0;
1942 $tempXY = explode(',',$val['XY']);
1943 if ($Wcounter<$minDim[0]) {$tempXY[0]=$minDim[0]-$Wcounter; $flag=1;}
1944 if ($Hcounter<$minDim[1]) {$tempXY[1]=$minDim[1]-$Hcounter; $flag=1;}
1945 $val['XY'] = implode(',',$tempXY);
1946 if (!$flag){break;}
1947 }
1948 $c++;
1949
1950 $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder');
1951 $gifCreator->init();
1952 $gifCreator->start($val,$this->menuArr[$key]);
1953 if ($maxDim) {
1954 $tempXY = explode(',',$val['XY']);
1955 if ($maxDim[0] && $Wcounter+$gifCreator->XY[0]>=$maxDim[0]) {$tempXY[0]==$maxDim[0]-$Wcounter; $maxFlag=1;}
1956 if ($maxDim[1] && $Hcounter+$gifCreator->XY[1]>=$maxDim[1]) {$tempXY[1]=$maxDim[1]-$Hcounter; $maxFlag=1;}
1957 if ($maxFlag) {
1958 $val['XY'] = implode(',',$tempXY);
1959 $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder');
1960 $gifCreator->init();
1961 $gifCreator->start($val,$this->menuArr[$key]);
1962 }
1963 }
1964 // SAME CODE AS makeGifs()! END
1965
1966 // Setting the width/height
1967 $totalWH['W'][$key]=$gifCreator->XY[0];
1968 $totalWH['H'][$key]=$gifCreator->XY[1];
1969 $totalWH['W_total']+=$gifCreator->XY[0];
1970 $totalWH['H_total']+=$gifCreator->XY[1];
1971 // ---- //
1972
1973 $Hcounter+=$gifCreator->XY[1]; // counter is increased
1974 $Wcounter+=$gifCreator->XY[0]; // counter is increased
1975
1976 if ($maxFlag){break;}
1977 }
1978 return $totalWH;
1979 }
1980
1981 /**
1982 * 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())
1983 * 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
1984 *
1985 * @return string The HTML for the menu (returns result through $this->extProc_finish(); )
1986 */
1987 function writeMenu() {
1988 if (is_array($this->menuArr) && is_array($this->result) && count($this->result) && is_array($this->result['NO'])) {
1989 $this->WMcObj = t3lib_div::makeInstance('tslib_cObj'); // Create new tslib_cObj for our use
1990 $this->WMresult='';
1991 $this->INPfixMD5 = substr(md5(microtime().$this->GMENU_fixKey),0,4);
1992 $this->WMmenuItems = count($this->result['NO']);
1993 $this->extProc_init();
1994 for ($key=0;$key<$this->WMmenuItems;$key++) {
1995 if ($this->result['NO'][$key]['output_file']) {
1996 $this->WMcObj->start($this->menuArr[$key],'pages'); // Initialize the cObj with the page record of the menu item
1997
1998 $this->I =array();
1999 $this->I['key'] = $key;
2000 $this->I['INPfix']= $this->imgNameNotRandom?'':'_'.$this->INPfixMD5.'_'.$key;
2001 $this->I['val'] = $this->result['NO'][$key];
2002 $this->I['title'] = $this->getPageTitle($this->menuArr[$key]['title'],$this->menuArr[$key]['nav_title']);
2003 $this->I['uid'] = $this->menuArr[$key]['uid'];
2004 $this->I['mount_pid'] = $this->menuArr[$key]['mount_pid'];
2005 $this->I['pid'] = $this->menuArr[$key]['pid'];
2006 $this->I['spacer'] = $this->menuArr[$key]['isSpacer'];
2007 if (!$this->I['uid'] && !$this->menuArr[$key]['_OVERRIDE_HREF']) {$this->I['spacer']=1;}
2008 $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
2009 $this->I['name']='';
2010
2011 // Get link.
2012 $this->I['linkHREF'] = $this->link($key,$this->I['val']['altTarget'],$this->mconf['forceTypeValue']);
2013 // Title attribute of links:
2014 $titleAttrValue = $this->WMcObj->stdWrap($this->I['val']['ATagTitle'],$this->I['val']['ATagTitle.']);
2015 if (strlen($titleAttrValue)) {
2016 $this->I['linkHREF']['title'] = $titleAttrValue;
2017 }
2018 // Setting "blurlink()" function:
2019 if (!$this->mconf['noBlur']) {
2020 $this->I['linkHREF']['onFocus']='blurLink(this);';
2021 }
2022
2023 // Set rollover
2024 if ($this->result['RO'][$key] && !$this->I['noLink']) {
2025 $this->I['theName'] = $this->imgNamePrefix.$this->I['uid'].$this->I['INPfix'];
2026 $this->I['name'] = ' name="'.$this->I["theName"].'"';
2027 $this->I['linkHREF']['onMouseover']=$this->WMfreezePrefix.'over(\''.$this->I['theName'].'\');';
2028 $this->I['linkHREF']['onMouseout']=$this->WMfreezePrefix.'out(\''.$this->I['theName'].'\');';
2029 $GLOBALS['TSFE']->JSImgCode.= chr(10).$this->I['theName'].'_n=new Image(); '.$this->I['theName'].'_n.src = "'.$GLOBALS['TSFE']->absRefPrefix.$this->I['val']['output_file'].'"; ';
2030 $GLOBALS['TSFE']->JSImgCode.= chr(10).$this->I['theName'].'_h=new Image(); '.$this->I['theName'].'_h.src = "'.$GLOBALS['TSFE']->absRefPrefix.$this->result['RO'][$key]['output_file'].'"; ';
2031 $GLOBALS['TSFE']->imagesOnPage[]=$this->result['RO'][$key]['output_file'];
2032 $GLOBALS['TSFE']->setJS('mouseOver');
2033 $this->extProc_RO($key);
2034 }
2035 // Set access key
2036 if ($this->mconf['accessKey']) {
2037 $this->I['accessKey'] = $this->accessKey($this->I['title']);
2038 } else {
2039 $this->I['accessKey']=Array();
2040 }
2041
2042 // Set altText
2043 $this->I['altText'] = $this->mconf['disableAltText'] ? '' : $this->I['title'].$this->I['accessKey']['alt'];
2044
2045 // Calling extra processing function
2046 $this->extProc_beforeLinking($key);
2047
2048 // Set linking
2049 if (!$this->I['noLink']) {
2050 $this->setATagParts();
2051 } else {
2052 $this->I['A1'] = '';
2053 $this->I['A2'] = '';
2054 }
2055 $this->I['IMG'] = '<img src="'.$GLOBALS['TSFE']->absRefPrefix.$this->I['val']['output_file'].'" width="'.$this->I['val']['output_w'].'" height="'.$this->I['val']['output_h'].'" border="0" alt="'.htmlspecialchars($this->I['altText']).'"'.$this->I['name'].($this->I['val']['imgParams']?' '.$this->I['val']['imgParams']:'').' />';
2056
2057 // Make before, middle and after parts
2058 $this->I['parts'] = array();
2059 $this->I['parts']['ATag_begin'] = $this->I['A1'];
2060 $this->I['parts']['image'] = $this->I['IMG'];
2061 $this->I['parts']['ATag_end'] = $this->I['A2'];
2062
2063 // Passing I to a user function
2064 if ($this->mconf['IProcFunc']) {
2065 $this->I = $this->userProcess('IProcFunc',$this->I);
2066 }
2067
2068 // Putting the item together.
2069 // Merge parts + beforeAllWrap
2070 $this->I['theItem']= implode('',$this->I['parts']);
2071 $this->I['theItem']= $this->extProc_beforeAllWrap($this->I['theItem'],$key);
2072
2073 // wrap:
2074 $this->I['theItem']= $this->tmpl->wrap($this->I['theItem'],$this->I['val']['wrap']);
2075
2076 // allWrap:
2077 $allWrap = $this->WMcObj->stdWrap($this->I['val']['allWrap'],$this->I['val']['allWrap.']);
2078 $this->I['theItem'] = $this->tmpl->wrap($this->I['theItem'],$allWrap);
2079
2080 if ($this->I['val']['subst_elementUid']) $this->I['theItem'] = str_replace('{elementUid}',$this->I['uid'],$this->I['theItem']);
2081
2082 // allStdWrap:
2083 if (is_array($this->I['val']['allStdWrap.'])) {
2084 $this->I['theItem'] = $this->WMcObj->stdWrap($this->I['theItem'],$this->I['val']['allStdWrap.']);
2085 }
2086
2087 $GLOBALS['TSFE']->imagesOnPage[]=$this->I['val']['output_file'];
2088
2089 $this->extProc_afterLinking($key);
2090 }
2091 }
2092 return $this->extProc_finish();
2093 }
2094 }
2095
2096 /**
2097 * Called right before the traversing of $this->result begins.
2098 * Can be used for various initialization
2099 *
2100 * @return void
2101 * @access private
2102 * @see writeMenu(), tslib_gmenu_layers::extProc_init()
2103 */
2104 function extProc_init() {
2105 }
2106
2107 /**
2108 * Called after all processing for RollOver of an element has been done.
2109 *
2110 * @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!
2111 * @return void
2112 * @access private
2113 * @see writeMenu(), tslib_gmenu_layers::extProc_RO()
2114 */
2115 function extProc_RO($key) {
2116 }
2117
2118 /**
2119 * Called right before the creation of the link for the menu item
2120 *
2121 * @param integer Pointer to $this->menuArr[$key] where the current menu element record is found
2122 * @return void
2123 * @access private
2124 * @see writeMenu(), tslib_gmenu_layers::extProc_beforeLinking()
2125 */
2126 function extProc_beforeLinking($key) {
2127 }
2128
2129 /**
2130 * 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.
2131 * This function MUST set $this->WMresult.=[HTML for menu item] to add the generated menu item to the internal accumulation of items.
2132 * Further this calls the subMenu function in the parent class to create any submenu there might be.
2133 *
2134 * @param integer Pointer to $this->menuArr[$key] where the current menu element record is found
2135 * @return void
2136 * @access private
2137 * @see writeMenu(), tslib_gmenu_layers::extProc_afterLinking(), tslib_menu::subMenu()
2138 */
2139 function extProc_afterLinking($key) {
2140 $this->WMresult.=$this->I['theItem'];
2141 if (!$this->I['spacer']) {
2142 $this->WMresult.= $this->subMenu($this->I['uid']);
2143 }
2144 }
2145
2146
2147 /**
2148 * Called before the "wrap" happens on the menu item.
2149 *
2150 * @param string The current content of the menu item, $this->I['theItem'], passed along.
2151 * @param integer Pointer to $this->menuArr[$key] where the current menu element record is found
2152 * @return string The modified version of $item, going back into $this->I['theItem']
2153 * @access private
2154 * @see writeMenu(), tslib_gmenu_layers::extProc_beforeAllWrap()
2155 */
2156 function extProc_beforeAllWrap($item,$key) {
2157 return $item;
2158 }
2159
2160 /**
2161 * Called before the writeMenu() function returns (only if a menu was generated)
2162 *
2163 * @return string The total menu content should be returned by this function
2164 * @access private
2165 * @see writeMenu(), tslib_gmenu_layers::extProc_finish()
2166 */
2167 function extProc_finish() {
2168 return $this->tmpl->wrap($this->WMresult,$this->mconf['wrap']).$this->WMextraScript;
2169 }
2170 }
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193 /**
2194 * ImageMap based menus
2195 *
2196 * @author Kasper Skaarhoj <kasper@typo3.com>
2197 * @package TYPO3
2198 * @subpackage tslib
2199 * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=389&cHash=fcf18c5d9f
2200 */
2201 class tslib_imgmenu extends tslib_menu {
2202
2203 /**
2204 * Calls procesItemStates() so that the common configuration for the menu items are resolved into individual configuration per item.
2205 * Calls makeImageMap() to generate the image map image-file
2206 *
2207 * @return void
2208 * @see tslib_menu::procesItemStates(), makeImageMap()
2209 */
2210 function generate() {
2211 $splitCount = count($this->menuArr);
2212 if ($splitCount) {
2213 list($NOconf) = $this->procesItemStates($splitCount);
2214 }
2215 if ($this->mconf['debugItemConf']) {echo '<h3>$NOconf:</h3>'; debug($NOconf); }
2216 $this->makeImageMap($NOconf);
2217 }
2218
2219 /**
2220 * Will traverse input array with configuratoin per-item and create corresponding GIF files for the menu.
2221 * The data of the files are stored in $this->result
2222 *
2223 * @param array Array with configuration for each item.
2224 * @return void
2225 * @access private
2226 * @see generate()
2227 */
2228 function makeImageMap($conf) {
2229 if (!is_array($conf)) {
2230 $conf = Array();
2231 }
2232 if (is_array($this->mconf['main.'])) {
2233 $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder');
2234 $gifCreator->init();
2235
2236 $itemsConf = $conf;
2237 $conf = $this->mconf['main.'];
2238 if (is_array($conf)) {
2239 $gifObjCount = 0;
2240
2241 $sKeyArray=t3lib_TStemplate::sortedKeyList($conf);
2242 $gifObjCount=intval(end($sKeyArray));
2243
2244 $lastOriginal = $gifObjCount;
2245
2246 // Now we add graphical objects to the gifbuilder-setup
2247 reset($itemsConf);
2248 $waArr = Array();
2249 while (list($key,$val)=each($itemsConf)) {
2250 if (is_array($val)) {
2251 $gifObjCount++;
2252 $waArr[$key]['free']=$gifObjCount;
2253
2254 $sKeyArray=t3lib_TStemplate::sortedKeyList($val);
2255
2256 foreach($sKeyArray as $theKey) {
2257 $theValue=$val[$theKey];
2258
2259
2260 if (intval($theKey) && $theValArr=$val[$theKey.'.']) {
2261 $cObjData = $this->menuArr[$key] ? $this->menuArr[$key] : Array();
2262
2263 $gifObjCount++;
2264 if ($theValue=='TEXT') {
2265 $waArr[$key]['textNum']=$gifObjCount;
2266
2267 $gifCreator->data = $cObjData;
2268 $theValArr = $gifCreator->checkTextObj($theValArr);
2269 unset($theValArr['text.']); // if this is not done it seems that imageMaps will be rendered wrong!!
2270 // check links
2271
2272 $LD = $this->tmpl->linkData($this->menuArr[$key],$this->mconf['target'],'','',array(),'',$this->mconf['forceTypeValue']);
2273
2274 // Overriding URL / Target if set to do so:
2275 if ($this->menuArr[$key]['_OVERRIDE_HREF']) {
2276 $LD['totalURL'] = $this->menuArr[$key]['_OVERRIDE_HREF'];
2277 if ($this->menuArr[$key]['_OVERRIDE_TARGET']) $LD['target'] = $this->menuArr[$key]['_OVERRIDE_TARGET'];
2278 }
2279
2280 // Setting target/url for Image Map:
2281 if ($theValArr['imgMap.']['url']=='') {
2282 $theValArr['imgMap.']['url'] = $LD['totalURL'];
2283 }
2284 if ($theValArr['imgMap.']['target']=='') {
2285 $theValArr['imgMap.']['target'] = $LD['target'];
2286 }
2287 if ($theValArr['imgMap.']['noBlur']=='') {
2288 $theValArr['imgMap.']['noBlur'] = $this->mconf['noBlur'];
2289 }
2290 if (is_array($theValArr['imgMap.']['altText.'])) {
2291 $cObj =t3lib_div::makeInstance('tslib_cObj');
2292 $cObj->start($cObjData,'pages');
2293 $theValArr['imgMap.']['altText'] = $cObj->stdWrap($theValArr['imgMap.']['altText'], $theValArr['imgMap.']['altText.']);
2294 unset($theValArr['imgMap.']['altText.']);
2295 }
2296 if (is_array($theValArr['imgMap.']['titleText.'])) {
2297 $cObj =t3lib_div::makeInstance('tslib_cObj');
2298 $cObj->start($cObjData,'pages');
2299 $theValArr['imgMap.']['titleText'] = $cObj->stdWrap($theValArr['imgMap.']['titleText'], $theValArr['imgMap.']['titleText.']);
2300 unset($theValArr['imgMap.']['titleText.']);
2301 }
2302 }
2303 // 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!!
2304 if ($theValue=='IMAGE') {
2305 if ($theValArr['file']=='GIFBUILDER') {
2306 $temp_sKeyArray=t3lib_TStemplate::sortedKeyList($theValArr['file.']);
2307 reset($temp_sKeyArray);
2308 while(list(,$temp_theKey)=each($temp_sKeyArray)) {
2309 if ($theValArr['mask.'][$temp_theKey]=='TEXT') {
2310 $gifCreator->data = $this->menuArr[$key] ? $this->menuArr[$key] : Array();
2311 $theValArr['mask.'][$temp_theKey.'.'] = $gifCreator->checkTextObj($theValArr['mask.'][$temp_theKey.'.']);
2312 unset($theValArr['mask.'][$temp_theKey.'.']['text.']); // if this is not done it seems that imageMaps will be rendered wrong!!
2313 }
2314 }
2315 }
2316 if ($theValArr['mask']=='GIFBUILDER') {
2317 $temp_sKeyArray=t3lib_TStemplate::sortedKeyList($theValArr['mask.']);
2318 reset($temp_sKeyArray);
2319 while(list(,$temp_theKey)=each($temp_sKeyArray)) {
2320 if ($theValArr['mask.'][$temp_theKey]=='TEXT') {
2321 $gifCreator->data = $this->menuArr[$key] ? $this->menuArr[$key] : Array();
2322 $theValArr['mask.'][$temp_theKey.'.'] = $gifCreator->checkTextObj($theValArr['mask.'][$temp_theKey.'.']);
2323 unset($theValArr['mask.'][$temp_theKey.'.']['text.']); // if this is not done it seems that imageMaps will be rendered wrong!!
2324 }
2325 }
2326 }
2327 }
2328
2329 // Checks if disabled is set...
2330 $setObjFlag=1;
2331 if ($theValArr['if.']) {
2332 $cObj =t3lib_div::makeInstance('tslib_cObj');
2333 $cObj->start($cObjData,'pages');
2334 if (!$cObj->checkIf($theValArr['if.'])) {
2335 $setObjFlag=0;
2336 }
2337 unset($theValArr['if.']);
2338 }
2339 // Set the object!
2340 if ($setObjFlag) {
2341 $conf[$gifObjCount] = $theValue;
2342 $conf[$gifObjCount.'.'] = $theValArr;
2343 }
2344 }
2345 }
2346 }
2347 }
2348
2349 $gifCreator->start($conf,$GLOBALS['TSFE']->page);
2350 // calculations
2351
2352 $sum=Array(0,0,0,0);
2353 reset($waArr);
2354 while (list($key,$val)=each($waArr)) {
2355 if ($dConf[$key] =$itemsConf[$key]['distrib']) {
2356 $textBB = $gifCreator->objBB[$val['textNum']];
2357 $dConf[$key] = str_replace('textX',$textBB[0],$dConf[$key]);
2358 $dConf[$key] = str_replace('textY',$textBB[1],$dConf[$key]);
2359 $dConf[$key] = t3lib_div::intExplode(',',$gifCreator->calcOffset($dConf[$key]));
2360 }
2361 }
2362 $workArea = t3lib_div::intExplode(',',$gifCreator->calcOffset($this->mconf['dWorkArea']));
2363 reset($waArr);
2364 while (list($key,$val)=each($waArr)) {
2365 $index = $val['free'];
2366 $gifCreator->setup[$index] = 'WORKAREA';
2367 $workArea[2] = $dConf[$key][2] ? $dConf[$key][2] : $dConf[$key][0];
2368 $workArea[3] = $dConf[$key][3] ? $dConf[$key][3] : $dConf[$key][1];
2369
2370 $gifCreator->setup[$index.'.']['set'] = implode(',',$workArea);
2371 $workArea[0]+=$dConf[$key][0];
2372 $workArea[1]+=$dConf[$key][1];
2373 }
2374
2375 if ($this->mconf['debugRenumberedObject']) {echo '<h3>Renumbered GIFBUILDER object:</h3>'; debug($gifCreator->setup);}
2376
2377 $gifCreator->createTempSubDir('menu/');
2378 $gifFileName = $gifCreator->fileName('menu/');
2379
2380 // Gets the ImageMap from the cache...
2381 $imgHash = md5($gifFileName);
2382 $imgMap = $this->sys_page->getHash($imgHash, 0);
2383
2384 if ($imgMap && @file_exists($gifFileName)) { // File exists
2385 $info = @getimagesize($gifFileName);
2386 $w=$info[0];
2387 $h=$info[1];
2388 } else { // file is generated
2389 $gifCreator->make();
2390 $w=$gifCreator->w;
2391 $h=$gifCreator->h;
2392 $gifCreator->output($gifFileName);
2393 $gifCreator->destroy();
2394 $imgMap=$gifCreator->map;
2395 $this->sys_page->storeHash($imgHash, $imgMap, 'MENU IMAGEMAP');
2396 }
2397 $imgMap.=$this->mconf['imgMapExtras'];
2398
2399 $gifFileName = t3lib_div::png_to_gif_by_imagemagick($gifFileName);
2400 $this->result = Array('output_file'=>$gifFileName, 'output_w'=>$w, 'output_h'=>$h, 'imgMap'=>$imgMap);
2401 }
2402 }
2403 }
2404
2405 /**
2406 * Returns the HTML for the image map menu.
2407 * If ->result is true it will create the HTML for the image map menu.
2408 *
2409 * @return string The HTML for the menu
2410 */
2411 function writeMenu() {
2412 if ($this->result) {
2413 $res = $this->result;
2414 $menuName = 'menu_'.t3lib_div::shortMD5($res['imgMap']); // shortMD5 260900
2415 $result = '<img src="'.$GLOBALS['TSFE']->absRefPrefix.$res['output_file'].'" width="'.$res['output_w'].'" height="'.$res['output_h'].'" usemap="#'.$menuName.'" border="0" '.$this->mconf['params'];
2416 if (!strstr($result,'alt="')) $result.=' alt="Menu Image Map"'; // Adding alt attribute if not set.
2417 $result.= ' /><map name="'.$menuName.'" id="'.$menuName.'">'.$res['imgMap'].'</map>';
2418
2419 $GLOBALS['TSFE']->imagesOnPage[]=$res['output_file'];
2420
2421 return $this->tmpl->wrap($result,$this->mconf['wrap']);
2422 }
2423 }
2424 }
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446 /**
2447 * JavaScript/Selectorbox based menus
2448 *
2449 * @author Kasper Skaarhoj <kasper@typo3.com>
2450 * @package TYPO3
2451 * @subpackage tslib
2452 * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=391&cHash=563435abbc
2453 */
2454 class tslib_jsmenu extends tslib_menu {
2455
2456 /**
2457 * Dummy. Should do nothing, because we don't use the result-array here!
2458 *
2459 * @return void
2460 */
2461 function generate() {
2462 }
2463
2464 /**
2465 * Creates the HTML (mixture of a <form> and a JavaScript section) for the JavaScript menu (basically an array of selector boxes with onchange handlers)
2466 *
2467 * @return string The HTML code for the menu
2468 */
2469 function writeMenu() {
2470 if ($this->id) {
2471 // Making levels:
2472 $levels = t3lib_div::intInRange($this->mconf['levels'],1,5);
2473 $this->levels = $levels;
2474 $this->JSVarName='eid';
2475 $this->JSMenuName= $this->mconf['menuName'] ? $this->mconf['menuName'] : 'JSmenu';
2476
2477 $JScode="\n var ".$this->JSMenuName." = new JSmenu(".$levels.",'".$this->JSMenuName."Form');";
2478
2479 for ($a=1;$a<=$levels;$a++) {
2480 $JScode.="\n var ".$this->JSVarName.$a."=0;";
2481 }
2482 $JScode.= $this->generate_level($levels,1,$this->id,$this->menuArr,$this->MP_array)."\n";
2483
2484 $GLOBALS['TSFE']->additionalHeaderData['JSMenuCode']='<script type="text/javascript" src="'.$GLOBALS['TSFE']->absRefPrefix.'t3lib/jsfunc.menu.js"></script>';
2485 $GLOBALS['TSFE']->JSCode.=$JScode;
2486
2487 // Printing:
2488 $allFormCode="";
2489 for ($a=1;$a<=$this->levels;$a++) {
2490 $formCode='';
2491 $levelConf = $this->mconf[$a.'.'];
2492 $length = $levelConf['width'] ? $levelConf['width'] : 14;
2493 $lenghtStr='';
2494 for ($b=0;$b<$length;$b++) {
2495 $lenghtStr.='_';
2496 }
2497 $height = $levelConf['elements'] ? $levelConf['elements'] : 5;
2498
2499 $formCode.= '<select name="selector'.$a.'" onchange="'.$this->JSMenuName.'.act('.$a.');"'.($levelConf['additionalParams']?' '.$levelConf['additionalParams']:'').'>';
2500 for ($b=0;$b<$height;$b++) {
2501 $formCode.= '<option value="0">';
2502 if ($b==0) {
2503 $formCode.= $lenghtStr;
2504 }
2505 $formCode.='</option>';
2506 }
2507 $formCode.= '</select>';
2508 $allFormCode.=$this->tmpl->wrap($formCode,$levelConf['wrap']);
2509 }
2510 $formCode = $this->tmpl->wrap($allFormCode,$this->mconf['wrap']);
2511
2512 $formCode= '<form action="" method="post" style="margin: 0 0 0 0;" name="'.$this->JSMenuName.'Form">'.$formCode.'</form>';
2513 $formCode.='<script type="text/javascript"> /*<![CDATA[*/ '.$this->JSMenuName.'.writeOut(1,'.$this->JSMenuName.'.openID,1); /*]]>*/ </script>';
2514 return $this->tmpl->wrap($formCode,$this->mconf['wrapAfterTags']);
2515 }
2516 }
2517
2518 /**
2519 * Generates a number of lines of JavaScript code for a menu level.
2520 * Calls itself recursively for additional levels.
2521 *
2522 * @param integer Number of levels to generate
2523 * @param integer Current level being generated - and if this number is less than $levels it will call itself recursively with $count incremented
2524 * @param integer Page id of the starting point.
2525 * @param array $this->menuArr passed along
2526 * @param array Previous MP vars
2527 * @return string JavaScript code lines.
2528 * @access private
2529 */
2530 function generate_level($levels,$count,$pid,$menuItemArray='',$MP_array=array()) {
2531 $levelConf = $this->mconf[$count.'.'];
2532
2533 // Translate PID to a mount page, if any:
2534 $mount_info = $this->sys_page->getMountPointInfo($pid);
2535 if (is_array($mount_info)) {
2536 $MP_array[] = $mount_info['MPvar'];
2537 $pid = $mount_info['mount_pid'];
2538 }
2539
2540 // Set "&MP=" var:
2541 $MP_var = implode(',',$MP_array);
2542 $MP_params = $MP_var ? '&MP='.rawurlencode($MP_var) : '';
2543
2544 // UIDs to ban:
2545 $banUidArray=array();
2546 if (trim($this->conf['excludeUidList'])) {
2547 $banUidArray = t3lib_div::intExplode(',', $this->conf['excludeUidList']);
2548 }
2549
2550 // Initializing variables:
2551 $var = $this->JSVarName;
2552 $menuName = $this->JSMenuName;
2553 $parent = $count==1 ? 0 : $var.($count-1);
2554 $prev=0;
2555 $c=0;
2556
2557 $menuItems = is_array($menuItemArray) ? $menuItemArray : $this->sys_page->getMenu($pid);
2558 foreach($menuItems as $uid => $data) {
2559 $spacer = (t3lib_div::inList($this->spacerIDList,$data['doktype'])?1:0); // if item is a spacer, $spacer is set
2560 if ($this->mconf['SPC'] || !$spacer) { // If the spacer-function is not enabled, spacers will not enter the $menuArr
2561 if (!t3lib_div::inList($this->doktypeExcludeList,$data['doktype']) && !$data['nav_hide'] && !t3lib_div::inArray($banUidArray,$uid)) { // Page may not be 'not_in_menu' or 'Backend User Section' + not in banned uid's
2562 if ($count<$levels) {
2563 $addLines = $this->generate_level($levels,$count+1,$data['uid'],'',$MP_array);
2564 } else {
2565 $addLines = '';
2566 }
2567 $title=rawurlencode($data['title']);
2568 $url='';
2569 $target='';
2570 if ((!$addLines && !$levelConf['noLink']) || $levelConf['alwaysLink']) {
2571 $LD = $this->tmpl->linkData($data,$this->mconf['target'],'','',array(),$MP_params,$this->mconf['forceTypeValue']);
2572 $url = rawurlencode($LD['totalURL']);
2573 $target = rawurlencode($LD['target']);
2574 }
2575 $codeLines.="\n".$var.$count."=".$menuName.".add(".$parent.",".$prev.",0,'".$title."','".$url."','".$target."');";
2576 // If the active one should be chosen...
2577 $active = ($levelConf['showActive'] && $data['uid'] == $this->tmpl->rootLine[$count]['uid']);
2578 // If the first item should be shown
2579 $first = (!$c && $levelConf['showFirst']);
2580 // do it...
2581 if ($active || $first) {
2582 if ($count==1) {
2583 $codeLines.="\n".$menuName.".openID = ".$var.$count.";";
2584 } else {
2585 $codeLines.="\n".$menuName.".entry[".$parent."].openID = ".$var.$count.";";
2586 }
2587 }
2588 // Add submenu...
2589 $codeLines.=$addLines;
2590
2591 $prev=$var.$count;
2592 $c++;
2593 }
2594 }
2595 }
2596 if ($this->mconf['firstLabelGeneral'] && !$levelConf['firstLabel']) {
2597 $levelConf['firstLabel'] = $this->mconf['firstLabelGeneral'];
2598 }
2599 if ($levelConf['firstLabel'] && $codeLines) {
2600 $codeLines.="\n".$menuName.".defTopTitle[".$count."] = unescape('".rawurlencode($levelConf['firstLabel'])."');";
2601 }
2602 return $codeLines;
2603 }
2604 }
2605
2606
2607 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_menu.php']) {
2608 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_menu.php']);
2609 }
2610
2611 ?>