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