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