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