2 /***************************************************************
5 * (c) 1999-2003 Kasper Skårhøj (kasper@typo3.com)
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.
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.
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.
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
30 * The script is called in the top frame of the backend typically by a click on an icon for which a context menu should appear.
31 * Either this script displays the context menu horizontally in the top frame or alternatively (default in MSIE, Mozilla) it writes the output to a <div>-layer in the calling document (which then appears as a layer/context sensitive menu)
32 * Writing content back into a <div>-layer is necessary if we want individualized context menus with any specific content for any specific element.
33 * Context menus can appear for either database elements or files
34 * The input to this script is basically the "&init" var which is divided by "|" - each part is a reference to table|uid|listframe-flag.
36 * @author Kasper Skårhøj <kasper@typo3.com>
40 * Revised for TYPO3 3.6 2/2003 by Kasper Skårhøj
45 require ('template.php');
46 require_once (PATH_t3lib
.'class.t3lib_clipboard.php');
47 $LANG->includeLLFile('EXT:lang/locallang_misc.php');
51 // ***************************
53 // ***************************
56 * Class for generating the click menu
62 var $listFrame=0; // If set, the calling document should be in the listframe of a frameset.
63 var $isDBmenu=0; // If set, the menu is about databsae records, not files. (set if part 2 [1] of the item-var is NOT blank)
64 var $alwaysContentFrame=0;
66 var $disabledItems=array();
67 var $editPageIconSet=0;
68 var $dontDisplayTopFrameCM=0;
71 var $extClassArray=array();
79 * Initialize click menu
81 * @param string Input "item" GET var.
82 * @return string The clickmenu HTML content
84 function init($item) {
85 // Explode the incoming command:
86 $this->iParts
= explode('|',$item);
89 if ($this->iParts
[2]) $this->listFrame
=1;
90 if ($GLOBALS['BE_USER']->uc
['condensedMode']) $this->alwaysContentFrame
=1;
91 if (strcmp($this->iParts
[1],'')) $this->isDBmenu
=1;
93 $TSkey =($this->isDBmenu?
'page':'folder').($this->listFrame?
'List':'Tree');
94 $this->disabledItems
= t3lib_div
::trimExplode(',',$GLOBALS['BE_USER']->getTSConfigVal('options.contextMenu.'.$TSkey.'.disableItems'),1);
95 $this->leftIcons
= $GLOBALS['BE_USER']->getTSConfigVal('options.contextMenu.options.leftIcons');
97 // &cmLevel flag detected (2nd level menu)
98 $this->cmLevel
= intval(t3lib_div
::GPvar('cmLevel'));
99 if (!$this->cmLevel
) {
100 // Make 1st level clickmenu:
101 if ($this->isDBmenu
) {
102 return $this->printDBClickMenu($this->iParts
[0],$this->iParts
[1]);
104 return $this->printFileClickMenu($this->iParts
[0]);
107 // Make 2nd level clickmenu (only for DBmenus)
108 if ($this->isDBmenu
) {
109 return $this->printNewDBLevel($this->iParts
[0],$this->iParts
[1]);
115 * Returns true if the menu should (also?) be displayed in topframe, not just <div>-layers
119 function doDisplayTopFrameCM() {
120 return !$GLOBALS['SOBE']->doc
->isCMlayers() ||
!$this->dontDisplayTopFrameCM
;
134 /***************************************
138 ***************************************/
141 * Make 1st level clickmenu:
143 * @param string Table name
144 * @param integer UID for the current record.
145 * @return string HTML content
147 function printDBClickMenu($table,$uid) {
148 global $TCA, $BE_USER;
151 $this->rec
= t3lib_BEfunc
::getRecord($table,$uid);
154 if ($table=='pages' && !strcmp($uid,'0')) { // Rootlevel
158 // If record found (or root), go ahead and fill the $menuItems array which will contain data for the elements to render.
159 if (is_array($this->rec
) ||
$root) {
161 $lCP = $BE_USER->calcPerms(t3lib_BEfunc
::getRecord('pages',($table=='pages'?
$this->rec
['uid']:$this->rec
['pid'])));
164 if (!in_array('view',$this->disabledItems
)) {
165 if ($table=='pages') $menuItems['view']=$this->DB_view($uid);
166 if ($table==$GLOBALS['TYPO3_CONF_VARS']['SYS']['contentTable']) $menuItems['view']=$this->DB_view($this->rec
['pid'],'#'.$uid);
170 if(!$root && ($BE_USER->isPSet($lCP,$table,'edit')||
$BE_USER->isPSet($lCP,$table,'editcontent'))) {
171 if (!in_array('edit',$this->disabledItems
)) $menuItems['edit']=$this->DB_edit($table,$uid);
176 if (!in_array('new',$this->disabledItems
) && $BE_USER->isPSet($lCP,$table,'new')) $menuItems['new']=$this->DB_new($table,$uid);
179 if(!in_array('info',$this->disabledItems
) && !$root) $menuItems['info']=$this->DB_info($table,$uid);
181 $menuItems[]='spacer';
184 if(!in_array('copy',$this->disabledItems
) && !$root) $menuItems['copy']=$this->DB_copycut($table,$uid,'copy');
186 if(!in_array('cut',$this->disabledItems
) && !$root) $menuItems['cut']=$this->DB_copycut($table,$uid,'cut');
189 $elFromAllTables = count($this->clipObj
->elFromTable(''));
190 if (!in_array('paste',$this->disabledItems
) && $elFromAllTables) {
191 $selItem = $this->clipObj
->getSelectedRecord();
193 $selItem['_RECORD_TITLE'],
194 ($root?
$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']:t3lib_div
::fixed_lgd(t3lib_BEfunc
::getRecordTitle($table,$this->rec
),$GLOBALS['BE_USER']->uc
['titleLen'])),
195 $this->clipObj
->currentMode()
197 if ($table=='pages' && ($lCP & 8)) {
198 if ($elFromAllTables) $menuItems['pasteinto']=$this->DB_paste('',$uid,'into',$elInfo);
201 $elFromTable = count($this->clipObj
->elFromTable($table));
202 if (!$root && $elFromTable && $TCA[$table]['ctrl']['sortby']) $menuItems['pasteafter']=$this->DB_paste($table,-$uid,'after',$elInfo);
206 $elInfo=array(t3lib_div
::fixed_lgd(t3lib_BEfunc
::getRecordTitle($table,$this->rec
),$GLOBALS['BE_USER']->uc
['titleLen']));
207 if(!in_array('delete',$this->disabledItems
) && !$root && $BE_USER->isPSet($lCP,$table,'delete')) {
208 $menuItems[]='spacer';
209 $menuItems['delete']=$this->DB_delete($table,$uid,$elInfo);
213 // Adding external elements to the menuItems array
214 $menuItems = $this->processingByExtClassArray($menuItems,$table,$uid);
216 // Processing by external functions?
217 $menuItems = $this->externalProcessingOfDBMenuItems($menuItems);
219 // Return the printed elements:
220 return $this->printItems($menuItems,
221 $this->wrapColorTable(
223 '<img src="'.$this->backPath
.'gfx/i/_icon_website.gif" width="18" height="16" hspace="5" border="0" align="absmiddle" alt="" /><strong>'.htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']).'</strong>':
224 t3lib_iconWorks
::getIconImage($table,$this->rec
,$this->backPath
,' hspace="5" align="absmiddle"'.t3lib_BEfunc
::titleAttrib(t3lib_BEfunc
::getRecordIconAltText($this->rec
,$table))).'<strong>'.t3lib_BEfunc
::getRecordTitle($table,$this->rec
,1).'</strong>'
230 * Make 2nd level clickmenu (only for DBmenus)
232 * @param string Table name
233 * @param integer UID for the current record.
234 * @return string HTML content
236 function printNewDBLevel($table,$uid) {
237 global $TCA, $BE_USER;
239 // Setting internal record to the table/uid :
240 $this->rec
= t3lib_BEfunc
::getRecord($table,$uid);
243 if ($table=='pages' && !strcmp($uid,'0')) { // Rootlevel
247 // If record was found, check permissions and get menu items.
248 if (is_array($this->rec
) ||
$root) {
249 $lCP = $BE_USER->calcPerms(t3lib_BEfunc
::getRecord('pages',($table=='pages'?
$this->rec
['uid']:$this->rec
['pid'])));
251 if(!$root && ($BE_USER->isPSet($lCP,$table,'edit')||
$BE_USER->isPSet($lCP,$table,'editcontent'))) {
255 $menuItems = $this->processingByExtClassArray($menuItems,$table,$uid);
258 // Return the printed elements:
259 if (!is_array($menuItems)) $menuItems=array();
260 return $this->printItems($menuItems,
261 $this->wrapColorTable(
263 '<img src="'.$this->backPath
.'gfx/i/_icon_website.gif" width="18" height="16" hspace=5 border="0" align="absmiddle" alt="" /><strong>'.htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']).'</strong>':
264 t3lib_iconWorks
::getIconImage($table,$this->rec
,$this->backPath
,' hspace="5" align="absmiddle"'.t3lib_BEfunc
::titleAttrib(t3lib_BEfunc
::getRecordIconAltText($this->rec
,$table))).'<strong>'.t3lib_BEfunc
::getRecordTitle($table,$this->rec
,1).'</strong>'
270 * Processing the $menuItems array (for extension classes) (DATABASE RECORDS)
272 * @param array $menuItems array for manipulation.
273 * @return array Processed $menuItems array
275 function externalProcessingOfDBMenuItems($menuItems) {
280 * Processing the $menuItems array by external classes (typ. adding items)
282 * @param array $menuItems array for manipulation.
283 * @param string Table name
284 * @param integer UID for the current record.
285 * @return array Processed $menuItems array
287 function processingByExtClassArray($menuItems,$table,$uid) {
288 if (is_array($this->extClassArray
)) {
289 reset($this->extClassArray
);
290 while(list(,$conf)=each($this->extClassArray
)) {
291 $obj=t3lib_div
::makeInstance($conf['name']);
292 $menuItems = $obj->main($this,$menuItems,$table,$uid);
299 * Returning JavaScript for the onClick event linking to the input URL.
301 * @param string The URL relative to TYPO3_mainDir
302 * @param string The return_url-parameter
303 * @param boolean If set, the "hideCM()" will be called
304 * @return string JavaScript for an onClick event.
306 function urlRefForCM($url,$retUrl='',$hideCM=1) {
307 $loc='top.content'.($this->listFrame
&& !$this->alwaysContentFrame ?
'.list_frame':'');
308 $editOnClick='var docRef=(top.content.list_frame)?top.content.list_frame:'.$loc.'; docRef.document.location=top.TS.PATH_typo3+\''.$url.'\''.
309 ($retUrl?
"+'&".$retUrl."='+top.rawurlencode(".$this->frameLocation('docRef.document').')':'').';'.
310 ($hideCM?
'return hideCM();':'');
315 * Adding CM element for Clipboard "copy" and "cut"
317 * @param string Table name
318 * @param integer UID for the current record.
319 * @param string Type: "copy" or "cut"
320 * @return array Item array, element in $menuItems
323 function DB_copycut($table,$uid,$type) {
324 if ($this->clipObj
->current
=='normal') {
325 $isSel = $this->clipObj
->isSelected($table,$uid);
327 return $this->linkItem(
329 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/clip_'.$type.($isSel==$type?
'_h':'').'.gif" width="12" height="12" border=0 align=top>'),
330 "top.loadTopMenu('".$this->clipObj
->selUrlDB($table,$uid,($type=='copy'?
1:0),($isSel==$type))."');return false;"
335 * Adding CM element for Clipboard "paste into"/"paste after"
336 * NOTICE: $table and $uid should follow the special syntax for paste, see clipboard-class :: pasteUrl();
338 * @param string Table name
339 * @param integer UID for the current record. NOTICE: Special syntax!
340 * @param string Type: "into" or "after"
341 * @return array Item array, element in $menuItems
342 * @see t3lib_clipboard::pasteUrl()
345 function DB_paste($table,$uid,$type,$elInfo) {
347 $loc='top.content'.($this->listFrame
&& !$this->alwaysContentFrame ?
'.list_frame':'');
348 $conf=$loc.' && confirm('.$GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:mess.'.($elInfo[2]=='copy'?
'copy':'move').'_'.$type),$elInfo[0],$elInfo[1])).')';
349 $editOnClick='if('.$conf.'){'.$loc.'.document.location=top.TS.PATH_typo3+\''.$this->clipObj
->pasteUrl($table,$uid,0).'&redirect=\'+top.rawurlencode('.$this->frameLocation($loc.'.document').'); hideCM();}';
351 return $this->linkItem(
352 $this->label('paste'.$type),
353 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/clip_paste'.$type.'.gif" width="12" height="12" border="0" align="top" alt="" />'),
354 $editOnClick.'return false;'
359 * Adding CM element for Info
361 * @param string Table name
362 * @param integer UID for the current record.
363 * @return array Item array, element in $menuItems
366 function DB_info($table,$uid) {
367 return $this->linkItem(
368 $this->label('info'),
369 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/zoom2.gif" width="12" height="12" border="0" align="top" alt="" />'),
370 "top.launchView('".$table."', '".$uid."'); return hideCM();"
375 * Adding CM element for History
377 * @param string Table name
378 * @param integer UID for the current record.
379 * @return array Item array, element in $menuItems
382 function DB_history($table,$uid) {
383 $url = 'show_rechis.php?element='.rawurlencode($table.':'.$uid);
384 return $this->linkItem(
385 $GLOBALS['LANG']->makeEntities($GLOBALS['LANG']->getLL('CM_history')),
386 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/history2.gif" width="13" height="12" border="0" align="top" alt="" />'),
387 $this->urlRefForCM($url,'returnUrl'),
393 * Adding CM element for Permission setting
395 * @param string Table name
396 * @param integer UID for the current record.
397 * @param array The "pages" record with "perms_*" fields inside.
398 * @return array Item array, element in $menuItems
401 function DB_perms($table,$uid,$rec) {
402 $url = 'mod/web/perm/index.php?id='.$uid.($rec['perms_userid']==$GLOBALS['BE_USER']->user
['uid']||
$GLOBALS['BE_USER']->isAdmin()?
'&return_id='.$uid.'&edit=1':'');
403 return $this->linkItem(
404 $GLOBALS['LANG']->makeEntities($GLOBALS['LANG']->getLL('CM_perms')),
405 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/perm.gif" width="7" height="12" border="0" align="top" alt="" />'),
406 $this->urlRefForCM($url),
412 * Adding CM element for DBlist
414 * @param string Table name
415 * @param integer UID for the current record.
416 * @param array Record of the element (needs "pid" field if not pages-record)
417 * @return array Item array, element in $menuItems
420 function DB_db_list($table,$uid,$rec) {
421 $url = t3lib_div
::getIndpEnv('TYPO3_REQUEST_DIR').'db_list.php?table='.($table=='pages'?
'':$table).'&id='.($table=='pages'?
$uid:$rec['pid']);
422 return $this->linkItem(
423 $GLOBALS['LANG']->makeEntities($GLOBALS['LANG']->getLL('CM_db_list')),
424 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/list.gif" width="11" height="11" border="0" align="top" alt="" />'),
425 "top.nextLoadModuleUrl='".$url."';top.goToModule('web_list',1);",
431 * Adding CM element for Moving wizard
433 * @param string Table name
434 * @param integer UID for the current record.
435 * @param array Record. Needed for tt-content elements which will have the sys_language_uid sent
436 * @return array Item array, element in $menuItems
439 function DB_moveWizard($table,$uid,$rec) {
440 $url = 'move_el.php?table='.$table.'&uid='.$uid.
441 ($table=='tt_content'?
'&sys_language_uid='.intval($rec['sys_language_uid']):''); // Hardcoded field for tt_content elements.
443 return $this->linkItem(
444 $GLOBALS['LANG']->makeEntities($GLOBALS['LANG']->getLL('CM_moveWizard'.($table=='pages'?
'_page':''))),
445 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/move_'.($table=='pages'?
'page':'record').'.gif" width="11" height="12" border="0" align="top" alt="" />'),
446 $this->urlRefForCM($url,'returnUrl'),
452 * Adding CM element for Create new wizard (either db_new.php or db_new_content_el.php)
454 * @param string Table name
455 * @param integer UID for the current record.
456 * @param array Record.
457 * @return array Item array, element in $menuItems
460 function DB_newWizard($table,$uid,$rec) {
461 $url = ($table=='pages') ?
'db_new.php?id='.$uid.'&pagesOnly=1' : 'db_new_content_el.php?id='.$rec['pid'].'&sys_language_uid='.intval($rec['sys_language_uid']);
462 return $this->linkItem(
463 $GLOBALS['LANG']->makeEntities($GLOBALS['LANG']->getLL('CM_newWizard')),
464 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/new_'.($table=='pages'?
'page':'record').'.gif" width="'.($table=='pages'?
'13':'16').'" height="12" border="0" align="top" alt="" />'),
465 $this->urlRefForCM($url,'returnUrl'),
471 * Adding CM element for Editing of the access related fields of a table (disable, starttime, endtime, fe_groups)
473 * @param string Table name
474 * @param integer UID for the current record.
475 * @return array Item array, element in $menuItems
478 function DB_editAccess($table,$uid) {
479 $addParam='&columnsOnly='.implode(',',$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']);
480 $url = 'alt_doc.php?edit['.$table.']['.$uid.']=edit'.$addParam;
481 return $this->linkItem(
482 $GLOBALS['LANG']->makeEntities($GLOBALS['LANG']->getLL('CM_editAccess')),
483 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/editaccess.gif" width="12" height="12" border="0" align="top" alt="" />'),
484 $this->urlRefForCM($url,'returnUrl'),
485 1 // no top frame CM!
490 * Adding CM element for edit page header
492 * @param integer page uid to edit (PID)
493 * @return array Item array, element in $menuItems
496 function DB_editPageHeader($uid) {
497 $url = 'alt_doc.php?edit[pages]['.$uid.']=edit';
498 return $this->linkItem(
499 $GLOBALS['LANG']->makeEntities($GLOBALS['LANG']->getLL('CM_editPageHeader')),
500 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/edit2.gif" width="11" height="12" border="0" align="top" alt="" />'),
501 $this->urlRefForCM($url,'returnUrl'),
502 1 // no top frame CM!
507 * Adding CM element for regular editing of the element!
509 * @param string Table name
510 * @param integer UID for the current record.
511 * @return array Item array, element in $menuItems
514 function DB_edit($table,$uid) {
518 $loc='top.content'.($this->listFrame
&& !$this->alwaysContentFrame ?
'.list_frame':'');
520 $theIcon = 'gfx/edit2.gif" width="11" height="12"';
522 $this->iParts
[0]=='pages' &&
524 $GLOBALS['BE_USER']->check('modules','web_layout')
526 $theIcon = 'gfx/edit_page.gif" width="12" height="12"';
527 $this->editPageIconSet
=1;
528 if ($BE_USER->uc
['classicPageEditMode'] ||
!t3lib_extMgm
::isLoaded('cms')) {
529 $addParam='&editRegularContentFromId='.intval($this->iParts
[1]);
531 $editOnClick="top.fsMod.recentIds['web']=".intval($this->iParts
[1]).";top.goToModule('web_layout',1);";
535 $editOnClick="if(".$loc."){".$loc.".document.location=top.TS.PATH_typo3+'alt_doc.php?returnUrl='+top.rawurlencode(".$this->frameLocation($loc.'.document').")+'&edit[".$table."][".$uid."]=edit".$addParam."';}";
538 return $this->linkItem(
539 $this->label('edit'),
540 $this->excludeIcon('<img src="'.$this->backPath
.$theIcon.' border="0" align="top" alt="" />'),
541 $editOnClick.'return hideCM();'
546 * Adding CM element for regular Create new element
548 * @param string Table name
549 * @param integer UID for the current record.
550 * @return array Item array, element in $menuItems
553 function DB_new($table,$uid) {
555 $loc='top.content'.(!$this->alwaysContentFrame?
'.list_frame':'');
556 $editOnClick='if('.$loc.'){'.$loc.".document.location=top.TS.PATH_typo3+'".
558 $this->backPath
."alt_doc.php?returnUrl='+top.rawurlencode(".$this->frameLocation($loc.'.document').")+'&edit[".$table."][-".$uid."]=new'":
559 $this->backPath
.'db_new.php?id='.intval($uid)."'").
562 return $this->linkItem(
564 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/new_'.($table=='pages'&&$this->listFrame?
'page':'el').'.gif" width="'.($table=='pages'?
'13':'11').'" height="12" border="0" align="top" alt="" />'),
565 $editOnClick.'return hideCM();'
570 * Adding CM element for hide/unhide of the input record
572 * @param string Table name
573 * @param array Record
574 * @param string Name of the hide field
575 * @return array Item array, element in $menuItems
578 function DB_hideUnhide($table,$rec,$hideField) {
581 $loc='top.content'.($this->listFrame
&& !$this->alwaysContentFrame ?
'.list_frame':'');
582 $editOnClick='if('.$loc.'){'.$loc.".document.location=top.TS.PATH_typo3+'tce_db.php?redirect='+top.rawurlencode(".$this->frameLocation($loc.'.document').")+'".
583 "&data[".$table.']['.$uid.']['.$hideField.']='.($rec[$hideField]?
0:1).'&prErr=1&vC='.$GLOBALS['BE_USER']->veriCode()."';hideCM();}";
585 return $this->linkItem(
586 $this->label(($rec[$hideField]?
'un':'').'hide'),
587 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/button_'.($rec[$hideField]?
'un':'').'hide.gif" width="11" height="10" vspace="1" border="0" align="top" alt="" />'),
588 $editOnClick.'return false;',
594 * Adding CM element for Delete
596 * @param string Table name
597 * @param integer UID for the current record.
598 * @param array Label for including in the confirmation message, EXT:lang/locallang_core.php:mess.delete
599 * @return array Item array, element in $menuItems
602 function DB_delete($table,$uid,$elInfo) {
604 $loc='top.content'.($this->listFrame
&& !$this->alwaysContentFrame ?
'.list_frame':'');
605 $editOnClick='if('.$loc." && confirm(".$GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:mess.delete'),$elInfo[0])).")){".$loc.".document.location=top.TS.PATH_typo3+'tce_db.php?redirect='+top.rawurlencode(".$this->frameLocation($loc.'.document').")+'".
606 "&cmd[".$table.']['.$uid.'][delete]=1&prErr=1&vC='.$GLOBALS['BE_USER']->veriCode()."';hideCM();}";
608 return $this->linkItem(
609 $this->label('delete'),
610 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/garbage.gif" width="11" height="12" border="0" align="top" alt="" />'),
611 $editOnClick.'return false;'
616 * Adding CM element for View Page
618 * @param integer Page uid (PID)
619 * @param string Anchor, if any
620 * @return array Item array, element in $menuItems
623 function DB_view($id,$anchor='') {
624 return $this->linkItem(
625 $this->label('view'),
626 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/zoom.gif" width="12" height="12" border="0" align="top" alt="" />'),
627 t3lib_BEfunc
::viewOnClick($id,$this->backPath
,t3lib_BEfunc
::BEgetRootLine($id),$anchor).'return hideCM();'
640 /***************************************
644 ***************************************/
647 * Make 1st level clickmenu:
649 * @param string The absolute path
650 * @return string HTML content
652 function printFileClickMenu($path) {
655 if (@file_exists
($path) && t3lib_div
::isAllowedAbsPath($path)) {
656 $fI = pathinfo($path);
657 $icon = is_dir($path) ?
'folder.gif' : t3lib_BEfunc
::getFileIcon(strtolower($fI['extension']));
658 $size=' ('.t3lib_div
::formatSize(filesize($path)).'bytes)';
659 $icon = '<img src="gfx/fileicons/'.$icon.'" width="18" height="16" border="0" hspace="5"'.t3lib_BEfunc
::titleAttrib($fI['basename'].$size,1).' align="absmiddle" alt="" />';
662 if (!in_array('edit',$this->disabledItems
) && is_file($path) && t3lib_div
::inList($GLOBALS['TYPO3_CONF_VARS']['SYS']['textfile_ext'],$fI['extension'])) $menuItems['edit']=$this->FILE_launch($path,'file_edit.php','edit','edit_file.gif');
664 if (!in_array('rename',$this->disabledItems
)) $menuItems['rename']=$this->FILE_launch($path,'file_rename.php','rename','rename.gif');
666 if (!in_array('upload',$this->disabledItems
) && is_dir($path)) $menuItems['upload']=$this->FILE_launch($path,'file_upload.php','upload','upload.gif');
668 if (!in_array('new',$this->disabledItems
) && is_dir($path)) $menuItems['new']=$this->FILE_launch($path,'file_newfolder.php','new','new_file.gif');
670 if (!in_array('info',$this->disabledItems
)) $menuItems['info']=$this->DB_info($path,'');
672 $menuItems[]='spacer';
675 if (!in_array('copy',$this->disabledItems
)) $menuItems['copy']=$this->FILE_copycut($path,'copy');
677 if (!in_array('cut',$this->disabledItems
)) $menuItems['cut']=$this->FILE_copycut($path,'cut');
680 $elFromAllTables = count($this->clipObj
->elFromTable('_FILE'));
681 if (!in_array('paste',$this->disabledItems
) && $elFromAllTables && is_dir($path)) {
682 $elArr = $this->clipObj
->elFromTable('_FILE');
684 $selItem = current($elArr);
688 $this->clipObj
->currentMode()
690 $menuItems['pasteinto']=$this->FILE_paste($path,$selItem,$elInfo);
693 $menuItems[]='spacer';
696 if (!in_array('delete',$this->disabledItems
)) $menuItems['delete']=$this->FILE_delete($path);
699 // Adding external elements to the menuItems array
700 $menuItems = $this->processingByExtClassArray($menuItems,$path,0);
702 // Processing by external functions?
703 $menuItems = $this->externalProcessingOfFileMenuItems($menuItems);
705 // Return the printed elements:
706 return $this->printItems($menuItems,
707 $this->wrapColorTable(
708 $icon.'<strong>'.basename($path).'</strong>'
715 * Processing the $menuItems array (for extension classes) (FILES)
717 * @param array $menuItems array for manipulation.
718 * @return array Processed $menuItems array
720 function externalProcessingOfFileMenuItems($menuItems) {
725 * Multi-function for adding an entry to the $menuItems array
727 * @param string Path to the file/directory (target)
728 * @param string Script (eg. file_edit.php) to pass &target= to
729 * @param string "type" is the code which fetches the correct label for the element from "cm."
730 * @param string icon image-filename from "gfx/" (12x12 icon)
731 * @return array Item array, element in $menuItems
734 function FILE_launch($path,$script,$type,$image) {
735 $loc='top.content'.(!$this->alwaysContentFrame?
'.list_frame':'');
736 $editOnClick='if('.$loc.'){'.$loc.".document.location=top.TS.PATH_typo3+'".$script.'?target='.rawurlencode($path)."';}";
738 return $this->linkItem(
740 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/'.$image.'" width="12" height="12" border="0" align="top" alt="" />'),
741 $editOnClick.'return hideCM();'
746 * Returns element for copy or cut of files.
748 * @param string Path to the file/directory (target)
749 * @param string Type: "copy" or "cut"
750 * @return array Item array, element in $menuItems
753 function FILE_copycut($path,$type) {
754 $table='_FILE'; // Pseudo table name for use in the clipboard.
755 $uid = t3lib_div
::shortmd5($path);
756 if ($this->clipObj
->current
=='normal') {
757 $isSel = $this->clipObj
->isSelected($table,$uid);
759 return $this->linkItem(
761 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/clip_'.$type.($isSel==$type?
'_h':'').'.gif" width="12" height="12" border="0" align="top" alt="" />'),
762 "top.loadTopMenu('".$this->clipObj
->selUrlFile($path,($type=='copy'?
1:0),($isSel==$type))."');return false;"
767 * Creates element for deleting of target
769 * @param string Path to the file/directory (target)
770 * @return array Item array, element in $menuItems
773 function FILE_delete($path) {
775 $loc='top.content'.($this->listFrame
&& !$this->alwaysContentFrame ?
'.list_frame':'');
776 $editOnClick='if('.$loc." && confirm(".$GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:mess.delete'),basename($path))).")){".$loc.".document.location=top.TS.PATH_typo3+'tce_file.php?redirect='+top.rawurlencode(".$this->frameLocation($loc.'.document').")+'".
777 "&file[delete][0][data]=".rawurlencode($path).'&vC='.$GLOBALS['BE_USER']->veriCode()."';hideCM();}";
779 return $this->linkItem(
780 $this->label('delete'),
781 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/garbage.gif" width="11" height="12" border="0" align="top" alt="" />'),
782 $editOnClick.'return false;'
787 * Creates element for pasting files.
789 * @param string Path to the file/directory (target)
790 * @param string target - NOT USED.
791 * @param array Various values for the labels.
792 * @return array Item array, element in $menuItems
795 function FILE_paste($path,$target,$elInfo) {
797 $loc='top.content'.($this->listFrame
&& !$this->alwaysContentFrame ?
'.list_frame':'');
798 $conf=$loc." && confirm(".$GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:mess'.($elInfo[2]=='copy'?
'copy':'move').'_into'),$elInfo[0],$elInfo[1])).")";
799 $editOnClick='if('.$conf.'){'.$loc.".document.location=top.TS.PATH_typo3+'".$this->clipObj
->pasteUrl('_FILE',$path,0).
800 "&redirect='+top.rawurlencode(".$this->frameLocation($loc.'.document').'); hideCM();}';
802 return $this->linkItem(
803 $this->label('pasteinto'),
804 $this->excludeIcon('<img src="'.$this->backPath
.'gfx/clip_pasteinto.gif" width="12" height="12" border="0" align="top" alt="" />'),
805 $editOnClick.'return false;'
821 /***************************************
825 **************************************/
828 * Prints the items from input $menuItems array - both as topframe menu AND the JS section for writing to the div-layers.
829 * Of course the topframe menu will appear only if $this->doDisplayTopFrameCM() returns true
831 * @param array $menuItems array
832 * @param string HTML code for the element which was clicked - shown in the end of the horizontal menu in topframe after the close-button.
833 * @return string HTML code
835 function printItems($menuItems,$item) {
838 // Adding topframe part (horizontal clickmenu)
839 if ($this->doDisplayTopFrameCM()) {
840 $out.= '<img src="clear.gif" width="1" height="10" alt="" /><br />
841 <table border="0" cellpadding="0" cellspacing="0">
843 <td nowrap="nowrap" valign="top">'.
844 implode('</td><td valign="top"><img src="gfx/acm_spacer2.gif" width="8" height="12" alt="" /></td><td nowrap="nowrap" valign="top">',$this->menuItemsForTopFrame($menuItems)).
846 <td><img src="clear.gif" width="10" height="1" alt="" /></td>
847 <td nowrap="nowrap" valign="top"><a href="#" onclick="hideCM();return false;"><img src="gfx/close_12h.gif" width="11" height="12" vspace="2" hspace="5" border="0"'.t3lib_BEfunc
::titleAttrib($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.close'),1).' alt="" /></a></td>
854 $out.=$this->printLayerJScode($menuItems);
856 // Return the content
861 * Create the JavaScript section
863 * @param array The $menuItems array to print
864 * @return string The JavaScript section which will print the content of the CM to the div-layer in the target frame.
866 function printLayerJScode($menuItems) {
868 if ($this->isCMlayers()) { // Clipboard must not be submitted - then it's probably a copy/cut situation.
869 $frameName = '.'.($this->listFrame ?
'list_frame' : 'nav_frame');
870 if ($this->alwaysContentFrame
) $frameName='';
872 // Create the table displayed in the clickmenu layer:
873 $CMtable = '<table border="0" cellpadding="0" cellspacing="0" bgcolor="'.$GLOBALS['TBE_TEMPLATE']->bgColor4
.'">'.
874 implode('',$this->menuItemsForClickMenu($menuItems)).
877 // Wrap the inner table in another table to create outer border:
878 $CMtable = $this->wrapColorTableCM($CMtable);
880 // Create JavaScript section:
881 $script=$GLOBALS['TBE_TEMPLATE']->wrapScriptTags('
883 if (top.content && top.content'.$frameName.' && top.content'.$frameName.'.setLayerObj) {
884 top.content'.$frameName.'.setLayerObj(unescape("'.t3lib_div
::rawurlencodeJS($CMtable).'"),'.$this->cmLevel
.');
886 '.(!$this->doDisplayTopFrameCM()?
'hideCM();':'')
894 * Wrapping the input string in a table with background color 4 and a black border style.
899 function wrapColorTableCM($str) {
900 $str = '<table border="0" cellpadding="1" cellspacing="0" bgcolor="'.$GLOBALS['TBE_TEMPLATE']->bgColor4
.'" style="border: solid 1px black;">
901 <tr><td>'.$str.'</td></tr>
908 * Wrapping the input string in a table with background color 2 and a black border style.
913 function wrapColorTable($str) {
914 return '<table border="0" cellpadding="0" cellspacing="0" bgcolor="'.$GLOBALS['TBE_TEMPLATE']->bgColor2
.'" style="border: solid 1px black;">
917 <td><img src=clear.gif width=10 height=1></td>
923 * Traverses the menuItems and generates an output array for implosion in the topframe horizontal menu
925 * @param array $menuItem array
926 * @param array Array with HTML content to be imploded between <td>-tags
928 function menuItemsForTopFrame($menuItems) {
931 while(list(,$i)=each($menuItems)) {
932 if ($i[4]==1 && !$GLOBALS['SOBE']->doc
->isCMlayers()) $i[4]=0; // IF the topbar is the ONLY means of the click menu, then items normally disabled from the top menu will appear anyways IF they are disabled with a "1" (2+ will still disallow them in the topbar)
933 if (is_array($i) && !$i[4]) $out[]=$i[0];
939 * Traverses the menuItems and generates an output array for implosion in the CM div-layers table.
941 * @param array $menuItem array
942 * @param array Array with HTML content to be imploded between <td>-tags
944 function menuItemsForClickMenu($menuItems) {
947 while(list($cc,$i)=each($menuItems)) {
948 if (is_string($i) && $i=='spacer') { // MAKE horizontal spacer
949 $out[]='<tr style="background:'.$GLOBALS['TBE_TEMPLATE']->bgColor2
.'">
950 <td colspan="4"><img src="clear.gif" width="1" height="1" alt="" /></td>
952 } else { // Just make normal element:
954 $onClick=eregi_replace('return[[:space:]]+hideCM\(\)[[:space:]]*;','',$onClick);
955 $onClick=eregi_replace('return[[:space:]]+false[[:space:]]*;','',$onClick);
956 $onClick=eregi_replace('hideCM\(\);','',$onClick);
957 if (!$i[5]) $onClick.='hideEmpty();';
959 $out[]='<tr onclick="'.htmlspecialchars($onClick).'" style="cursor:hand;" onmouseover="this.bgColor=\''.$GLOBALS['TBE_TEMPLATE']->bgColor5
.'\';" onmouseout="this.bgColor=\'\';">'.
961 <td nowrap="nowrap"> '.$i[1].'</td>
962 <td><img src="clear.gif" width="20" height="14" alt="" /></td>
963 <td align="center">'.$i[2].'</td>
966 '<td><img src="clear.gif" width="2" height="14" alt="" /></td>
967 <td align="center">'.$i[2].'</td>
968 <td nowrap="nowrap"> '.$i[1].'</td>
977 * Creating an array with various elements for the clickmenu entry
979 * @param string The label, htmlspecialchar'ed already
980 * @param string <img>-tag for the icon
981 * @param string JavaScript onclick event for label/icon
982 * @param boolean ==1 and the element will NOT appear in clickmenus in the topframe (unless clickmenu is totally unavailable)! ==2 and the item will NEVER appear in top frame. (This is mostly for "less important" options since the top frame is not capable of holding so many elements horizontally)
983 * @param boolean If set, the clickmenu layer will not hide itself onclick - used for secondary menus to appear...
984 * @return array $menuItem entry with 6 numerical entries: [0] is the HTML for display of the element with link and icon an mouseover etc., [1]-[5] is simply the input params passed through!
986 function linkItem($str,$icon,$onClick,$onlyCM=0,$dontHide=0) {
989 '<img src="clear.gif" width="7" height="10" align="top" hspace="1" name="roimg_'.$this->elCount
.'" alt="" />'.
990 '<a href="#" onclick="'.htmlspecialchars($onClick).'" onmouseover="mo('.$this->elCount
.');" onmouseout="mout('.$this->elCount
.');">'.
1002 * Returns the input string IF not a user setting has disabled display of icons.
1004 * @param string The icon-image tag
1005 * @return string The icon-image tag prefixed with space char IF the icon should be printed at all due to user settings
1007 function excludeIcon($iconCode) {
1008 return ($GLOBALS['BE_USER']->uc
['noMenuMode'] && strcmp($GLOBALS['BE_USER']->uc
['noMenuMode'],'icons')) ?
'' : ' '.$iconCode;
1012 * Get label from locallang_core.php:cm.*
1014 * @param string The "cm."-suffix to get.
1017 function label($label) {
1018 return $GLOBALS['LANG']->makeEntities($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:cm.'.$label,1));
1022 * Returns true if there should be writing to the div-layers (commands sent to clipboard MUST NOT write to div-layers)
1026 function isCMlayers() {
1027 return $GLOBALS['SOBE']->doc
->isCMlayers() && !t3lib_div
::GPvar('CB');
1031 * Appends ".location" to input string
1036 function frameLocation($str) {
1037 return $str.'.location';
1056 class SC_alt_clickmenu
{
1057 var $content=''; // Content accumulation
1058 var $doc; // Template object
1059 var $include_once=array(); // Files to include_once() - set in init() function
1060 var $extClassArray=array(); // Internal array of classes for extending the clickmenu
1061 var $dontDisplayTopFrameCM=0; // If set, then the clickmenu will NOT display in the top frame.
1067 global $BE_USER,$BACK_PATH;
1069 // Setting pseudo module name
1070 $this->MCONF
['name']='xMOD_alt_clickmenu.php';
1072 // Setting internal array of classes for extending the clickmenu:
1073 $this->extClassArray
= $GLOBALS['TBE_MODULES_EXT']['xMOD_alt_clickmenu']['extendCMclasses'];
1075 // Traversing that array and setting files for inclusion:
1076 if (is_array($this->extClassArray
)) {
1077 reset($this->extClassArray
);
1078 while(list(,$extClassConf)=each($this->extClassArray
)) {
1079 if ($extClassConf['path']) $this->include_once[]=$extClassConf['path'];
1083 // Initialize template object
1084 $this->doc
= t3lib_div
::makeInstance('template');
1085 $this->doc
->docType
='xhtml_trans';
1086 $this->doc
->inDocStyles
= 'BODY {background-color: '.$this->doc
->bgColor2
.'; background-image: url(gfx/alt_topmenu_back_full.gif)}';
1087 $this->doc
->backPath
= $BACK_PATH;
1089 // Setting mode for display and background image in the top frame
1090 $this->dontDisplayTopFrameCM
= $this->doc
->isCMlayers() && !$GLOBALS['BE_USER']->getTSConfigVal('options.contextMenu.options.alwaysShowClickMenuInTopFrame');
1091 if ($this->dontDisplayTopFrameCM
) {
1092 $this->doc
->inDocStyles
= 'BODY {background-color: '.$this->doc
->bgColor2
.'; background-image: url(gfx/alt_topmenu_back_dummy.gif)}';
1095 // Setting clickmenu timeout
1096 $secs = t3lib_div
::intInRange($BE_USER->getTSConfigVal('options.contextMenu.options.clickMenuTimeOut'),1,100,5); // default is 5
1098 // Setting the JavaScript controlling the timer on the page
1099 $this->doc
->JScode
.=$this->doc
->wrapScriptTags('
1100 var date = new Date();
1101 var mo_timeout = Math.floor(date.getTime()/1000);
1104 roImg.src = "gfx/content_client.gif";
1106 routImg =new Image();
1107 routImg.src = "clear.gif";
1110 var name="roimg_"+c;
1111 document[name].src = roImg.src;
1115 var name="roimg_"+c;
1116 document[name].src = routImg.src;
1119 function updateTime() {
1121 mo_timeout = Math.floor(date.getTime()/1000);
1124 function timeout_func() {
1126 if (Math.floor(date.getTime()/1000)-mo_timeout > '.$secs.') {
1130 window.setTimeout("timeout_func();",1*1000);
1134 document.location="alt_topmenu_dummy.php";
1144 * Main function - generating the click menu in whatever form it has.
1147 global $HTTP_GET_VARS;
1149 // Initialize Clipboard object:
1150 $clipObj = t3lib_div
::makeInstance('t3lib_clipboard');
1151 $clipObj->initializeClipboard();
1152 $clipObj->lockToNormal(); // This locks the clipboard to the Normal for this request.
1154 // Update clipboard if some actions are sent.
1155 $CB = $HTTP_GET_VARS['CB'];
1156 $clipObj->setCmd($CB);
1157 $clipObj->cleanCurrent();
1158 $clipObj->endClipboard(); // Saves
1160 // Create clickmenu object
1161 $clickMenu = t3lib_div
::makeInstance('clickMenu');
1163 // Set internal vars in clickmenu object:
1164 $clickMenu->clipObj
= $clipObj;
1165 $clickMenu->extClassArray
= $this->extClassArray
;
1166 $clickMenu->dontDisplayTopFrameCM
= $this->dontDisplayTopFrameCM
;
1168 // Takes the backPath as a parameter BUT since we are worried about someone forging a backPath (XSS security hole) we will check with sent md5 hash:
1169 $inputBP = explode('|',t3lib_div
::GPvar('backPath'));
1170 if (count($inputBP)==2 && $inputBP[1]==md5($inputBP[0].'|'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
1171 $clickMenu->backPath
= $inputBP[0];
1175 $this->content
.=$this->doc
->startPage('Context Sensitive Menu');
1177 // Set content of the clickmenu with the incoming var, "item"
1178 $this->content
.= $clickMenu->init(t3lib_div
::GPvar('item'));
1182 * End page and output content.
1184 function printContent() {
1185 $this->content
.= $this->doc
->endPage();
1186 echo $this->content
;
1190 // Include extension?
1191 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE
]['XCLASS']['typo3/alt_clickmenu.php']) {
1192 include_once($TYPO3_CONF_VARS[TYPO3_MODE
]['XCLASS']['typo3/alt_clickmenu.php']);
1205 $SOBE = t3lib_div
::makeInstance('SC_alt_clickmenu');
1209 reset($SOBE->include_once);
1210 while(list(,$INC_FILE)=each($SOBE->include_once)) {include_once($INC_FILE);}
1213 $SOBE->printContent();