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