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