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