Followup to #7282: Username is now only linked to user setup if the module is accessible
[Packages/TYPO3.CMS.git] / typo3 / backend.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2007 Ingo Renner <ingo@typo3.org>
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 require_once('init.php');
29 require_once('template.php');
30 require_once('interfaces/interface.backend_toolbaritem.php');
31
32 require('classes/class.typo3logo.php');
33 require('classes/class.modulemenu.php');
34
35 // core toolbar items
36 require('classes/class.workspaceselector.php');
37 require('classes/class.clearcachemenu.php');
38 require('classes/class.shortcutmenu.php');
39 require('classes/class.backendsearchmenu.php');
40
41 require_once(PATH_t3lib.'class.t3lib_loadmodules.php');
42 require_once(PATH_t3lib.'class.t3lib_basicfilefunc.php');
43 require_once('class.alt_menu_functions.inc');
44 $GLOBALS['LANG']->includeLLFile('EXT:lang/locallang_misc.xml');
45
46
47 /**
48 * Class for rendering the TYPO3 backend version 4.2+
49 *
50 * @author Ingo Renner <ingo@typo3.org>
51 * @package TYPO3
52 * @subpackage core
53 */
54 class TYPO3backend {
55
56 private $content;
57 private $css;
58 private $cssFiles;
59 private $js;
60 private $jsFiles;
61
62 /**
63 * Object for loading backend modules
64 *
65 * @var t3lib_loadModules
66 */
67 private $moduleLoader;
68
69 /**
70 * module menu generating object
71 *
72 * @var ModuleMenu
73 */
74 private $moduleMenu;
75
76 private $leftMenuWidth;
77 private $topHeight;
78 private $selectMenu;
79 private $toolbarItems;
80
81 /**
82 * constructor
83 *
84 * @return void
85 */
86 public function __construct() {
87 // Initializes the backend modules structure for use later.
88 $this->moduleLoader = t3lib_div::makeInstance('t3lib_loadModules');
89 $this->moduleLoader->load($GLOBALS['TBE_MODULES']);
90
91 $this->moduleMenu = t3lib_div::makeInstance('ModuleMenu');
92
93 // Check for distances defined in the styles array:
94 if ($TBE_STYLES['dims']['leftMenuFrameW']) {
95 $this->leftMenuWidth = $TBE_STYLES['dims']['leftMenuFrameW'];
96 }
97 if ($TBE_STYLES['dims']['topFrameH']) {
98 $this->topHeight = $TBE_STYLES['dims']['topFrameH'];
99 }
100 if ($TBE_STYLES['dims']['selMenuFrame']) {
101 $this->selectMenu = $TBE_STYLES['dims']['selMenuFrame'];
102 }
103
104 // add default BE javascript
105 $this->js = '';
106 $this->jsFiles = array(
107 'contrib/prototype/prototype.js',
108 'contrib/scriptaculous/scriptaculous.js?load=builder,effects,controls,dragdrop',
109 'md5.js',
110 'js/backend.js',
111 'js/common.js',
112 'js/sizemanager.js',
113 'js/toolbarmanager.js',
114 'js/modulemenu.js',
115 '../t3lib/jsfunc.evalfield.js'
116 );
117
118 // add default BE css
119 $this->css = '';
120 $this->cssFiles = array(
121 'backend-scaffolding' => 'css/backend-scaffolding.css',
122 'backend-style' => 'css/backend-style.css',
123 'modulemenu' => 'css/modulemenu.css'
124 );
125
126 $this->toolbarItems = array();
127 $this->initializeCoreToolbarItems();
128 }
129
130 /**
131 * initializes the core toolbar items
132 *
133 * @return void
134 */
135 private function initializeCoreToolbarItems() {
136
137 $coreToolbarItems = array(
138 'workspaceSelector' => 'WorkspaceSelector',
139 'clearCacheActions' => 'ClearCacheMenu',
140 'shortcuts' => 'ShortcutMenu',
141 'backendSearch' => 'BackendSearchMenu'
142 );
143
144 foreach($coreToolbarItems as $toolbarItemName => $toolbarItemClass) {
145 $toolbarItem = t3lib_div::makeInstance($toolbarItemClass);
146
147 if(!($toolbarItem instanceof backend_toolbarItem)) {
148 throw new UnexpectedValueException('$toolbarItem "'.$toolbarItemName.'" must implement interface backend_toolbarItem', 1195126772);
149 }
150
151 $toolbarItem->setBackend($this);
152 $this->toolbarItems[$toolbarItemName] = $toolbarItem;
153 }
154 }
155
156 /**
157 * main function generating the BE scaffolding
158 *
159 * @return void
160 */
161 public function render() {
162
163 // prepare the scaffolding, at this point extension may still add javascript and css
164 $logo = t3lib_div::makeInstance('TYPO3Logo');
165 $logo->setLogo('gfx/typo3logo_mini.png');
166
167 $menu = $this->moduleMenu->render();
168
169
170 // create backend scaffolding
171 $backendScaffolding = '
172 <div id="typo3-backend">
173 <div id="typo3-top-container">
174 <div id="typo3-logo">'.$logo->render().'</div>
175 <div id="typo3-top" class="typo3-top-toolbar">'
176 .$this->renderToolbar()
177 .'</div>
178 </div>
179 <div id="typo3-main-container">
180 <div id="typo3-side-menu">
181 '.$menu.'
182 </div>
183 <div id="typo3-content">
184 <iframe src="alt_intro.php" name="content" id="content" marginwidth="0" marginheight="0" frameborder="0" scrolling="auto" noresize="noresize"></iframe>
185 </div>
186 </div>
187 </div>
188 </body>
189 </html>';
190
191 /******************************************************
192 * now put the complete backend document together
193 ******************************************************/
194
195 // set doctype
196 $GLOBALS['TBE_TEMPLATE']->docType = 'xhtml_trans';
197
198 // add javascript
199 foreach($this->jsFiles as $jsFile) {
200 $GLOBALS['TBE_TEMPLATE']->JScode .= '
201 <script type="text/javascript" src="'.$jsFile.'"></script>';
202 }
203 $GLOBALS['TBE_TEMPLATE']->JScode .= chr(10);
204 $this->generateJavascript();
205 $GLOBALS['TBE_TEMPLATE']->JScode .= $GLOBALS['TBE_TEMPLATE']->wrapScriptTags($this->js);
206
207 // FIXME abusing the JS container to add CSS, need to fix template.php
208 foreach($this->cssFiles as $cssFileName => $cssFile) {
209 $GLOBALS['TBE_TEMPLATE']->JScode .= '
210 <link rel="stylesheet" type="text/css" href="'.$cssFile.'" />
211 ';
212
213 // load addditional css files to overwrite existing core styles
214 if(!empty($GLOBALS['TBE_STYLES']['stylesheets'][$cssFileName])) {
215 $GLOBALS['TBE_TEMPLATE']->JScode .= '
216 <link rel="stylesheet" type="text/css" href="'.$GLOBALS['TBE_STYLES']['stylesheets'][$cssFileName].'" />
217 ';
218 }
219 }
220
221 if(!empty($this->css)) {
222 $GLOBALS['TBE_TEMPLATE']->JScode .= '
223 <style type="text/css" id="internalStyle">
224 '.$this->css.'
225 </style>';
226 }
227
228 // set document title
229 $title = $TYPO3_CONF_VARS['SYS']['sitename'] ?
230 $TYPO3_CONF_VARS['SYS']['sitename'].' [TYPO3 '.TYPO3_version.']'
231 : 'TYPO3 '.TYPO3_version;
232
233 // start page header:
234 $this->content .= $GLOBALS['TBE_TEMPLATE']->startPage($title);
235 $this->content .= $GLOBALS['TBE_TEMPLATE']->endPage();
236
237 $this->content .= $backendScaffolding;
238
239 echo $this->content;
240 }
241
242 /**
243 * renders the items in the top toolbar
244 *
245 * @return string top toolbar elements as HTML
246 */
247 private function renderToolbar() {
248 $toolbar = '<ul id="typo3-toolbar">';
249 $toolbar.= '<li>'.$this->getLoggedInUserLabel().'</li>
250 <li><div id="logout-button" class="toolbar-item no-separator">'.$this->moduleMenu->renderLogoutButton().'</div></li>';
251
252 foreach($this->toolbarItems as $toolbarItem) {
253 $additionalAttributes = $toolbarItem->getAdditionalAttributes();
254
255 $toolbar .= '<li'.$additionalAttributes.'>'.$toolbarItem->render().'</li>';
256 }
257
258 return $toolbar.'</ul>';
259 }
260
261 /**
262 * gets the label of the currently loged in BE user
263 *
264 * @return string html code snippet displaying the currently logged in user
265 */
266 private function getLoggedInUserLabel() {
267 global $BE_USER, $BACK_PATH;
268
269 $icon = '<img'.t3lib_iconWorks::skinImg(
270 '',
271 $BE_USER->isAdmin() ?
272 'gfx/i/be_users_admin.gif' :
273 'gfx/i/be_users.gif',
274 'width="18" height="16"'
275 )
276 .' title="" alt="" />';
277
278 $label = $GLOBALS['BE_USER']->user['realName'] ?
279 $BE_USER->user['realName'].' ['.$BE_USER->user['username'].']' :
280 '['.$BE_USER->user['username'].']';
281
282 // Link to user setup if it's loaded and user has access
283 $link = '';
284 if (t3lib_extMgm::isLoaded('setup') && $BE_USER->check('modules','user_setup')) {
285 $link = '<a href="#" onclick="top.goToModule(\'user_setup\');this.blur();return false;">';
286 }
287
288 $username = '">'.$link.$icon.'<span>'.htmlspecialchars($label).'</span>'.($link?'</a>':'');
289
290 // superuser mode
291 if($BE_USER->user['ses_backuserid']) {
292 $username = ' su-user">SU: '.$icon.'<span>'.htmlspecialchars($label).'</span>';
293 }
294
295 return '<div id="username" class="toolbar-item no-separator'.$username.'</div>';
296 }
297
298 /**
299 * Generates the JavaScript code for the backend.
300 *
301 * @return void
302 */
303 private function generateJavascript() {
304
305 $pathTYPO3 = t3lib_div::dirname(t3lib_div::getIndpEnv('SCRIPT_NAME')).'/';
306 $goToModuleSwitch = $this->moduleMenu->getGotoModuleJavascript();
307 $moduleFramesHelper = implode(chr(10), $this->moduleMenu->getFsMod());
308
309 // If another page module was specified, replace the default Page module with the new one
310 $newPageModule = trim($GLOBALS['BE_USER']->getTSConfigVal('options.overridePageModule'));
311 $pageModule = t3lib_BEfunc::isModuleSetInTBE_MODULES($newPageModule) ? $newPageModule : 'web_layout';
312
313 $menuFrameName = 'menu';
314 if($GLOBALS['BE_USER']->uc['noMenuMode'] === 'icons') {
315 $menuFrameName = 'topmenuFrame';
316 }
317
318 $this->js .= '
319 /**
320 * Function similar to PHPs rawurlencode();
321 */
322 function rawurlencode(str) { //
323 var output = escape(str);
324 output = str_replace("*","%2A", output);
325 output = str_replace("+","%2B", output);
326 output = str_replace("/","%2F", output);
327 output = str_replace("@","%40", output);
328 return output;
329 }
330
331 /**
332 * String-replace function
333 */
334 function str_replace(match,replace,string) { //
335 var input = ""+string;
336 var matchStr = ""+match;
337 if (!matchStr) {return string;}
338 var output = "";
339 var pointer=0;
340 var pos = input.indexOf(matchStr);
341 while (pos!=-1) {
342 output+=""+input.substr(pointer, pos-pointer)+replace;
343 pointer=pos+matchStr.length;
344 pos = input.indexOf(match,pos+1);
345 }
346 output+=""+input.substr(pointer);
347 return output;
348 }
349
350 /**
351 * TypoSetup object.
352 */
353 function typoSetup() { //
354 this.PATH_typo3 = "'.$pathTYPO3.'";
355 this.PATH_typo3_enc = "'.rawurlencode($pathTYPO3).'";
356 this.username = "'.$GLOBALS['BE_USER']->user['username'].'";
357 this.uniqueID = "'.t3lib_div::shortMD5(uniqid('')).'";
358 this.navFrameWidth = 0;
359 }
360 var TS = new typoSetup();
361
362 /**
363 * Functions for session-expiry detection:
364 */
365 function busy() { //
366 this.loginRefreshed = busy_loginRefreshed;
367 this.checkLoginTimeout = busy_checkLoginTimeout;
368 this.openRefreshWindow = busy_OpenRefreshWindow;
369 this.busyloadTime=0;
370 this.openRefreshW=0;
371 this.reloginCancelled=0;
372 }
373 function busy_loginRefreshed() { //
374 var date = new Date();
375 this.busyloadTime = Math.floor(date.getTime()/1000);
376 this.openRefreshW=0;
377 }
378 function busy_checkLoginTimeout() { //
379 var date = new Date();
380 var theTime = Math.floor(date.getTime()/1000);
381 if (theTime > this.busyloadTime+'.intval($GLOBALS['BE_USER']->auth_timeout_field).'-30) {
382 return true;
383 }
384 }
385 function busy_OpenRefreshWindow() { //
386 vHWin=window.open("login_frameset.php","relogin_"+TS.uniqueID,"height=350,width=700,status=0,menubar=0,location=1");
387 vHWin.focus();
388 this.openRefreshW=1;
389 }
390 function busy_checkLoginTimeout_timer() { //
391 if (busy.checkLoginTimeout() && !busy.reloginCancelled && !busy.openRefreshW) {
392 if (confirm('.$GLOBALS['LANG']->JScharCode($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:mess.refresh_login')).')) {
393 busy.openRefreshWindow();
394 } else {
395 busy.reloginCancelled = 1;
396 }
397 }
398 window.setTimeout("busy_checkLoginTimeout_timer();",2*1000); // Each 2nd second is enough for checking. The popup will be triggered 10 seconds before the login expires (see above, busy_checkLoginTimeout())
399
400 // Detecting the frameset module navigation frame widths (do this AFTER setting new timeout so that any errors in the code below does not prevent another time to be set!)
401 if (top && top.content && top.content.nav_frame && top.content.nav_frame.document && top.content.nav_frame.document.body) {
402 TS.navFrameWidth = (top.content.nav_frame.document.documentElement && top.content.nav_frame.document.documentElement.clientWidth) ? top.content.nav_frame.document.documentElement.clientWidth : top.content.nav_frame.document.body.clientWidth;
403 }
404 }
405
406 /**
407 * Launcing information window for records/files (fileref as "table" argument)
408 */
409 function launchView(table,uid,bP) { //
410 var backPath= bP ? bP : "";
411 var thePreviewWindow="";
412 thePreviewWindow = window.open(TS.PATH_typo3+"show_item.php?table="+encodeURIComponent(table)+"&uid="+encodeURIComponent(uid),"ShowItem"+TS.uniqueID,"height=400,width=550,status=0,menubar=0,resizable=0,location=0,directories=0,scrollbars=1,toolbar=0");
413 if (thePreviewWindow && thePreviewWindow.focus) {
414 thePreviewWindow.focus();
415 }
416 }
417
418 /**
419 * Opens plain window with url
420 */
421 function openUrlInWindow(url,windowName) { //
422 regularWindow = window.open(url,windowName,"status=1,menubar=1,resizable=1,location=1,directories=0,scrollbars=1,toolbar=1");
423 regularWindow.focus();
424 return false;
425 }
426
427 /**
428 * Loads a URL in the topmenuFrame
429 */
430 function loadTopMenu(url) { //
431 top.topmenuFrame.location = url;
432 }
433
434 /**
435 * Loads a page id for editing in the page edit module:
436 */
437 function loadEditId(id,addGetVars) { //
438 top.fsMod.recentIds["web"]=id;
439 top.fsMod.navFrameHighlightedID["web"]="pages"+id+"_0"; // For highlighting
440
441 if (top.content && top.content.nav_frame && top.content.nav_frame.refresh_nav) {
442 top.content.nav_frame.refresh_nav();
443 }
444
445 top.goToModule("'.$pageModule.'", 0, addGetVars?addGetVars:"");
446 }
447
448 /**
449 * Returns incoming URL (to a module) unless nextLoadModuleUrl is set. If that is the case nextLoadModuleUrl is returned (and cleared)
450 * Used by the shortcut frame to set a "intermediate URL"
451 */
452 var nextLoadModuleUrl="";
453 function getModuleUrl(inUrl) { //
454 var nMU;
455 if (top.nextLoadModuleUrl) {
456 nMU=top.nextLoadModuleUrl;
457 top.nextLoadModuleUrl="";
458 return nMU;
459 } else {
460 return inUrl;
461 }
462 }
463
464 /**
465 * Print properties of an object
466 */
467 function debugObj(obj,name) { //
468 var acc;
469 for (i in obj) {
470 if (obj[i]) {
471 acc+=i+": "+obj[i]+"\n";
472 }
473 }
474 alert("Object: "+name+"\n\n"+acc);
475 }
476
477 /**
478 * Initialize login expiration warning object
479 */
480 var busy = new busy();
481 busy.loginRefreshed();
482 busy_checkLoginTimeout_timer();
483
484 /**
485 * Function used to switch modules
486 */
487 var currentModuleLoaded = "";
488 var goToModule = '.$goToModuleSwitch.'
489
490 /**
491 * Frameset Module object
492 *
493 * Used in main modules with a frameset for submodules to keep the ID between modules
494 * Typically that is set by something like this in a Web>* sub module:
495 * if (top.fsMod) top.fsMod.recentIds["web"] = "\'.intval($this->id).\'";
496 * if (top.fsMod) top.fsMod.recentIds["file"] = "...(file reference/string)...";
497 */
498 function fsModules() { //
499 this.recentIds=new Array(); // used by frameset modules to track the most recent used id for list frame.
500 this.navFrameHighlightedID=new Array(); // used by navigation frames to track which row id was highlighted last time
501 this.currentMainLoaded="";
502 this.currentBank="0";
503 }
504 var fsMod = new fsModules();
505 '.$moduleFramesHelper.'
506
507 // Used by Frameset Modules
508 var condensedMode = '.($GLOBALS['BE_USER']->uc['condensedMode']?1:0).';
509 var currentSubScript = "";
510 var currentSubNavScript = "";
511
512 // Used for tab-panels:
513 var DTM_currentTabs = new Array();
514 ';
515
516 // Check editing of page:
517 $this->handlePageEditing();
518 $this->setStartupModule();
519 }
520
521 /**
522 * Checking if the "&edit" variable was sent so we can open it for editing the page.
523 * Code based on code from "alt_shortcut.php"
524 *
525 * @return void
526 */
527 private function handlePageEditing() {
528
529 if(!t3lib_extMgm::isLoaded('cms')) {
530 return;
531 }
532
533 // EDIT page:
534 $editId = preg_replace('/[^[:alnum:]_]/', '', t3lib_div::_GET('edit'));
535 $editRecord = '';
536
537 if($editId) {
538
539 // Looking up the page to edit, checking permissions:
540 $where = ' AND ('.$GLOBALS['BE_USER']->getPagePermsClause(2)
541 .' OR '.$GLOBALS['BE_USER']->getPagePermsClause(16).')';
542
543 if(t3lib_div::testInt($editId)) {
544 $editRecord = t3lib_BEfunc::getRecordWSOL('pages', $editId, '*', $where);
545 } else {
546 $records = t3lib_BEfunc::getRecordsByField('pages', 'alias', $editId, $where);
547
548 if(is_array($records)) {
549 reset($records);
550 $editRecord = current($records);
551 t3lib_BEfunc::workspaceOL('pages', $editRecord);
552 }
553 }
554
555 // If the page was accessible, then let the user edit it.
556 if(is_array($editRecord) && $GLOBALS['BE_USER']->isInWebMount($editRecord['uid'])) {
557 // Setting JS code to open editing:
558 $this->js .= '
559 // Load page to edit:
560 window.setTimeout("top.loadEditId('.intval($editRecord['uid']).');", 500);
561 ';
562 // Checking page edit parameter:
563 if(!$GLOBALS['BE_USER']->getTSConfigVal('options.shortcut_onEditId_dontSetPageTree')) {
564
565 // Expanding page tree:
566 t3lib_BEfunc::openPageTree(intval($editRecord['pid']), !$GLOBALS['BE_USER']->getTSConfigVal('options.shortcut_onEditId_keepExistingExpanded'));
567 }
568 } else {
569 $this->js .= '
570 // Warning about page editing:
571 alert('.$GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->getLL('noEditPage'), $editId)).');
572 ';
573 }
574 }
575 }
576
577 /**
578 * Sets the startup module from either GETvars module and mpdParams or user configuration.
579 *
580 * @return void
581 */
582 private function setStartupModule() {
583 $startModule = preg_replace('/[^[:alnum:]_]/', '', t3lib_div::_GET('module'));
584
585 if(!$startModule) {
586 if ($GLOBALS['BE_USER']->uc['startModule']) {
587 $startModule = $GLOBALS['BE_USER']->uc['startModule'];
588 } else if($GLOBALS['BE_USER']->uc['startInTaskCenter']) {
589 $startModule = 'user_task';
590 }
591 }
592
593 $moduleParameters = t3lib_div::_GET('modParams');
594 if($startModule) {
595 $this->js .= '
596 // start in module:
597 function startInModule(modName, cMR_flag, addGetVars) {
598 Event.observe(document, \'dom:loaded\', function() {
599 top.goToModule(modName, cMR_flag, addGetVars);
600 });
601 }
602
603 startInModule(\''.$startModule.'\', false, \''.$moduleParameters.'\');
604 ';
605 }
606 }
607
608 /**
609 * generates the code for the TYPO3 logo, either the default TYPO3 logo or a custom one
610 *
611 * @return string HTML code snippet to display the TYPO3 logo
612 */
613 private function getLogo() {
614 $logo = '<a href="http://www.typo3.com/" target="_blank" onclick="'.$GLOBALS['TBE_TEMPLATE']->thisBlur().'">'.
615 '<img'.t3lib_iconWorks::skinImg('','gfx/alt_backend_logo.gif','width="117" height="32"').' title="TYPO3 Content Management Framework" alt="" />'.
616 '</a>';
617
618 // overwrite with custom logo
619 if($GLOBALS['TBE_STYLES']['logo']) {
620 if(substr($GLOBALS['TBE_STYLES']['logo'], 0, 3) == '../') {
621 $imgInfo = @getimagesize(PATH_site.substr($GLOBALS['TBE_STYLES']['logo'], 3));
622 }
623 $logo = '<a href="http://www.typo3.com/" target="_blank" onclick="'.$GLOBALS['TBE_TEMPLATE']->thisBlur().'">'.
624 '<img src="'.$GLOBALS['TBE_STYLES']['logo'].'" '.$imgInfo[3].' title="TYPO3 Content Management Framework" alt="" />'.
625 '</a>';
626 }
627
628 return $logo;
629 }
630
631 /**
632 * adds a javascript snippet to the backend
633 *
634 * @param string javascript snippet
635 * @return void
636 */
637 public function addJavascript($javascript) {
638 // TODO do we need more checks?
639 if(!is_string($javascript)) {
640 throw new InvalidArgumentException('parameter $javascript must be of type string', 1195129553);
641 }
642
643 $this->js .= $javascript;
644 }
645
646 /**
647 * adds a javscript file to the backend after it has been checked that it exists
648 *
649 * @param string javascript file reference
650 * @return boolean true if the javascript file was successfully added, false otherwise
651 */
652 public function addJavascriptFile($javascriptFile) {
653 $jsFileAdded = false;
654
655 //TODO add more checks if neccessary
656 if(file_exists(t3lib_div::resolveBackPath(PATH_typo3.$javascriptFile))) {
657 $this->jsFiles[] = $javascriptFile;
658 $jsFileAdded = true;
659 }
660
661 return $jsFileAdded;
662 }
663
664 /**
665 * adds a css snippet to the backend
666 *
667 * @param string css snippet
668 * @return void
669 */
670 public function addCss($css) {
671 if(!is_string($css)) {
672 throw new InvalidArgumentException('parameter $css must be of type string', 1195129642);
673 }
674
675 $this->css .= $css;
676 }
677
678 /**
679 * adds a css file to the backend after it has been checked that it exists
680 *
681 * @param string the css file's name with out the .css ending
682 * @param string css file reference
683 * @return boolean true if the css file was added, false otherwise
684 */
685 public function addCssFile($cssFileName, $cssFile) {
686 $cssFileAdded = false;
687
688 //TODO add more checks if neccessary
689 if(file_exists(t3lib_div::resolveBackPath(PATH_typo3.$cssFile))) {
690 // prevent overwriting existing css files
691 if(empty($this->cssFiles[$cssFileName])) {
692 $this->cssFiles[$cssFileName] = $cssFile;
693 $cssFileAdded = true;
694 }
695 }
696
697 return $cssFileAdded;
698 }
699
700 /**
701 * adds an item to the toolbar
702 *
703 * @param string toolbar item class reference, f.e. EXT:toolbarextension/class.tx_toolbarextension_coolitem.php:tx_toolbarExtension_coolItem
704 * @param backend_toolbarItem object of an backend_toolbarItem implementation
705 * @return void
706 */
707 public function addToolbarItem($toolbarItemName, $toolbarItemClassReference) {
708 $toolbarItem = t3lib_div::getUserObj($toolbarItemClassReference);
709
710 if(!($toolbarItem instanceof backend_toolbarItem)) {
711 throw new UnexpectedValueException('$toolbarItem "'.$toolbarItemName.'" must implement interface backend_toolbarItem', 1195125501);
712 }
713
714 $toolbarItem->setBackend($this);
715 $this->toolbarItems[$toolbarItemName] = $toolbarItem;
716 }
717 }
718
719
720 // include XCLASS
721 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/backend.php']) {
722 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/backend.php']);
723 }
724
725
726 // document generation
727 $TYPO3backend = t3lib_div::makeInstance('TYPO3backend');
728
729 // include extensions which may add css, javascript or toolbar items
730 if(is_array($GLOBALS['TYPO3_CONF_VARS']['typo3/backend.php']['additionalBackendItems'])) {
731 foreach($GLOBALS['TYPO3_CONF_VARS']['typo3/backend.php']['additionalBackendItems'] as $additionalBackendItem) {
732 include_once($additionalBackendItem);
733 }
734 }
735
736 $TYPO3backend->render();
737
738 ?>