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