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