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