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