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