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