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