cleaner backend project: modified interface for toolbar items to add access chechking
[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">SU: '.$icon.'<span>'.htmlspecialchars($label).'</span>';
280 }
281
282 return '<div id="username" class="toolbar-item no-separator'.$username.'</div>';
283 }
284
285 /**
286 * Generates the JavaScript code for the backend.
287 *
288 * @return void
289 */
290 private function generateJavascript() {
291
292 $pathTYPO3 = t3lib_div::dirname(t3lib_div::getIndpEnv('SCRIPT_NAME')).'/';
293 $goToModuleSwitch = $this->moduleMenu->getGotoModuleJavascript();
294 $moduleFramesHelper = implode(chr(10), $this->moduleMenu->getFsMod());
295
296 // If another page module was specified, replace the default Page module with the new one
297 $newPageModule = trim($GLOBALS['BE_USER']->getTSConfigVal('options.overridePageModule'));
298 $pageModule = t3lib_BEfunc::isModuleSetInTBE_MODULES($newPageModule) ? $newPageModule : 'web_layout';
299
300 $menuFrameName = 'menu';
301 if($GLOBALS['BE_USER']->uc['noMenuMode'] === 'icons') {
302 $menuFrameName = 'topmenuFrame';
303 }
304
305 $this->js .= '
306 /**
307 * Function similar to PHPs rawurlencode();
308 */
309 function rawurlencode(str) { //
310 var output = escape(str);
311 output = str_replace("*","%2A", output);
312 output = str_replace("+","%2B", output);
313 output = str_replace("/","%2F", output);
314 output = str_replace("@","%40", output);
315 return output;
316 }
317
318 /**
319 * String-replace function
320 */
321 function str_replace(match,replace,string) { //
322 var input = ""+string;
323 var matchStr = ""+match;
324 if (!matchStr) {return string;}
325 var output = "";
326 var pointer=0;
327 var pos = input.indexOf(matchStr);
328 while (pos!=-1) {
329 output+=""+input.substr(pointer, pos-pointer)+replace;
330 pointer=pos+matchStr.length;
331 pos = input.indexOf(match,pos+1);
332 }
333 output+=""+input.substr(pointer);
334 return output;
335 }
336
337 /**
338 * TypoSetup object.
339 */
340 function typoSetup() { //
341 this.PATH_typo3 = "'.$pathTYPO3.'";
342 this.PATH_typo3_enc = "'.rawurlencode($pathTYPO3).'";
343 this.username = "'.$GLOBALS['BE_USER']->user['username'].'";
344 this.uniqueID = "'.t3lib_div::shortMD5(uniqid('')).'";
345 this.navFrameWidth = 0;
346 }
347 var TS = new typoSetup();
348
349 /**
350 * Functions for session-expiry detection:
351 */
352 function busy() { //
353 this.loginRefreshed = busy_loginRefreshed;
354 this.checkLoginTimeout = busy_checkLoginTimeout;
355 this.openRefreshWindow = busy_OpenRefreshWindow;
356 this.busyloadTime=0;
357 this.openRefreshW=0;
358 this.reloginCancelled=0;
359 }
360 function busy_loginRefreshed() { //
361 var date = new Date();
362 this.busyloadTime = Math.floor(date.getTime()/1000);
363 this.openRefreshW=0;
364 }
365 function busy_checkLoginTimeout() { //
366 var date = new Date();
367 var theTime = Math.floor(date.getTime()/1000);
368 if (theTime > this.busyloadTime+'.intval($GLOBALS['BE_USER']->auth_timeout_field).'-30) {
369 return true;
370 }
371 }
372 function busy_OpenRefreshWindow() { //
373 vHWin=window.open("login_frameset.php","relogin_"+TS.uniqueID,"height=350,width=700,status=0,menubar=0,location=1");
374 vHWin.focus();
375 this.openRefreshW=1;
376 }
377 function busy_checkLoginTimeout_timer() { //
378 if (busy.checkLoginTimeout() && !busy.reloginCancelled && !busy.openRefreshW) {
379 if (confirm('.$GLOBALS['LANG']->JScharCode($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:mess.refresh_login')).')) {
380 busy.openRefreshWindow();
381 } else {
382 busy.reloginCancelled = 1;
383 }
384 }
385 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())
386
387 // 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!)
388 if (top && top.content && top.content.nav_frame && top.content.nav_frame.document && top.content.nav_frame.document.body) {
389 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;
390 }
391 }
392
393 /**
394 * Launcing information window for records/files (fileref as "table" argument)
395 */
396 function launchView(table,uid,bP) { //
397 var backPath= bP ? bP : "";
398 var thePreviewWindow="";
399 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");
400 if (thePreviewWindow && thePreviewWindow.focus) {
401 thePreviewWindow.focus();
402 }
403 }
404
405 /**
406 * Opens plain window with url
407 */
408 function openUrlInWindow(url,windowName) { //
409 regularWindow = window.open(url,windowName,"status=1,menubar=1,resizable=1,location=1,directories=0,scrollbars=1,toolbar=1");
410 regularWindow.focus();
411 return false;
412 }
413
414 /**
415 * Loads a page id for editing in the page edit module:
416 */
417 function loadEditId(id,addGetVars) { //
418 top.fsMod.recentIds["web"]=id;
419 top.fsMod.navFrameHighlightedID["web"]="pages"+id+"_0"; // For highlighting
420
421 if (top.content && top.content.nav_frame && top.content.nav_frame.refresh_nav) {
422 top.content.nav_frame.refresh_nav();
423 }
424
425 top.goToModule("'.$pageModule.'", 0, addGetVars?addGetVars:"");
426 }
427
428 /**
429 * Returns incoming URL (to a module) unless nextLoadModuleUrl is set. If that is the case nextLoadModuleUrl is returned (and cleared)
430 * Used by the shortcut frame to set a "intermediate URL"
431 */
432 var nextLoadModuleUrl="";
433 function getModuleUrl(inUrl) { //
434 var nMU;
435 if (top.nextLoadModuleUrl) {
436 nMU=top.nextLoadModuleUrl;
437 top.nextLoadModuleUrl="";
438 return nMU;
439 } else {
440 return inUrl;
441 }
442 }
443
444 /**
445 * Print properties of an object
446 */
447 function debugObj(obj,name) { //
448 var acc;
449 for (i in obj) {
450 if (obj[i]) {
451 acc+=i+": "+obj[i]+"\n";
452 }
453 }
454 alert("Object: "+name+"\n\n"+acc);
455 }
456
457 /**
458 * Initialize login expiration warning object
459 */
460 var busy = new busy();
461 busy.loginRefreshed();
462 busy_checkLoginTimeout_timer();
463
464 /**
465 * Function used to switch modules
466 */
467 var currentModuleLoaded = "";
468 var goToModule = '.$goToModuleSwitch.'
469
470 /**
471 * Frameset Module object
472 *
473 * Used in main modules with a frameset for submodules to keep the ID between modules
474 * Typically that is set by something like this in a Web>* sub module:
475 * if (top.fsMod) top.fsMod.recentIds["web"] = "\'.intval($this->id).\'";
476 * if (top.fsMod) top.fsMod.recentIds["file"] = "...(file reference/string)...";
477 */
478 function fsModules() { //
479 this.recentIds=new Array(); // used by frameset modules to track the most recent used id for list frame.
480 this.navFrameHighlightedID=new Array(); // used by navigation frames to track which row id was highlighted last time
481 this.currentMainLoaded="";
482 this.currentBank="0";
483 }
484 var fsMod = new fsModules();
485 '.$moduleFramesHelper.'
486
487 // Used by Frameset Modules
488 var condensedMode = '.($GLOBALS['BE_USER']->uc['condensedMode']?1:0).';
489 var currentSubScript = "";
490 var currentSubNavScript = "";
491
492 // Used for tab-panels:
493 var DTM_currentTabs = new Array();
494 ';
495
496 // Check editing of page:
497 $this->handlePageEditing();
498 $this->setStartupModule();
499 }
500
501 /**
502 * Checking if the "&edit" variable was sent so we can open it for editing the page.
503 * Code based on code from "alt_shortcut.php"
504 *
505 * @return void
506 */
507 private function handlePageEditing() {
508
509 if(!t3lib_extMgm::isLoaded('cms')) {
510 return;
511 }
512
513 // EDIT page:
514 $editId = preg_replace('/[^[:alnum:]_]/', '', t3lib_div::_GET('edit'));
515 $editRecord = '';
516
517 if($editId) {
518
519 // Looking up the page to edit, checking permissions:
520 $where = ' AND ('.$GLOBALS['BE_USER']->getPagePermsClause(2)
521 .' OR '.$GLOBALS['BE_USER']->getPagePermsClause(16).')';
522
523 if(t3lib_div::testInt($editId)) {
524 $editRecord = t3lib_BEfunc::getRecordWSOL('pages', $editId, '*', $where);
525 } else {
526 $records = t3lib_BEfunc::getRecordsByField('pages', 'alias', $editId, $where);
527
528 if(is_array($records)) {
529 reset($records);
530 $editRecord = current($records);
531 t3lib_BEfunc::workspaceOL('pages', $editRecord);
532 }
533 }
534
535 // If the page was accessible, then let the user edit it.
536 if(is_array($editRecord) && $GLOBALS['BE_USER']->isInWebMount($editRecord['uid'])) {
537 // Setting JS code to open editing:
538 $this->js .= '
539 // Load page to edit:
540 window.setTimeout("top.loadEditId('.intval($editRecord['uid']).');", 500);
541 ';
542 // Checking page edit parameter:
543 if(!$GLOBALS['BE_USER']->getTSConfigVal('options.shortcut_onEditId_dontSetPageTree')) {
544
545 // Expanding page tree:
546 t3lib_BEfunc::openPageTree(intval($editRecord['pid']), !$GLOBALS['BE_USER']->getTSConfigVal('options.shortcut_onEditId_keepExistingExpanded'));
547 }
548 } else {
549 $this->js .= '
550 // Warning about page editing:
551 alert('.$GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->getLL('noEditPage'), $editId)).');
552 ';
553 }
554 }
555 }
556
557 /**
558 * Sets the startup module from either GETvars module and mpdParams or user configuration.
559 *
560 * @return void
561 */
562 private function setStartupModule() {
563 $startModule = preg_replace('/[^[:alnum:]_]/', '', t3lib_div::_GET('module'));
564
565 if(!$startModule) {
566 if ($GLOBALS['BE_USER']->uc['startModule']) {
567 $startModule = $GLOBALS['BE_USER']->uc['startModule'];
568 } else if($GLOBALS['BE_USER']->uc['startInTaskCenter']) {
569 $startModule = 'user_task';
570 }
571 }
572
573 $moduleParameters = t3lib_div::_GET('modParams');
574 if($startModule) {
575 $this->js .= '
576 // start in module:
577 function startInModule(modName, cMR_flag, addGetVars) {
578 Event.observe(document, \'dom:loaded\', function() {
579 top.goToModule(modName, cMR_flag, addGetVars);
580 });
581 }
582
583 startInModule(\''.$startModule.'\', false, \''.$moduleParameters.'\');
584 ';
585 }
586 }
587
588 /**
589 * generates the code for the TYPO3 logo, either the default TYPO3 logo or a custom one
590 *
591 * @return string HTML code snippet to display the TYPO3 logo
592 */
593 private function getLogo() {
594 $logo = '<a href="http://www.typo3.com/" target="_blank" onclick="'.$GLOBALS['TBE_TEMPLATE']->thisBlur().'">'.
595 '<img'.t3lib_iconWorks::skinImg('','gfx/alt_backend_logo.gif','width="117" height="32"').' title="TYPO3 Content Management Framework" alt="" />'.
596 '</a>';
597
598 // overwrite with custom logo
599 if($GLOBALS['TBE_STYLES']['logo']) {
600 if(substr($GLOBALS['TBE_STYLES']['logo'], 0, 3) == '../') {
601 $imgInfo = @getimagesize(PATH_site.substr($GLOBALS['TBE_STYLES']['logo'], 3));
602 }
603 $logo = '<a href="http://www.typo3.com/" target="_blank" onclick="'.$GLOBALS['TBE_TEMPLATE']->thisBlur().'">'.
604 '<img src="'.$GLOBALS['TBE_STYLES']['logo'].'" '.$imgInfo[3].' title="TYPO3 Content Management Framework" alt="" />'.
605 '</a>';
606 }
607
608 return $logo;
609 }
610
611 /**
612 * adds a javascript snippet to the backend
613 *
614 * @param string javascript snippet
615 * @return void
616 */
617 public function addJavascript($javascript) {
618 // TODO do we need more checks?
619 if(!is_string($javascript)) {
620 throw new InvalidArgumentException('parameter $javascript must be of type string', 1195129553);
621 }
622
623 $this->js .= $javascript;
624 }
625
626 /**
627 * adds a javscript file to the backend after it has been checked that it exists
628 *
629 * @param string javascript file reference
630 * @return boolean true if the javascript file was successfully added, false otherwise
631 */
632 public function addJavascriptFile($javascriptFile) {
633 $jsFileAdded = false;
634
635 //TODO add more checks if neccessary
636 if(file_exists(t3lib_div::resolveBackPath(PATH_typo3.$javascriptFile))) {
637 $this->jsFiles[] = $javascriptFile;
638 $jsFileAdded = true;
639 }
640
641 return $jsFileAdded;
642 }
643
644 /**
645 * adds a css snippet to the backend
646 *
647 * @param string css snippet
648 * @return void
649 */
650 public function addCss($css) {
651 if(!is_string($css)) {
652 throw new InvalidArgumentException('parameter $css must be of type string', 1195129642);
653 }
654
655 $this->css .= $css;
656 }
657
658 /**
659 * adds a css file to the backend after it has been checked that it exists
660 *
661 * @param string the css file's name with out the .css ending
662 * @param string css file reference
663 * @return boolean true if the css file was added, false otherwise
664 */
665 public function addCssFile($cssFileName, $cssFile) {
666 $cssFileAdded = false;
667
668 //TODO add more checks if neccessary
669 if(file_exists(t3lib_div::resolveBackPath(PATH_typo3.$cssFile))) {
670 // prevent overwriting existing css files
671 if(empty($this->cssFiles[$cssFileName])) {
672 $this->cssFiles[$cssFileName] = $cssFile;
673 $cssFileAdded = true;
674 }
675 }
676
677 return $cssFileAdded;
678 }
679
680 /**
681 * adds an item to the toolbar, the class file for the toolbar item must be loaded at this point
682 *
683 * @param string toolbar item name, f.e. tx_toolbarExtension_coolItem
684 * @param string toolbar item class name, f.e. tx_toolbarExtension_coolItem
685 * @return void
686 */
687 public function addToolbarItem($toolbarItemName, $toolbarItemClassName) {
688 $toolbarItemResolvedClassName = t3lib_div::makeInstanceClassName($toolbarItemClassName);
689 $toolbarItem = new $toolbarItemResolvedClassName($this);
690
691 if(!($toolbarItem instanceof backend_toolbarItem)) {
692 throw new UnexpectedValueException('$toolbarItem "'.$toolbarItemName.'" must implement interface backend_toolbarItem', 1195125501);
693 }
694
695 if($toolbarItem->checkAccess()) {
696 $this->toolbarItems[$toolbarItemName] = $toolbarItem;
697 } else {
698 unset($toolbarItem);
699 }
700 }
701 }
702
703
704 // include XCLASS
705 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/backend.php']) {
706 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/backend.php']);
707 }
708
709
710 // document generation
711 $TYPO3backend = t3lib_div::makeInstance('TYPO3backend');
712
713 // include extensions which may add css, javascript or toolbar items
714 if(is_array($GLOBALS['TYPO3_CONF_VARS']['typo3/backend.php']['additionalBackendItems'])) {
715 foreach($GLOBALS['TYPO3_CONF_VARS']['typo3/backend.php']['additionalBackendItems'] as $additionalBackendItem) {
716 include_once($additionalBackendItem);
717 }
718 }
719
720 $TYPO3backend->render();
721
722 ?>