[TASK] Use short version ?: in ternary operator (PHP 5.3+)
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Controller / BackendController.php
1 <?php
2 namespace TYPO3\CMS\Backend\Controller;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2007-2013 Ingo Renner <ingo@typo3.org>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the text file GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29
30 use TYPO3\CMS\Backend\Utility\BackendUtility;
31 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
32 use TYPO3\CMS\Core\Utility\GeneralUtility;
33
34 /**
35 * Class for rendering the TYPO3 backend version 4.2+
36 *
37 * @author Ingo Renner <ingo@typo3.org>
38 */
39 class BackendController {
40
41 protected $content;
42
43 protected $css;
44
45 protected $cssFiles;
46
47 protected $js;
48
49 protected $jsFiles;
50
51 protected $jsFilesAfterInline;
52
53 protected $toolbarItems;
54
55 // intentionally private as nobody should modify defaults
56 private $menuWidthDefault = 190;
57
58 protected $menuWidth;
59
60 protected $debug;
61
62 /**
63 * Object for loading backend modules
64 *
65 * @var \TYPO3\CMS\Backend\Module\ModuleLoader
66 */
67 protected $moduleLoader;
68
69 /**
70 * module menu generating object
71 *
72 * @var \TYPO3\CMS\Backend\View\ModuleMenuView
73 */
74 protected $moduleMenu;
75
76 /**
77 * Pagerenderer
78 *
79 * @var \TYPO3\CMS\Core\Page\PageRenderer
80 */
81 protected $pageRenderer;
82
83 /**
84 * Constructor
85 */
86 public function __construct() {
87 // Set debug flag for BE development only
88 $this->debug = intval($GLOBALS['TYPO3_CONF_VARS']['BE']['debug']) === 1;
89 // Initializes the backend modules structure for use later.
90 $this->moduleLoader = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Module\\ModuleLoader');
91 $this->moduleLoader->load($GLOBALS['TBE_MODULES']);
92 $this->moduleMenu = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\View\\ModuleMenuView');
93 $this->pageRenderer = $GLOBALS['TBE_TEMPLATE']->getPageRenderer();
94 $this->pageRenderer->loadScriptaculous('builder,effects,controls,dragdrop');
95 $this->pageRenderer->loadExtJS();
96 $this->pageRenderer->enableExtJSQuickTips();
97 $this->pageRenderer->addJsInlineCode('consoleOverrideWithDebugPanel', '//already done', FALSE);
98 $this->pageRenderer->addExtDirectCode();
99 // Add default BE javascript
100 $this->js = '';
101 $this->jsFiles = array(
102 'common' => 'sysext/backend/Resources/Public/JavaScript/common.js',
103 'locallang' => $this->getLocalLangFileName(),
104 'modernizr' => 'contrib/modernizr/modernizr.min.js',
105 'md5' => 'sysext/backend/Resources/Public/JavaScript/md5.js',
106 'toolbarmanager' => 'sysext/backend/Resources/Public/JavaScript/toolbarmanager.js',
107 'modulemenu' => 'sysext/backend/Resources/Public/JavaScript/modulemenu.js',
108 'iecompatibility' => 'sysext/backend/Resources/Public/JavaScript/iecompatibility.js',
109 'evalfield' => 'sysext/backend/Resources/Public/JavaScript/jsfunc.evalfield.js',
110 'flashmessages' => 'sysext/backend/Resources/Public/JavaScript/flashmessages.js',
111 'tabclosemenu' => 'js/extjs/ux/ext.ux.tabclosemenu.js',
112 'notifications' => 'sysext/backend/Resources/Public/JavaScript/notifications.js',
113 'backend' => 'sysext/backend/Resources/Public/JavaScript/backend.js',
114 'loginrefresh' => 'sysext/backend/Resources/Public/JavaScript/loginrefresh.js',
115 'debugPanel' => 'js/extjs/debugPanel.js',
116 'viewport' => 'js/extjs/viewport.js',
117 'iframepanel' => 'sysext/backend/Resources/Public/JavaScript/iframepanel.js',
118 'backendcontentiframe' => 'js/extjs/backendcontentiframe.js',
119 'modulepanel' => 'js/extjs/modulepanel.js',
120 'viewportConfiguration' => 'js/extjs/viewportConfiguration.js',
121 'util' => 'sysext/backend/Resources/Public/JavaScript/util.js'
122 );
123 if ($this->debug) {
124 unset($this->jsFiles['loginrefresh']);
125 }
126 // Add default BE css
127 $this->css = '';
128 $this->cssFiles = array();
129 $this->toolbarItems = array();
130 $this->initializeCoreToolbarItems();
131 $this->menuWidth = $this->menuWidthDefault;
132 if (isset($GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW']) && (int) $GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW'] != (int) $this->menuWidth) {
133 $this->menuWidth = (int) $GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW'];
134 }
135 $this->executeHook('constructPostProcess');
136 }
137
138 /**
139 * Initializes the core toolbar items
140 *
141 * @return void
142 */
143 protected function initializeCoreToolbarItems() {
144 $coreToolbarItems = array(
145 'shortcuts' => 'TYPO3\\CMS\\Backend\\Toolbar\\ShortcutToolbarItem',
146 'clearCacheActions' => 'TYPO3\\CMS\\Backend\\Toolbar\\ClearCacheToolbarItem',
147 'liveSearch' => '\\TYPO3\\CMS\\Backend\\Toolbar\\LiveSearchToolbarItem'
148 );
149 foreach ($coreToolbarItems as $toolbarItemName => $toolbarItemClassName) {
150 $toolbarItem = GeneralUtility::makeInstance($toolbarItemClassName, $this);
151 if (!$toolbarItem instanceof \TYPO3\CMS\Backend\Toolbar\ToolbarItemHookInterface) {
152 throw new \UnexpectedValueException('$toolbarItem "' . $toolbarItemName . '" must implement interface TYPO3\\CMS\\Backend\\Toolbar\\ToolbarItemHookInterface', 1195126772);
153 }
154 if ($toolbarItem->checkAccess()) {
155 $this->toolbarItems[$toolbarItemName] = $toolbarItem;
156 } else {
157 unset($toolbarItem);
158 }
159 }
160 }
161
162 /**
163 * Main function generating the BE scaffolding
164 *
165 * @return void
166 */
167 public function render() {
168 $this->executeHook('renderPreProcess');
169
170 // Prepare the scaffolding, at this point extension may still add javascript and css
171 $logo = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\View\\LogoView');
172
173 // Create backend scaffolding
174 $backendScaffolding = '
175 <div id="typo3-top-container" class="x-hide-display">
176 <div id="typo3-logo">' . $logo->render() . '</div>
177 <div id="typo3-top" class="typo3-top-toolbar">' . $this->renderToolbar() . '</div>
178 </div>';
179 /******************************************************
180 * Now put the complete backend document together
181 ******************************************************/
182 foreach ($this->cssFiles as $cssFileName => $cssFile) {
183 $this->pageRenderer->addCssFile($cssFile);
184 // Load addditional css files to overwrite existing core styles
185 if (!empty($GLOBALS['TBE_STYLES']['stylesheets'][$cssFileName])) {
186 $this->pageRenderer->addCssFile($GLOBALS['TBE_STYLES']['stylesheets'][$cssFileName]);
187 }
188 }
189 if (!empty($this->css)) {
190 $this->pageRenderer->addCssInlineBlock('BackendInlineCSS', $this->css);
191 }
192 foreach ($this->jsFiles as $jsFile) {
193 $this->pageRenderer->addJsFile($jsFile);
194 }
195 $this->generateJavascript();
196 $this->pageRenderer->addJsInlineCode('BackendInlineJavascript', $this->js, FALSE);
197 $this->loadResourcesForRegisteredNavigationComponents();
198 // Add state provider
199 $GLOBALS['TBE_TEMPLATE']->setExtDirectStateProvider();
200 $states = $GLOBALS['BE_USER']->uc['BackendComponents']['States'];
201 // Save states in BE_USER->uc
202 $extOnReadyCode = '
203 Ext.state.Manager.setProvider(new TYPO3.state.ExtDirectProvider({
204 key: "BackendComponents.States",
205 autoRead: false
206 }));
207 ';
208 if ($states) {
209 $extOnReadyCode .= 'Ext.state.Manager.getProvider().initState(' . json_encode($states) . ');';
210 }
211 $extOnReadyCode .= '
212 TYPO3.Backend = new TYPO3.Viewport(TYPO3.Viewport.configuration);
213 if (typeof console === "undefined") {
214 console = TYPO3.Backend.DebugConsole;
215 }
216 TYPO3.ContextHelpWindow.init();';
217 $this->pageRenderer->addExtOnReadyCode($extOnReadyCode);
218 // Set document title:
219 $title = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] ? $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . ' [TYPO3 CMS ' . TYPO3_version . ']' : 'TYPO3 CMS ' . TYPO3_version;
220 $this->content = $backendScaffolding;
221 // Renders the module page
222 $this->content = $GLOBALS['TBE_TEMPLATE']->render($title, $this->content);
223 $hookConfiguration = array('content' => &$this->content);
224 $this->executeHook('renderPostProcess', $hookConfiguration);
225 echo $this->content;
226 }
227
228 /**
229 * Loads the css and javascript files of all registered navigation widgets
230 *
231 * @return void
232 */
233 protected function loadResourcesForRegisteredNavigationComponents() {
234 if (!is_array($GLOBALS['TBE_MODULES']['_navigationComponents'])) {
235 return;
236 }
237 $loadedComponents = array();
238 foreach ($GLOBALS['TBE_MODULES']['_navigationComponents'] as $module => $info) {
239 if (in_array($info['componentId'], $loadedComponents)) {
240 continue;
241 }
242 $loadedComponents[] = $info['componentId'];
243 $component = strtolower(substr($info['componentId'], strrpos($info['componentId'], '-') + 1));
244 $componentDirectory = 'components/' . $component . '/';
245 if ($info['isCoreComponent']) {
246 $absoluteComponentPath = PATH_site . 'typo3/js/extjs/' . $componentDirectory;
247 $relativeComponentPath = '../' . str_replace(PATH_site, '', $absoluteComponentPath);
248 } else {
249 $absoluteComponentPath = ExtensionManagementUtility::extPath($info['extKey']) . $componentDirectory;
250 $relativeComponentPath = ExtensionManagementUtility::extRelPath($info['extKey']) . $componentDirectory;
251 }
252 $cssFiles = GeneralUtility::getFilesInDir($absoluteComponentPath . 'css/', 'css');
253 if (file_exists($absoluteComponentPath . 'css/loadorder.txt')) {
254 // Don't allow inclusion outside directory
255 $loadOrder = str_replace('../', '', GeneralUtility::getUrl($absoluteComponentPath . 'css/loadorder.txt'));
256 $cssFilesOrdered = GeneralUtility::trimExplode(LF, $loadOrder, TRUE);
257 $cssFiles = array_merge($cssFilesOrdered, $cssFiles);
258 }
259 foreach ($cssFiles as $cssFile) {
260 $this->pageRenderer->addCssFile($relativeComponentPath . 'css/' . $cssFile);
261 }
262 $jsFiles = GeneralUtility::getFilesInDir($absoluteComponentPath . 'javascript/', 'js');
263 if (file_exists($absoluteComponentPath . 'javascript/loadorder.txt')) {
264 // Don't allow inclusion outside directory
265 $loadOrder = str_replace('../', '', GeneralUtility::getUrl($absoluteComponentPath . 'javascript/loadorder.txt'));
266 $jsFilesOrdered = GeneralUtility::trimExplode(LF, $loadOrder, TRUE);
267 $jsFiles = array_merge($jsFilesOrdered, $jsFiles);
268 }
269 foreach ($jsFiles as $jsFile) {
270 $this->pageRenderer->addJsFile($relativeComponentPath . 'javascript/' . $jsFile);
271 }
272 }
273 }
274
275 /**
276 * Renders the items in the top toolbar
277 *
278 * @return string top toolbar elements as HTML
279 */
280 protected function renderToolbar() {
281 // Move search to last position
282 if (array_key_exists('liveSearch', $this->toolbarItems)) {
283 $search = $this->toolbarItems['liveSearch'];
284 unset($this->toolbarItems['liveSearch']);
285 $this->toolbarItems['liveSearch'] = $search;
286 }
287 $toolbar = '<ul id="typo3-toolbar">';
288 $toolbar .= '<li>' . $this->getLoggedInUserLabel() . '</li>';
289 $toolbar .= '<li class="separator"><div id="logout-button" class="toolbar-item no-separator">' . $this->moduleMenu->renderLogoutButton() . '</div></li>';
290 $i = 0;
291 foreach ($this->toolbarItems as $key => $toolbarItem) {
292 $i++;
293 $menu = $toolbarItem->render();
294 if ($menu) {
295 $additionalAttributes = $toolbarItem->getAdditionalAttributes();
296 if (sizeof($this->toolbarItems) > 1 && $i == sizeof($this->toolbarItems) - 1) {
297 if (strpos($additionalAttributes, 'class="')) {
298 str_replace('class="', 'class="separator ', $additionalAttributes);
299 } else {
300 $additionalAttributes .= 'class="separator"';
301 }
302 }
303 $toolbar .= '<li ' . $additionalAttributes . '>' . $menu . '</li>';
304 }
305 }
306 return $toolbar . '</ul>';
307 }
308
309 /**
310 * Gets the label of the BE user currently logged in
311 *
312 * @return string Html code snippet displaying the currently logged in user
313 */
314 protected function getLoggedInUserLabel() {
315 $css = 'toolbar-item';
316 $icon = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('status-user-' . ($GLOBALS['BE_USER']->isAdmin() ? 'admin' : 'backend'));
317 $realName = $GLOBALS['BE_USER']->user['realName'];
318 $username = $GLOBALS['BE_USER']->user['username'];
319 $label = $realName ?: $username;
320 $title = $username;
321 // Link to user setup if it's loaded and user has access
322 $link = '';
323 if (ExtensionManagementUtility::isLoaded('setup') && $GLOBALS['BE_USER']->check('modules', 'user_setup')) {
324 $link = '<a href="#" onclick="top.goToModule(\'user_setup\'); this.blur(); return false;">';
325 }
326 // Superuser mode
327 if ($GLOBALS['BE_USER']->user['ses_backuserid']) {
328 $css .= ' su-user';
329 $title = $GLOBALS['LANG']->getLL('switchtouser') . ': ' . $username;
330 $label = $GLOBALS['LANG']->getLL('switchtousershort') . ' ' . ($realName ? $realName . ' (' . $username . ')' : $username);
331 }
332 return '<div id="username" class="' . $css . '">' . $link . $icon . '<span title="' . htmlspecialchars($title) . '">' . htmlspecialchars($label) . '</span>' . ($link ? '</a>' : '') . '</div>';
333 }
334
335 /**
336 * Returns the file name to the LLL JavaScript, containing the localized labels,
337 * which can be used in JavaScript code.
338 *
339 * @return string File name of the JS file, relative to TYPO3_mainDir
340 */
341 protected function getLocalLangFileName() {
342 $code = $this->generateLocalLang();
343 $filePath = 'typo3temp/locallang-BE-' . sha1($code) . '.js';
344 if (!file_exists((PATH_site . $filePath))) {
345 // writeFileToTypo3tempDir() returns NULL on success (please double-read!)
346 if (GeneralUtility::writeFileToTypo3tempDir(PATH_site . $filePath, $code) !== NULL) {
347 throw new \RuntimeException('LocalLangFile could not be written to ' . $filePath, 1295193026);
348 }
349 }
350 return '../' . $filePath;
351 }
352
353 /**
354 * Reads labels required in JavaScript code from the localization system and returns them as JSON
355 * array in TYPO3.LLL.
356 *
357 * @return string JavaScript code containing the LLL labels in TYPO3.LLL
358 */
359 protected function generateLocalLang() {
360 $coreLabels = array(
361 'waitTitle' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.refresh_login_logging_in'),
362 'refresh_login_failed' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.refresh_login_failed'),
363 'refresh_login_failed_message' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.refresh_login_failed_message'),
364 'refresh_login_title' => sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.refresh_login_title'), htmlspecialchars($GLOBALS['BE_USER']->user['username'])),
365 'login_expired' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.login_expired'),
366 'refresh_login_username' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.refresh_login_username'),
367 'refresh_login_password' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.refresh_login_password'),
368 'refresh_login_emptyPassword' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.refresh_login_emptyPassword'),
369 'refresh_login_button' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.refresh_login_button'),
370 'refresh_logout_button' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.refresh_logout_button'),
371 'please_wait' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.please_wait'),
372 'loadingIndicator' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:loadingIndicator'),
373 'be_locked' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.be_locked'),
374 'refresh_login_countdown_singular' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.refresh_login_countdown_singular'),
375 'refresh_login_countdown' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.refresh_login_countdown'),
376 'login_about_to_expire' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.login_about_to_expire'),
377 'login_about_to_expire_title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.login_about_to_expire_title'),
378 'refresh_login_refresh_button' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.refresh_login_refresh_button'),
379 'refresh_direct_logout_button' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:mess.refresh_direct_logout_button'),
380 'tabs_closeAll' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:tabs.closeAll'),
381 'tabs_closeOther' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:tabs.closeOther'),
382 'tabs_close' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:tabs.close'),
383 'tabs_openInBrowserWindow' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:tabs.openInBrowserWindow'),
384 'csh_tooltip_loading' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:csh_tooltip_loading')
385 );
386 $labels = array(
387 'fileUpload' => array(
388 'windowTitle',
389 'buttonSelectFiles',
390 'buttonCancelAll',
391 'infoComponentMaxFileSize',
392 'infoComponentFileUploadLimit',
393 'infoComponentFileTypeLimit',
394 'infoComponentOverrideFiles',
395 'processRunning',
396 'uploadWait',
397 'uploadStarting',
398 'uploadProgress',
399 'uploadSuccess',
400 'errorQueueLimitExceeded',
401 'errorQueueFileSizeLimit',
402 'errorQueueZeroByteFile',
403 'errorQueueInvalidFiletype',
404 'errorUploadHttp',
405 'errorUploadMissingUrl',
406 'errorUploadIO',
407 'errorUploadSecurityError',
408 'errorUploadLimit',
409 'errorUploadFailed',
410 'errorUploadFileIDNotFound',
411 'errorUploadFileValidation',
412 'errorUploadFileCancelled',
413 'errorUploadStopped',
414 'allErrorMessageTitle',
415 'allErrorMessageText',
416 'allError401',
417 'allError2038'
418 ),
419 'liveSearch' => array(
420 'title',
421 'helpTitle',
422 'emptyText',
423 'loadingText',
424 'listEmptyText',
425 'showAllResults',
426 'helpDescription',
427 'helpDescriptionPages',
428 'helpDescriptionContent'
429 ),
430 'viewPort' => array(
431 'tooltipModuleMenuSplit',
432 'tooltipNavigationContainerSplitDrag',
433 'tooltipDebugPanelSplitDrag'
434 )
435 );
436 $generatedLabels = array();
437 $generatedLabels['core'] = $coreLabels;
438 // First loop over all categories (fileUpload, liveSearch, ..)
439 foreach ($labels as $categoryName => $categoryLabels) {
440 // Then loop over every single label
441 foreach ($categoryLabels as $label) {
442 // LLL identifier must be called $categoryName_$label, e.g. liveSearch_loadingText
443 $generatedLabels[$categoryName][$label] = $GLOBALS['LANG']->getLL($categoryName . '_' . $label);
444 }
445 }
446 return 'TYPO3.LLL = ' . json_encode($generatedLabels) . ';';
447 }
448
449 /**
450 * Generates the JavaScript code for the backend.
451 *
452 * @return void
453 */
454 protected function generateJavascript() {
455 $pathTYPO3 = GeneralUtility::dirname(GeneralUtility::getIndpEnv('SCRIPT_NAME')) . '/';
456 // If another page module was specified, replace the default Page module with the new one
457 $newPageModule = trim($GLOBALS['BE_USER']->getTSConfigVal('options.overridePageModule'));
458 $pageModule = BackendUtility::isModuleSetInTBE_MODULES($newPageModule) ? $newPageModule : 'web_layout';
459 if (!$GLOBALS['BE_USER']->check('modules', $pageModule)) {
460 $pageModule = '';
461 }
462 $menuFrameName = 'menu';
463 if ($GLOBALS['BE_USER']->uc['noMenuMode'] === 'icons') {
464 $menuFrameName = 'topmenuFrame';
465 }
466 // Determine security level from conf vars and default to super challenged
467 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel']) {
468 $this->loginSecurityLevel = $GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel'];
469 } else {
470 $this->loginSecurityLevel = 'superchallenged';
471 }
472 $t3Configuration = array(
473 'siteUrl' => GeneralUtility::getIndpEnv('TYPO3_SITE_URL'),
474 'PATH_typo3' => $pathTYPO3,
475 'PATH_typo3_enc' => rawurlencode($pathTYPO3),
476 'username' => htmlspecialchars($GLOBALS['BE_USER']->user['username']),
477 'uniqueID' => GeneralUtility::shortMD5(uniqid('')),
478 'securityLevel' => $this->loginSecurityLevel,
479 'TYPO3_mainDir' => TYPO3_mainDir,
480 'pageModule' => $pageModule,
481 'condensedMode' => $GLOBALS['BE_USER']->uc['condensedMode'] ? 1 : 0,
482 'inWorkspace' => $GLOBALS['BE_USER']->workspace !== 0 ? 1 : 0,
483 'workspaceFrontendPreviewEnabled' => $GLOBALS['BE_USER']->user['workspace_preview'] ? 1 : 0,
484 'veriCode' => $GLOBALS['BE_USER']->veriCode(),
485 'denyFileTypes' => PHP_EXTENSIONS_DEFAULT,
486 'moduleMenuWidth' => $this->menuWidth - 1,
487 'topBarHeight' => isset($GLOBALS['TBE_STYLES']['dims']['topFrameH']) ? intval($GLOBALS['TBE_STYLES']['dims']['topFrameH']) : 30,
488 'showRefreshLoginPopup' => isset($GLOBALS['TYPO3_CONF_VARS']['BE']['showRefreshLoginPopup']) ? intval($GLOBALS['TYPO3_CONF_VARS']['BE']['showRefreshLoginPopup']) : FALSE,
489 'listModulePath' => ExtensionManagementUtility::isLoaded('recordlist') ? ExtensionManagementUtility::extRelPath('recordlist') . 'mod1/' : '',
490 'debugInWindow' => $GLOBALS['BE_USER']->uc['debugInWindow'] ? 1 : 0,
491 'ContextHelpWindows' => array(
492 'width' => 600,
493 'height' => 400
494 ),
495 );
496 $this->js .= '
497 TYPO3.configuration = ' . json_encode($t3Configuration) . ';
498
499 /**
500 * TypoSetup object.
501 */
502 function typoSetup() { //
503 this.PATH_typo3 = TYPO3.configuration.PATH_typo3;
504 this.PATH_typo3_enc = TYPO3.configuration.PATH_typo3_enc;
505 this.username = TYPO3.configuration.username;
506 this.uniqueID = TYPO3.configuration.uniqueID;
507 this.navFrameWidth = 0;
508 this.securityLevel = TYPO3.configuration.securityLevel;
509 this.veriCode = TYPO3.configuration.veriCode;
510 this.denyFileTypes = TYPO3.configuration.denyFileTypes;
511 }
512 var TS = new typoSetup();
513 //backwards compatibility
514 /**
515 * Frameset Module object
516 *
517 * Used in main modules with a frameset for submodules to keep the ID between modules
518 * Typically that is set by something like this in a Web>* sub module:
519 * if (top.fsMod) top.fsMod.recentIds["web"] = "\'.intval($this->id).\'";
520 * if (top.fsMod) top.fsMod.recentIds["file"] = "...(file reference/string)...";
521 */
522 function fsModules() { //
523 this.recentIds=new Array(); // used by frameset modules to track the most recent used id for list frame.
524 this.navFrameHighlightedID=new Array(); // used by navigation frames to track which row id was highlighted last time
525 this.currentMainLoaded="";
526 this.currentBank="0";
527 }
528 var fsMod = new fsModules();
529
530 top.goToModule = function(modName, cMR_flag, addGetVars) {
531 TYPO3.ModuleMenu.App.showModule(modName, addGetVars);
532 }
533 ' . $this->setStartupModule();
534 // Check editing of page:
535 $this->handlePageEditing();
536 }
537
538 /**
539 * Checking if the "&edit" variable was sent so we can open it for editing the page.
540 * Code based on code from "alt_shortcut.php"
541 *
542 * @return void
543 */
544 protected function handlePageEditing() {
545 if (!ExtensionManagementUtility::isLoaded('cms')) {
546 return;
547 }
548 // EDIT page:
549 $editId = preg_replace('/[^[:alnum:]_]/', '', GeneralUtility::_GET('edit'));
550 $editRecord = '';
551 if ($editId) {
552 // Looking up the page to edit, checking permissions:
553 $where = ' AND (' . $GLOBALS['BE_USER']->getPagePermsClause(2) . ' OR ' . $GLOBALS['BE_USER']->getPagePermsClause(16) . ')';
554 if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($editId)) {
555 $editRecord = BackendUtility::getRecordWSOL('pages', $editId, '*', $where);
556 } else {
557 $records = BackendUtility::getRecordsByField('pages', 'alias', $editId, $where);
558 if (is_array($records)) {
559 $editRecord = reset($records);
560 BackendUtility::workspaceOL('pages', $editRecord);
561 }
562 }
563 // If the page was accessible, then let the user edit it.
564 if (is_array($editRecord) && $GLOBALS['BE_USER']->isInWebMount($editRecord['uid'])) {
565 // Setting JS code to open editing:
566 $this->js .= '
567 // Load page to edit:
568 window.setTimeout("top.loadEditId(' . intval($editRecord['uid']) . ');", 500);
569 ';
570 // Checking page edit parameter:
571 if (!$GLOBALS['BE_USER']->getTSConfigVal('options.bookmark_onEditId_dontSetPageTree')) {
572 $bookmarkKeepExpanded = $GLOBALS['BE_USER']->getTSConfigVal('options.bookmark_onEditId_keepExistingExpanded');
573 // Expanding page tree:
574 BackendUtility::openPageTree(intval($editRecord['pid']), !$bookmarkKeepExpanded);
575 }
576 } else {
577 $this->js .= '
578 // Warning about page editing:
579 alert(' . $GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->getLL('noEditPage'), $editId)) . ');
580 ';
581 }
582 }
583 }
584
585 /**
586 * Sets the startup module from either GETvars module and mpdParams or user configuration.
587 *
588 * @return void
589 */
590 protected function setStartupModule() {
591 $startModule = preg_replace('/[^[:alnum:]_]/', '', GeneralUtility::_GET('module'));
592 if (!$startModule) {
593 if ($GLOBALS['BE_USER']->uc['startModule']) {
594 $startModule = $GLOBALS['BE_USER']->uc['startModule'];
595 } elseif ($GLOBALS['BE_USER']->uc['startInTaskCenter']) {
596 $startModule = 'user_task';
597 }
598 }
599 $moduleParameters = GeneralUtility::_GET('modParams');
600 if ($startModule) {
601 return '
602 // start in module:
603 top.startInModule = [\'' . $startModule . '\', ' . GeneralUtility::quoteJSvalue($moduleParameters) . '];
604 ';
605 } else {
606 return '';
607 }
608 }
609
610 /**
611 * Sdds a javascript snippet to the backend
612 *
613 * @param string $javascript Javascript snippet
614 * @return void
615 */
616 public function addJavascript($javascript) {
617 // TODO do we need more checks?
618 if (!is_string($javascript)) {
619 throw new \InvalidArgumentException('parameter $javascript must be of type string', 1195129553);
620 }
621 $this->js .= $javascript;
622 }
623
624 /**
625 * Adds a javscript file to the backend after it has been checked that it exists
626 *
627 * @param string $javascriptFile Javascript file reference
628 * @return boolean TRUE if the javascript file was successfully added, FALSE otherwise
629 */
630 public function addJavascriptFile($javascriptFile) {
631 $jsFileAdded = FALSE;
632 //TODO add more checks if neccessary
633 if (file_exists(GeneralUtility::resolveBackPath(PATH_typo3 . $javascriptFile))) {
634 $this->jsFiles[] = $javascriptFile;
635 $jsFileAdded = TRUE;
636 }
637 return $jsFileAdded;
638 }
639
640 /**
641 * Adds a css snippet to the backend
642 *
643 * @param string $css Css snippet
644 * @return void
645 */
646 public function addCss($css) {
647 if (!is_string($css)) {
648 throw new \InvalidArgumentException('parameter $css must be of type string', 1195129642);
649 }
650 $this->css .= $css;
651 }
652
653 /**
654 * Adds a css file to the backend after it has been checked that it exists
655 *
656 * @param string $cssFileName The css file's name with out the .css ending
657 * @param string $cssFile Css file reference
658 * @return boolean TRUE if the css file was added, FALSE otherwise
659 */
660 public function addCssFile($cssFileName, $cssFile) {
661 $cssFileAdded = FALSE;
662 if (empty($this->cssFiles[$cssFileName])) {
663 $this->cssFiles[$cssFileName] = $cssFile;
664 $cssFileAdded = TRUE;
665 }
666 return $cssFileAdded;
667 }
668
669 /**
670 * Adds an item to the toolbar, the class file for the toolbar item must be loaded at this point
671 *
672 * @param string $toolbarItemName Toolbar item name, f.e. tx_toolbarExtension_coolItem
673 * @param string $toolbarItemClassName Toolbar item class name, f.e. tx_toolbarExtension_coolItem
674 * @return void
675 */
676 public function addToolbarItem($toolbarItemName, $toolbarItemClassName) {
677 $toolbarItem = GeneralUtility::makeInstance($toolbarItemClassName, $this);
678 if (!$toolbarItem instanceof \TYPO3\CMS\Backend\Toolbar\ToolbarItemHookInterface) {
679 throw new \UnexpectedValueException('$toolbarItem "' . $toolbarItemName . '" must implement interface TYPO3\\CMS\\Backend\\Toolbar\\ToolbarItemHookInterface', 1195125501);
680 }
681 if ($toolbarItem->checkAccess()) {
682 $this->toolbarItems[$toolbarItemName] = $toolbarItem;
683 } else {
684 unset($toolbarItem);
685 }
686 }
687
688 /**
689 * Executes defined hooks functions for the given identifier.
690 *
691 * These hook identifiers are valid:
692 * + constructPostProcess
693 * + renderPreProcess
694 * + renderPostProcess
695 *
696 * @param string $identifier Specific hook identifier
697 * @param array $hookConfiguration Additional configuration passed to hook functions
698 * @return void
699 */
700 protected function executeHook($identifier, array $hookConfiguration = array()) {
701 $options = &$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/backend.php'];
702 if (isset($options[$identifier]) && is_array($options[$identifier])) {
703 foreach ($options[$identifier] as $hookFunction) {
704 GeneralUtility::callUserFunction($hookFunction, $hookConfiguration, $this);
705 }
706 }
707 }
708
709 }