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