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