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