[TASK] Improve username information in top toolbar
[Packages/TYPO3.CMS.git] / typo3 / backend.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2007-2011 Ingo Renner <ingo@typo3.org>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27
28 require_once('init.php');
29 require_once('template.php');
30 require_once(PATH_typo3 . '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.clearcachemenu.php');
37 require('classes/class.shortcutmenu.php');
38 require('classes/class.livesearch.php');
39
40 $GLOBALS['LANG']->includeLLFile('EXT:lang/locallang_misc.xml');
41
42
43 /**
44 * Class for rendering the TYPO3 backend version 4.2+
45 *
46 * @author Ingo Renner <ingo@typo3.org>
47 * @package TYPO3
48 * @subpackage core
49 */
50 class TYPO3backend {
51
52 protected $content;
53 protected $css;
54 protected $cssFiles;
55 protected $js;
56 protected $jsFiles;
57 protected $jsFilesAfterInline;
58 protected $toolbarItems;
59 private $menuWidthDefault = 190; // intentionally private as nobody should modify defaults
60 protected $menuWidth;
61 protected $debug;
62
63 /**
64 * Object for loading backend modules
65 *
66 * @var t3lib_loadModules
67 */
68 protected $moduleLoader;
69
70 /**
71 * module menu generating object
72 *
73 * @var ModuleMenu
74 */
75 protected $moduleMenu;
76
77 /**
78 * Pagerenderer
79 *
80 * @var t3lib_PageRenderer
81 */
82 protected $pageRenderer;
83
84 /**
85 * constructor
86 *
87 * @return void
88 */
89 public function __construct() {
90 // set debug flag for BE development only
91 $this->debug = intval($GLOBALS['TYPO3_CONF_VARS']['BE']['debug']) === 1;
92
93 // Initializes the backend modules structure for use later.
94 $this->moduleLoader = t3lib_div::makeInstance('t3lib_loadModules');
95 $this->moduleLoader->load($GLOBALS['TBE_MODULES']);
96
97 $this->moduleMenu = t3lib_div::makeInstance('ModuleMenu');
98
99 $this->pageRenderer = $GLOBALS['TBE_TEMPLATE']->getPageRenderer();
100 $this->pageRenderer->loadScriptaculous('builder,effects,controls,dragdrop');
101 $this->pageRenderer->loadExtJS();
102 $this->pageRenderer->enableExtJSQuickTips();
103
104
105 $this->pageRenderer->addJsInlineCode(
106 'consoleOverrideWithDebugPanel',
107 '//already done',
108 FALSE
109 );
110 $this->pageRenderer->addExtDirectCode();
111
112 // add default BE javascript
113 $this->js = '';
114 $this->jsFiles = array(
115 'common' => 'js/common.js',
116 'locallang' => $this->getLocalLangFileName(),
117 'modernizr' => 'contrib/modernizr/modernizr.min.js',
118 'swfupload' => 'contrib/swfupload/swfupload.js',
119 'swfupload.swfobject' => 'contrib/swfupload/plugins/swfupload.swfobject.js',
120 'swfupload.cookies' => 'contrib/swfupload/plugins/swfupload.cookies.js',
121 'swfupload.queue' => 'contrib/swfupload/plugins/swfupload.queue.js',
122 'md5' => 'md5.js',
123 'toolbarmanager' => 'js/toolbarmanager.js',
124 'modulemenu' => 'js/modulemenu.js',
125 'iecompatibility' => 'js/iecompatibility.js',
126 'flashupload' => 'js/flashupload.js',
127 'evalfield' => '../t3lib/jsfunc.evalfield.js',
128 'flashmessages' => '../t3lib/js/extjs/ux/flashmessages.js',
129 'tabclosemenu' => '../t3lib/js/extjs/ux/ext.ux.tabclosemenu.js',
130 'notifications' => '../t3lib/js/extjs/notifications.js',
131 'backend' => 'js/backend.js',
132 'loginrefresh' => 'js/loginrefresh.js',
133 'debugPanel' => 'js/extjs/debugPanel.js',
134 'viewport' => 'js/extjs/viewport.js',
135 'iframepanel' => 'js/extjs/iframepanel.js',
136 'modulepanel' => 'js/extjs/modulepanel.js',
137 'viewportConfiguration' => 'js/extjs/viewportConfiguration.js',
138 'util' => '../t3lib/js/extjs/util.js',
139 );
140
141 if ($this->debug) {
142 unset($this->jsFiles['loginrefresh']);
143 }
144
145 // add default BE css
146 $this->css = '';
147 $this->cssFiles = array();
148
149 $this->toolbarItems = array();
150 $this->initializeCoreToolbarItems();
151
152 $this->menuWidth = $this->menuWidthDefault;
153 if (isset($GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW']) && (int) $GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW'] != (int) $this->menuWidth) {
154 $this->menuWidth = (int) $GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW'];
155 }
156
157 $this->executeHook('constructPostProcess');
158 }
159
160 /**
161 * initializes the core toolbar items
162 *
163 * @return void
164 */
165 protected function initializeCoreToolbarItems() {
166
167 $coreToolbarItems = array(
168 'shortcuts' => 'ShortcutMenu',
169 'clearCacheActions' => 'ClearCacheMenu',
170 'liveSearch' => 'LiveSearch'
171 );
172
173 foreach($coreToolbarItems as $toolbarItemName => $toolbarItemClassName) {
174 $toolbarItem = t3lib_div::makeInstance($toolbarItemClassName, $this);
175
176 if(!($toolbarItem instanceof backend_toolbarItem)) {
177 throw new UnexpectedValueException('$toolbarItem "'.$toolbarItemName.'" must implement interface backend_toolbarItem', 1195126772);
178 }
179
180 if($toolbarItem->checkAccess()) {
181 $this->toolbarItems[$toolbarItemName] = $toolbarItem;
182 } else {
183 unset($toolbarItem);
184 }
185 }
186 }
187
188 /**
189 * main function generating the BE scaffolding
190 *
191 * @return void
192 */
193 public function render() {
194 $this->executeHook('renderPreProcess');
195
196 // prepare the scaffolding, at this point extension may still add javascript and css
197 $logo = t3lib_div::makeInstance('TYPO3Logo');
198 $logo->setLogo('gfx/typo3logo_mini.png');
199
200
201
202 // create backend scaffolding
203 $backendScaffolding = '
204 <div id="typo3-top-container" class="x-hide-display">
205 <div id="typo3-logo">'.$logo->render().'</div>
206 <div id="typo3-top" class="typo3-top-toolbar">' .
207 $this->renderToolbar() .
208 '</div>
209 </div>
210
211 ';
212
213 /******************************************************
214 * now put the complete backend document together
215 ******************************************************/
216
217 foreach($this->cssFiles as $cssFileName => $cssFile) {
218 $this->pageRenderer->addCssFile($cssFile);
219
220 // load addditional css files to overwrite existing core styles
221 if(!empty($GLOBALS['TBE_STYLES']['stylesheets'][$cssFileName])) {
222 $this->pageRenderer->addCssFile($GLOBALS['TBE_STYLES']['stylesheets'][$cssFileName]);
223 }
224 }
225
226 if(!empty($this->css)) {
227 $this->pageRenderer->addCssInlineBlock('BackendInlineCSS', $this->css);
228 }
229
230 foreach ($this->jsFiles as $jsFile) {
231 $this->pageRenderer->addJsFile($jsFile);
232 }
233
234
235 $this->generateJavascript();
236 $this->pageRenderer->addJsInlineCode('BackendInlineJavascript', $this->js, FALSE);
237
238 $this->loadResourcesForRegisteredNavigationComponents();
239
240 // add state provider
241 $GLOBALS['TBE_TEMPLATE']->setExtDirectStateProvider();
242 $states = $GLOBALS['BE_USER']->uc['BackendComponents']['States'];
243 //save states in BE_USER->uc
244 $extOnReadyCode = '
245 Ext.state.Manager.setProvider(new TYPO3.state.ExtDirectProvider({
246 key: "BackendComponents.States",
247 autoRead: false
248 }));
249 ';
250 if ($states) {
251 $extOnReadyCode .= 'Ext.state.Manager.getProvider().initState(' . json_encode($states) . ');';
252 }
253 $extOnReadyCode .= '
254 TYPO3.Backend = new TYPO3.Viewport(TYPO3.Viewport.configuration);
255 if (typeof console === "undefined") {
256 console = TYPO3.Backend.DebugConsole;
257 }
258 TYPO3.ContextHelpWindow.init();';
259 $this->pageRenderer->addExtOnReadyCode($extOnReadyCode);
260
261
262 // set document title:
263 $title = ($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']
264 ? $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'].' [TYPO3 '.TYPO3_version.']'
265 : 'TYPO3 '.TYPO3_version
266 );
267
268 $this->content = $backendScaffolding;
269 // Renders the module page
270 $this->content = $GLOBALS['TBE_TEMPLATE']->render(
271 $title,
272 $this->content
273 );
274
275 $hookConfiguration = array('content' => &$this->content);
276 $this->executeHook('renderPostProcess', $hookConfiguration);
277
278 echo $this->content;
279 }
280
281 /**
282 * Loads the css and javascript files of all registered navigation widgets
283 *
284 * @return void
285 */
286 protected function loadResourcesForRegisteredNavigationComponents() {
287 if (!is_array($GLOBALS['TBE_MODULES']['_navigationComponents'])) {
288 return;
289 }
290
291 $loadedComponents = array();
292 foreach ($GLOBALS['TBE_MODULES']['_navigationComponents'] as $module => $info) {
293 if (in_array($info['componentId'], $loadedComponents)) {
294 continue;
295 }
296 $loadedComponents[] = $info['componentId'];
297
298 $component = strtolower(substr($info['componentId'], strrpos($info['componentId'], '-') + 1));
299 $componentDirectory = 'components/' . $component . '/';
300
301 if ($info['isCoreComponent']) {
302 $absoluteComponentPath = PATH_t3lib . 'js/extjs/' . $componentDirectory;
303 $relativeComponentPath = '../' . str_replace(PATH_site, '', $absoluteComponentPath);
304 } else {
305 $absoluteComponentPath = t3lib_extMgm::extPath($info['extKey']) . $componentDirectory;
306 $relativeComponentPath = t3lib_extMgm::extRelPath($info['extKey']) . $componentDirectory;
307 }
308
309 $cssFiles = t3lib_div::getFilesInDir($absoluteComponentPath . 'css/', 'css');
310 if (file_exists($absoluteComponentPath . 'css/loadorder.txt')) {
311 //don't allow inclusion outside directory
312 $loadOrder = str_replace('../', '', t3lib_div::getUrl($absoluteComponentPath . 'css/loadorder.txt'));
313 $cssFilesOrdered = t3lib_div::trimExplode(LF, $loadOrder, TRUE);
314 $cssFiles = array_merge($cssFilesOrdered, $cssFiles);
315 }
316 foreach ($cssFiles as $cssFile) {
317 $this->pageRenderer->addCssFile($relativeComponentPath . 'css/' . $cssFile);
318 }
319
320 $jsFiles = t3lib_div::getFilesInDir($absoluteComponentPath . 'javascript/', 'js');
321 if (file_exists($absoluteComponentPath . 'javascript/loadorder.txt')) {
322 //don't allow inclusion outside directory
323 $loadOrder = str_replace('../', '', t3lib_div::getUrl($absoluteComponentPath . 'javascript/loadorder.txt'));
324 $jsFilesOrdered = t3lib_div::trimExplode(LF, $loadOrder, TRUE);
325 $jsFiles = array_merge($jsFilesOrdered, $jsFiles);
326 }
327
328 foreach ($jsFiles as $jsFile) {
329 $this->pageRenderer->addJsFile($relativeComponentPath . 'javascript/' . $jsFile);
330 }
331 }
332 }
333
334 /**
335 * renders the items in the top toolbar
336 *
337 * @return string top toolbar elements as HTML
338 */
339 protected function renderToolbar() {
340
341 // move search to last position
342 if (array_key_exists('liveSearch', $this->toolbarItems)) {
343 $search = $this->toolbarItems['liveSearch'];
344 unset($this->toolbarItems['liveSearch']);
345 $this->toolbarItems['liveSearch'] = $search;
346 }
347
348 $toolbar = '<ul id="typo3-toolbar">';
349 $toolbar.= '<li>'.$this->getLoggedInUserLabel().'</li>
350 <li><div id="logout-button" class="toolbar-item no-separator">'.$this->moduleMenu->renderLogoutButton().'</div></li>';
351
352 foreach($this->toolbarItems as $toolbarItem) {
353 $menu = $toolbarItem->render();
354 if ($menu) {
355 $additionalAttributes = $toolbarItem->getAdditionalAttributes();
356 $toolbar .= '<li' . $additionalAttributes . '>' .$menu. '</li>';
357 }
358 }
359
360 return $toolbar.'</ul>';
361 }
362
363 /**
364 * Gets the label of the BE user currently logged in
365 *
366 * @return string html code snippet displaying the currently logged in user
367 */
368 protected function getLoggedInUserLabel() {
369 $css = 'toolbar-item no-separator';
370 $icon = t3lib_iconWorks::getSpriteIcon('status-user-' . ($GLOBALS['BE_USER']->isAdmin() ? 'admin' : 'backend'));
371 $realName = $GLOBALS['BE_USER']->user['realName'];
372 $username = $GLOBALS['BE_USER']->user['username'];
373
374 $label = $realName ? $realName : $username;
375 $title = $username;
376
377 // Link to user setup if it's loaded and user has access
378 $link = '';
379 if (t3lib_extMgm::isLoaded('setup') && $GLOBALS['BE_USER']->check('modules', 'user_setup')) {
380 $link = '<a href="#" onclick="top.goToModule(\'user_setup\'); this.blur(); return false;">';
381 }
382
383 // superuser mode
384 if ($GLOBALS['BE_USER']->user['ses_backuserid']) {
385 $css .= ' su-user';
386 $title = $GLOBALS['LANG']->getLL('switchtouser') . ': ' . $username;
387 $label = $GLOBALS['LANG']->getLL('switchtousershort') . ' ' .
388 ($realName ? $realName . ' (' . $username . ')' : $username);
389 }
390
391 return '<div id="username" class="' . $css . '">' . $link . $icon .
392 '<span title="' . htmlspecialchars($title) . '">' . htmlspecialchars($label) . '</span>' .
393 ($link ? '</a>' : '') . '</div>';
394 }
395
396 /**
397 * Returns the file name to the LLL JavaScript, containing the localized labels,
398 * which can be used in JavaScript code.
399 *
400 * @return string File name of the JS file, relative to TYPO3_mainDir
401 */
402 protected function getLocalLangFileName() {
403 $code = $this->generateLocalLang();
404 $filePath = 'typo3temp/locallang-BE-' . sha1($code) . '.js';
405 if (!file_exists(PATH_site . $filePath)) {
406 // writeFileToTypo3tempDir() returns NULL on success (please double-read!)
407 if (t3lib_div::writeFileToTypo3tempDir(PATH_site . $filePath, $code) !== NULL) {
408 throw new RuntimeException('LocalLangFile could not be written to ' . $filePath, 1295193026);
409 }
410 }
411 return '../' . $filePath;
412 }
413
414 /**
415 * Reads labels required in JavaScript code from the localization system and returns them as JSON
416 * array in TYPO3.LLL.
417 *
418 * @return string JavaScript code containing the LLL labels in TYPO3.LLL
419 */
420 protected function generateLocalLang() {
421 $coreLabels = array(
422 'waitTitle' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_logging_in') ,
423 'refresh_login_failed' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_failed'),
424 'refresh_login_failed_message' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_failed_message'),
425 'refresh_login_title' => sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_title'), htmlspecialchars($GLOBALS['BE_USER']->user['username'])),
426 'login_expired' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.login_expired'),
427 'refresh_login_username' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_username'),
428 'refresh_login_password' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_password'),
429 'refresh_login_emptyPassword' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_emptyPassword'),
430 'refresh_login_button' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_button'),
431 'refresh_logout_button' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_logout_button'),
432 'please_wait' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.please_wait'),
433 'loadingIndicator' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:loadingIndicator'),
434 'be_locked' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.be_locked'),
435 'refresh_login_countdown_singular' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_countdown_singular'),
436 'refresh_login_countdown' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_countdown'),
437 'login_about_to_expire' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.login_about_to_expire'),
438 'login_about_to_expire_title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.login_about_to_expire_title'),
439 'refresh_login_refresh_button' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_refresh_button'),
440 'refresh_direct_logout_button' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_direct_logout_button'),
441 'tabs_closeAll' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:tabs.closeAll'),
442 'tabs_closeOther' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:tabs.closeOther'),
443 'tabs_close' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:tabs.close'),
444 'tabs_openInBrowserWindow' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:tabs.openInBrowserWindow'),
445 'csh_tooltip_loading' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:csh_tooltip_loading'),
446 );
447
448 $labels = array(
449 'fileUpload' => array(
450 'windowTitle',
451 'buttonSelectFiles',
452 'buttonCancelAll',
453 'infoComponentMaxFileSize',
454 'infoComponentFileUploadLimit',
455 'infoComponentFileTypeLimit',
456 'infoComponentOverrideFiles',
457 'processRunning',
458 'uploadWait',
459 'uploadStarting',
460 'uploadProgress',
461 'uploadSuccess',
462 'errorQueueLimitExceeded',
463 'errorQueueFileSizeLimit',
464 'errorQueueZeroByteFile',
465 'errorQueueInvalidFiletype',
466 'errorUploadHttp',
467 'errorUploadMissingUrl',
468 'errorUploadIO',
469 'errorUploadSecurityError',
470 'errorUploadLimit',
471 'errorUploadFailed',
472 'errorUploadFileIDNotFound',
473 'errorUploadFileValidation',
474 'errorUploadFileCancelled',
475 'errorUploadStopped',
476 'allErrorMessageTitle',
477 'allErrorMessageText',
478 'allError401',
479 'allError2038',
480 ),
481 'liveSearch' => array(
482 'title',
483 'helpTitle',
484 'emptyText',
485 'loadingText',
486 'listEmptyText',
487 'showAllResults',
488 'helpDescription',
489 'helpDescriptionPages',
490 'helpDescriptionContent',
491 ),
492 'viewPort' => array(
493 'tooltipModuleMenuSplit',
494 'tooltipNavigationContainerSplitDrag',
495 'tooltipDebugPanelSplitDrag',
496
497 ),
498 );
499 $generatedLabels = array();
500 $generatedLabels['core'] = $coreLabels;
501
502 // first loop over all categories (fileUpload, liveSearch, ..)
503 foreach ($labels as $categoryName => $categoryLabels) {
504 // then loop over every single label
505 foreach ($categoryLabels as $label) {
506 // LLL identifier must be called $categoryName_$label, e.g. liveSearch_loadingText
507 $generatedLabels[$categoryName][$label] = $GLOBALS['LANG']->getLL($categoryName . '_' . $label);
508 }
509 }
510
511 // Convert labels/settings back to UTF-8 since json_encode() only works with UTF-8:
512 if ($GLOBALS['LANG']->charSet !== 'utf-8') {
513 $GLOBALS['LANG']->csConvObj->convArray($generatedLabels, $GLOBALS['LANG']->charSet, 'utf-8');
514 }
515
516 return 'TYPO3.LLL = ' . json_encode($generatedLabels) . ';';
517 }
518
519 /**
520 * Generates the JavaScript code for the backend.
521 *
522 * @return void
523 */
524 protected function generateJavascript() {
525
526 $pathTYPO3 = t3lib_div::dirname(t3lib_div::getIndpEnv('SCRIPT_NAME')).'/';
527
528 // If another page module was specified, replace the default Page module with the new one
529 $newPageModule = trim($GLOBALS['BE_USER']->getTSConfigVal('options.overridePageModule'));
530 $pageModule = t3lib_BEfunc::isModuleSetInTBE_MODULES($newPageModule) ? $newPageModule : 'web_layout';
531 if (!$GLOBALS['BE_USER']->check('modules', $pageModule)) {
532 $pageModule = '';
533 }
534
535 $menuFrameName = 'menu';
536 if($GLOBALS['BE_USER']->uc['noMenuMode'] === 'icons') {
537 $menuFrameName = 'topmenuFrame';
538 }
539
540 // determine security level from conf vars and default to super challenged
541 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel']) {
542 $this->loginSecurityLevel = $GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel'];
543 } else {
544 $this->loginSecurityLevel = 'superchallenged';
545 }
546
547 $t3Configuration = array(
548 'siteUrl' => t3lib_div::getIndpEnv('TYPO3_SITE_URL'),
549 'PATH_typo3' => $pathTYPO3,
550 'PATH_typo3_enc' => rawurlencode($pathTYPO3),
551 'username' => htmlspecialchars($GLOBALS['BE_USER']->user['username']),
552 'uniqueID' => t3lib_div::shortMD5(uniqid('')),
553 'securityLevel' => $this->loginSecurityLevel,
554 'TYPO3_mainDir' => TYPO3_mainDir,
555 'pageModule' => $pageModule,
556 'condensedMode' => $GLOBALS['BE_USER']->uc['condensedMode'] ? 1 : 0 ,
557 'inWorkspace' => $GLOBALS['BE_USER']->workspace !== 0 ? 1 : 0,
558 'workspaceFrontendPreviewEnabled' => $GLOBALS['BE_USER']->user['workspace_preview'] ? 1 : 0,
559 'veriCode' => $GLOBALS['BE_USER']->veriCode(),
560 'denyFileTypes' => PHP_EXTENSIONS_DEFAULT,
561 'moduleMenuWidth' => $this->menuWidth - 1,
562 'topBarHeight' => (isset($GLOBALS['TBE_STYLES']['dims']['topFrameH']) ? intval($GLOBALS['TBE_STYLES']['dims']['topFrameH']) : 30),
563 'showRefreshLoginPopup' => isset($GLOBALS['TYPO3_CONF_VARS']['BE']['showRefreshLoginPopup']) ? intval($GLOBALS['TYPO3_CONF_VARS']['BE']['showRefreshLoginPopup']) : FALSE,
564 'listModulePath' => t3lib_extMgm::isLoaded('recordlist') ? t3lib_extMgm::extRelPath('recordlist') . 'mod1/' : '',
565 'debugInWindow' => $GLOBALS['BE_USER']->uc['debugInWindow'] ? 1 : 0,
566 'ContextHelpWindows' => array(
567 'width' => 600,
568 'height' => 400
569 ),
570 'firstWebmountPid' => intval($GLOBALS['WEBMOUNTS'][0]),
571 );
572 if ($GLOBALS['LANG']->charSet !== 'utf-8') {
573 $t3Configuration['username'] = $GLOBALS['LANG']->csConvObj->conv($t3Configuration['username'], $GLOBALS['LANG']->charSet, 'utf-8');
574 }
575
576 $this->js .= '
577 TYPO3.configuration = ' . json_encode($t3Configuration) . ';
578
579 /**
580 * TypoSetup object.
581 */
582 function typoSetup() { //
583 this.PATH_typo3 = TYPO3.configuration.PATH_typo3;
584 this.PATH_typo3_enc = TYPO3.configuration.PATH_typo3_enc;
585 this.username = TYPO3.configuration.username;
586 this.uniqueID = TYPO3.configuration.uniqueID;
587 this.navFrameWidth = 0;
588 this.securityLevel = TYPO3.configuration.securityLevel;
589 this.veriCode = TYPO3.configuration.veriCode;
590 this.denyFileTypes = TYPO3.configuration.denyFileTypes;
591 }
592 var TS = new typoSetup();
593 //backwards compatibility
594 /**
595 * Frameset Module object
596 *
597 * Used in main modules with a frameset for submodules to keep the ID between modules
598 * Typically that is set by something like this in a Web>* sub module:
599 * if (top.fsMod) top.fsMod.recentIds["web"] = "\'.intval($this->id).\'";
600 * if (top.fsMod) top.fsMod.recentIds["file"] = "...(file reference/string)...";
601 */
602 function fsModules() { //
603 this.recentIds=new Array(); // used by frameset modules to track the most recent used id for list frame.
604 this.navFrameHighlightedID=new Array(); // used by navigation frames to track which row id was highlighted last time
605 this.currentMainLoaded="";
606 this.currentBank="0";
607 }
608 var fsMod = new fsModules();
609
610 top.goToModule = function(modName, cMR_flag, addGetVars) {
611 TYPO3.ModuleMenu.App.showModule(modName, addGetVars);
612 }
613 ' . $this->setStartupModule();
614
615 // Check editing of page:
616 $this->handlePageEditing();
617
618 }
619
620 /**
621 * Checking if the "&edit" variable was sent so we can open it for editing the page.
622 * Code based on code from "alt_shortcut.php"
623 *
624 * @return void
625 */
626 protected function handlePageEditing() {
627
628 if(!t3lib_extMgm::isLoaded('cms')) {
629 return;
630 }
631
632 // EDIT page:
633 $editId = preg_replace('/[^[:alnum:]_]/', '', t3lib_div::_GET('edit'));
634 $editRecord = '';
635
636 if($editId) {
637
638 // Looking up the page to edit, checking permissions:
639 $where = ' AND ('.$GLOBALS['BE_USER']->getPagePermsClause(2)
640 .' OR '.$GLOBALS['BE_USER']->getPagePermsClause(16).')';
641
642 if(t3lib_utility_Math::canBeInterpretedAsInteger($editId)) {
643 $editRecord = t3lib_BEfunc::getRecordWSOL('pages', $editId, '*', $where);
644 } else {
645 $records = t3lib_BEfunc::getRecordsByField('pages', 'alias', $editId, $where);
646
647 if(is_array($records)) {
648 $editRecord = reset($records);
649 t3lib_BEfunc::workspaceOL('pages', $editRecord);
650 }
651 }
652
653 // If the page was accessible, then let the user edit it.
654 if(is_array($editRecord) && $GLOBALS['BE_USER']->isInWebMount($editRecord['uid'])) {
655 // Setting JS code to open editing:
656 $this->js .= '
657 // Load page to edit:
658 window.setTimeout("top.loadEditId('.intval($editRecord['uid']).');", 500);
659 ';
660
661 // Checking page edit parameter:
662 if (!$GLOBALS['BE_USER']->getTSConfigVal('options.bookmark_onEditId_dontSetPageTree')) {
663 $bookmarkKeepExpanded = $GLOBALS['BE_USER']->getTSConfigVal('options.bookmark_onEditId_keepExistingExpanded');
664
665 // Expanding page tree:
666 t3lib_BEfunc::openPageTree(intval($editRecord['pid']), !$bookmarkKeepExpanded);
667 }
668 } else {
669 $this->js .= '
670 // Warning about page editing:
671 alert('.$GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->getLL('noEditPage'), $editId)).');
672 ';
673 }
674 }
675 }
676
677 /**
678 * Sets the startup module from either GETvars module and mpdParams or user configuration.
679 *
680 * @return void
681 */
682 protected function setStartupModule() {
683 $startModule = preg_replace('/[^[:alnum:]_]/', '', t3lib_div::_GET('module'));
684
685 if(!$startModule) {
686 if ($GLOBALS['BE_USER']->uc['startModule']) {
687 $startModule = $GLOBALS['BE_USER']->uc['startModule'];
688 } elseif ($GLOBALS['BE_USER']->uc['startInTaskCenter']) {
689 $startModule = 'user_task';
690 }
691 }
692
693 $moduleParameters = t3lib_div::_GET('modParams');
694 if($startModule) {
695 return '
696 // start in module:
697 top.startInModule = [\'' . $startModule . '\', ' . t3lib_div::quoteJSvalue($moduleParameters) . '];
698 ';
699 } else {
700 return '';
701 }
702
703 }
704
705 /**
706 * adds a javascript snippet to the backend
707 *
708 * @param string javascript snippet
709 * @return void
710 */
711 public function addJavascript($javascript) {
712 // TODO do we need more checks?
713 if(!is_string($javascript)) {
714 throw new InvalidArgumentException('parameter $javascript must be of type string', 1195129553);
715 }
716
717 $this->js .= $javascript;
718 }
719
720 /**
721 * adds a javscript file to the backend after it has been checked that it exists
722 *
723 * @param string javascript file reference
724 * @return boolean TRUE if the javascript file was successfully added, FALSE otherwise
725 */
726 public function addJavascriptFile($javascriptFile) {
727 $jsFileAdded = FALSE;
728
729 //TODO add more checks if neccessary
730 if(file_exists(t3lib_div::resolveBackPath(PATH_typo3.$javascriptFile))) {
731 $this->jsFiles[] = $javascriptFile;
732 $jsFileAdded = TRUE;
733 }
734
735 return $jsFileAdded;
736 }
737
738 /**
739 * adds a css snippet to the backend
740 *
741 * @param string css snippet
742 * @return void
743 */
744 public function addCss($css) {
745 if(!is_string($css)) {
746 throw new InvalidArgumentException('parameter $css must be of type string', 1195129642);
747 }
748
749 $this->css .= $css;
750 }
751
752 /**
753 * adds a css file to the backend after it has been checked that it exists
754 *
755 * @param string the css file's name with out the .css ending
756 * @param string css file reference
757 * @return boolean TRUE if the css file was added, FALSE otherwise
758 */
759 public function addCssFile($cssFileName, $cssFile) {
760 $cssFileAdded = FALSE;
761
762 if(empty($this->cssFiles[$cssFileName])) {
763 $this->cssFiles[$cssFileName] = $cssFile;
764 $cssFileAdded = TRUE;
765 }
766
767 return $cssFileAdded;
768 }
769
770 /**
771 * adds an item to the toolbar, the class file for the toolbar item must be loaded at this point
772 *
773 * @param string toolbar item name, f.e. tx_toolbarExtension_coolItem
774 * @param string toolbar item class name, f.e. tx_toolbarExtension_coolItem
775 * @return void
776 */
777 public function addToolbarItem($toolbarItemName, $toolbarItemClassName) {
778 $toolbarItem = t3lib_div::makeInstance($toolbarItemClassName, $this);
779
780 if(!($toolbarItem instanceof backend_toolbarItem)) {
781 throw new UnexpectedValueException('$toolbarItem "'.$toolbarItemName.'" must implement interface backend_toolbarItem', 1195125501);
782 }
783
784 if($toolbarItem->checkAccess()) {
785 $this->toolbarItems[$toolbarItemName] = $toolbarItem;
786 } else {
787 unset($toolbarItem);
788 }
789 }
790
791 /**
792 * Executes defined hooks functions for the given identifier.
793 *
794 * These hook identifiers are valid:
795 * + constructPostProcess
796 * + renderPreProcess
797 * + renderPostProcess
798 *
799 * @param string $identifier Specific hook identifier
800 * @param array $hookConfiguration Additional configuration passed to hook functions
801 * @return void
802 */
803 protected function executeHook($identifier, array $hookConfiguration = array()) {
804 $options =& $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/backend.php'];
805
806 if(isset($options[$identifier]) && is_array($options[$identifier])) {
807 foreach($options[$identifier] as $hookFunction) {
808 t3lib_div::callUserFunction($hookFunction, $hookConfiguration, $this);
809 }
810 }
811 }
812 }
813
814
815 // include XCLASS
816 if(defined('TYPO3_MODE') && $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/backend.php']) {
817 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/backend.php']);
818 }
819
820
821 // document generation
822 $TYPO3backend = t3lib_div::makeInstance('TYPO3backend');
823
824 // include extensions which may add css, javascript or toolbar items
825 if(is_array($GLOBALS['TYPO3_CONF_VARS']['typo3/backend.php']['additionalBackendItems'])) {
826 foreach($GLOBALS['TYPO3_CONF_VARS']['typo3/backend.php']['additionalBackendItems'] as $additionalBackendItem) {
827 include_once($additionalBackendItem);
828 }
829 }
830
831 $TYPO3backend->render();
832
833 ?>