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