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