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