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