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