Added feature #16408: Support for Custom Navigation Components (Thanks to Stefan...
[Packages/TYPO3.CMS.git] / typo3 / backend.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2007-2010 Ingo Renner <ingo@typo3.org>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27
28 require_once('init.php');
29 require_once('template.php');
30 require_once('interfaces/interface.backend_toolbaritem.php');
31
32 require('classes/class.typo3logo.php');
33 require('classes/class.modulemenu.php');
34 require_once('classes/class.donatewindow.php');
35
36 // core toolbar items
37 require('classes/class.clearcachemenu.php');
38 require('classes/class.shortcutmenu.php');
39 require('classes/class.backendsearchmenu.php');
40
41 require_once('class.alt_menu_functions.inc');
42 $GLOBALS['LANG']->includeLLFile('EXT:lang/locallang_misc.xml');
43
44
45 /**
46 * Class for rendering the TYPO3 backend version 4.2+
47 *
48 * @author Ingo Renner <ingo@typo3.org>
49 * @package TYPO3
50 * @subpackage core
51 */
52 class TYPO3backend {
53
54 protected $content;
55 protected $css;
56 protected $cssFiles;
57 protected $js;
58 protected $jsFiles;
59 protected $jsFilesAfterInline;
60 protected $toolbarItems;
61 private $menuWidthDefault = 190; // intentionally private as nobody should modify defaults
62 protected $menuWidth;
63 protected $debug;
64
65 /**
66 * Object for loading backend modules
67 *
68 * @var t3lib_loadModules
69 */
70 protected $moduleLoader;
71
72 /**
73 * module menu generating object
74 *
75 * @var ModuleMenu
76 */
77 protected $moduleMenu;
78
79 /**
80 * Pagerenderer
81 *
82 * @var t3lib_PageRenderer
83 */
84 protected $pageRenderer;
85
86 /**
87 * constructor
88 *
89 * @return void
90 */
91 public function __construct() {
92 // set debug flag for BE development only
93 $this->debug = intval($GLOBALS['TYPO3_CONF_VARS']['BE']['debug']) === 1;
94
95 // Initializes the backend modules structure for use later.
96 $this->moduleLoader = t3lib_div::makeInstance('t3lib_loadModules');
97 $this->moduleLoader->load($GLOBALS['TBE_MODULES']);
98
99 $this->moduleMenu = t3lib_div::makeInstance('ModuleMenu');
100
101 $this->pageRenderer = $GLOBALS['TBE_TEMPLATE']->getPageRenderer();
102 $this->pageRenderer->loadScriptaculous('builder,effects,controls,dragdrop');
103 $this->pageRenderer->loadExtJS();
104
105 $this->pageRenderer->addExtOnReadyCode(
106 'TYPO3.Backend = new TYPO3.Viewport(TYPO3.Viewport.configuration);
107 if (typeof console === "undefined") {
108 console = TYPO3.Backend.DebugConsole;
109 }
110 TYPO3.ContextHelpWindow.init();',
111 TRUE
112 );
113 $this->pageRenderer->addJsInlineCode(
114 'consoleOverrideWithDebugPanel',
115 '//already done'
116 );
117 $this->pageRenderer->addExtDirectCode();
118
119 // add default BE javascript
120 $this->js = '';
121 $this->jsFiles = array(
122 'modernizr' => 'contrib/modernizr/modernizr.min.js',
123 'swfupload' => 'contrib/swfupload/swfupload.js',
124 'swfupload.swfobject' => 'contrib/swfupload/plugins/swfupload.swfobject.js',
125 'swfupload.cookies' => 'contrib/swfupload/plugins/swfupload.cookies.js',
126 'swfupload.queue' => 'contrib/swfupload/plugins/swfupload.queue.js',
127 'md5' => 'md5.js',
128 'common' => 'js/common.js',
129 'toolbarmanager' => 'js/toolbarmanager.js',
130 'modulemenu' => 'js/modulemenu.js',
131 'iecompatibility' => 'js/iecompatibility.js',
132 'flashupload' => 'js/flashupload.js',
133 'evalfield' => '../t3lib/jsfunc.evalfield.js',
134 'flashmessages' => '../t3lib/js/extjs/ux/flashmessages.js',
135 'tabclosemenu' => '../t3lib/js/extjs/ux/ext.ux.tabclosemenu.js',
136 'notifications' => '../t3lib/js/extjs/notifications.js',
137 'backend' => 'js/backend.js',
138 'loginrefresh' => 'js/loginrefresh.js',
139 'debugPanel' => 'js/extjs/debugPanel.js',
140 'viewport' => 'js/extjs/viewport.js',
141 'iframepanel' => 'js/extjs/iframepanel.js',
142 'viewportConfiguration' => 'js/extjs/viewportConfiguration.js',
143 );
144
145 if ($this->debug) {
146 unset($this->jsFiles['loginrefresh']);
147 }
148
149 // add default BE css
150 $this->css = '';
151 $this->cssFiles = array();
152
153 $this->toolbarItems = array();
154 $this->initializeCoreToolbarItems();
155
156 $this->menuWidth = $this->menuWidthDefault;
157 if (isset($GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW']) && (int) $GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW'] != (int) $this->menuWidth) {
158 $this->menuWidth = (int) $GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW'];
159 }
160
161 $this->executeHook('constructPostProcess');
162 }
163
164 /**
165 * initializes the core toolbar items
166 *
167 * @return void
168 */
169 protected function initializeCoreToolbarItems() {
170
171 $coreToolbarItems = array(
172 'shortcuts' => 'ShortcutMenu',
173 'clearCacheActions' => 'ClearCacheMenu',
174 'backendSearch' => 'BackendSearchMenu'
175 );
176
177 foreach($coreToolbarItems as $toolbarItemName => $toolbarItemClassName) {
178 $toolbarItem = t3lib_div::makeInstance($toolbarItemClassName, $this);
179
180 if(!($toolbarItem instanceof backend_toolbarItem)) {
181 throw new UnexpectedValueException('$toolbarItem "'.$toolbarItemName.'" must implement interface backend_toolbarItem', 1195126772);
182 }
183
184 if($toolbarItem->checkAccess()) {
185 $this->toolbarItems[$toolbarItemName] = $toolbarItem;
186 } else {
187 unset($toolbarItem);
188 }
189 }
190 }
191
192 /**
193 * main function generating the BE scaffolding
194 *
195 * @return void
196 */
197 public function render() {
198 $this->executeHook('renderPreProcess');
199
200 if (t3lib_div::makeInstance('DonateWindow')->isDonateWindowAllowed()) {
201 $this->pageRenderer->addJsFile('js/donate.js');
202 }
203
204 // prepare the scaffolding, at this point extension may still add javascript and css
205 $logo = t3lib_div::makeInstance('TYPO3Logo');
206 $logo->setLogo('gfx/typo3logo_mini.png');
207
208
209
210 // create backend scaffolding
211 $backendScaffolding = '
212 <div id="typo3-top-container" class="x-hide-display">
213 <div id="typo3-logo">'.$logo->render().'</div>
214 <div id="typo3-top" class="typo3-top-toolbar">' .
215 $this->renderToolbar() .
216 '</div>
217 </div>
218
219 ';
220
221 /******************************************************
222 * now put the complete backend document together
223 ******************************************************/
224
225 foreach($this->cssFiles as $cssFileName => $cssFile) {
226 $this->pageRenderer->addCssFile($cssFile);
227
228 // load addditional css files to overwrite existing core styles
229 if(!empty($GLOBALS['TBE_STYLES']['stylesheets'][$cssFileName])) {
230 $this->pageRenderer->addCssFile($GLOBALS['TBE_STYLES']['stylesheets'][$cssFileName]);
231 }
232 }
233
234 if(!empty($this->css)) {
235 $this->pageRenderer->addCssInlineBlock('BackendInlineCSS', $this->css);
236 }
237
238 foreach ($this->jsFiles as $jsFile) {
239 $this->pageRenderer->addJsFile($jsFile);
240 }
241
242 // Those lines can be removed once we have at least one official ExtDirect router within the backend.
243 $hasExtDirectRouter = FALSE;
244 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect']) && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect'])) {
245 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect'] as $key => $value) {
246 if (strpos($key, 'TYPO3.Ajax.ExtDirect') !== FALSE) {
247 $hasExtDirectRouter = TRUE;
248 break;
249 }
250 }
251 }
252 if ($hasExtDirectRouter) {
253 $this->pageRenderer->addJsFile('ajax.php?ajaxID=ExtDirect::getAPI&namespace=TYPO3.Ajax.ExtDirect', NULL, FALSE);
254 }
255
256 $this->generateJavascript();
257 $this->pageRenderer->addJsInlineCode('BackendInlineJavascript', $this->js);
258
259 $this->loadResourcesForRegisteredNavigationComponents();
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 $loadedComponents = array();
287 foreach ($GLOBALS['TBE_MODULES']['_navigationComponents'] as $module => $info) {
288 if (in_array($info['componentId'], $loadedComponents)) {
289 continue;
290 }
291 $loadedComponents[] = $info['componentId'];
292
293 $component = strtolower(substr($info['componentId'], strrpos($info['componentId'], '-') + 1));
294 $componentDirectory = 'components/' . $component . '/';
295 $absoluteComponentPath = t3lib_extMgm::extPath($info['extKey']) . $componentDirectory;
296 $relativeComponentPath = t3lib_extMgm::extRelPath($info['extKey']) . $componentDirectory;
297
298 $cssFiles = t3lib_div::getFilesInDir($absoluteComponentPath . 'css/');
299 foreach ($cssFiles as $cssFile) {
300 $this->pageRenderer->addCssFile($relativeComponentPath . 'css/' . $cssFile);
301 }
302
303 $jsFiles = t3lib_div::getFilesInDir($absoluteComponentPath . 'javascript/');
304 foreach ($jsFiles as $jsFile) {
305 $this->pageRenderer->addJsFile($relativeComponentPath . 'javascript/' . $jsFile);
306 }
307
308 if (is_array($info['extDirectNamespaces']) && count($info['extDirectNamespaces'])) {
309 foreach ($info['extDirectNamespaces'] as $namespace) {
310 $this->pageRenderer->addJsFile(
311 'ajax.php?ajaxID=ExtDirect::getAPI&namespace=' . $namespace,
312 NULL,
313 FALSE
314 );
315 }
316 }
317 }
318 }
319
320 /**
321 * renders the items in the top toolbar
322 *
323 * @return string top toolbar elements as HTML
324 */
325 protected function renderToolbar() {
326
327 // move search to last position
328 $search = $this->toolbarItems['backendSearch'];
329 unset($this->toolbarItems['backendSearch']);
330 $this->toolbarItems['backendSearch'] = $search;
331
332 $toolbar = '<ul id="typo3-toolbar">';
333 $toolbar.= '<li>'.$this->getLoggedInUserLabel().'</li>
334 <li><div id="logout-button" class="toolbar-item no-separator">'.$this->moduleMenu->renderLogoutButton().'</div></li>';
335
336 foreach($this->toolbarItems as $toolbarItem) {
337 $menu = $toolbarItem->render();
338 if ($menu) {
339 $additionalAttributes = $toolbarItem->getAdditionalAttributes();
340 $toolbar .= '<li' . $additionalAttributes . '>' .$menu. '</li>';
341 }
342 }
343
344 return $toolbar.'</ul>';
345 }
346
347 /**
348 * Gets the label of the BE user currently logged in
349 *
350 * @return string html code snippet displaying the currently logged in user
351 */
352 protected function getLoggedInUserLabel() {
353 global $BE_USER, $BACK_PATH;
354
355 $icon = t3lib_iconWorks::getSpriteIcon('status-user-'. ($BE_USER->isAdmin() ? 'admin' : 'backend'));
356
357 $label = $GLOBALS['BE_USER']->user['realName'] ?
358 $BE_USER->user['realName'] . ' (' . $BE_USER->user['username'] . ')' :
359 $BE_USER->user['username'];
360
361 // Link to user setup if it's loaded and user has access
362 $link = '';
363 if (t3lib_extMgm::isLoaded('setup') && $BE_USER->check('modules','user_setup')) {
364 $link = '<a href="#" onclick="top.goToModule(\'user_setup\');this.blur();return false;">';
365 }
366
367 $username = '">'.$link.$icon.'<span>'.htmlspecialchars($label).'</span>'.($link?'</a>':'');
368
369 // superuser mode
370 if($BE_USER->user['ses_backuserid']) {
371 $username = ' su-user">'.$icon.
372 '<span title="' . $GLOBALS['LANG']->getLL('switchtouser') . '">' .
373 $GLOBALS['LANG']->getLL('switchtousershort') . ' </span>' .
374 '<span>' . htmlspecialchars($label) . '</span>';
375 }
376
377 return '<div id="username" class="toolbar-item no-separator'.$username.'</div>';
378 }
379
380 /**
381 * Generates the JavaScript code for the backend.
382 *
383 * @return void
384 */
385 protected function generateJavascript() {
386
387 $pathTYPO3 = t3lib_div::dirname(t3lib_div::getIndpEnv('SCRIPT_NAME')).'/';
388
389 // If another page module was specified, replace the default Page module with the new one
390 $newPageModule = trim($GLOBALS['BE_USER']->getTSConfigVal('options.overridePageModule'));
391 $pageModule = t3lib_BEfunc::isModuleSetInTBE_MODULES($newPageModule) ? $newPageModule : 'web_layout';
392 if (!$GLOBALS['BE_USER']->check('modules', $pageModule)) {
393 $pageModule = '';
394 }
395
396 $menuFrameName = 'menu';
397 if($GLOBALS['BE_USER']->uc['noMenuMode'] === 'icons') {
398 $menuFrameName = 'topmenuFrame';
399 }
400
401 // determine security level from conf vars and default to super challenged
402 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel']) {
403 $this->loginSecurityLevel = $GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel'];
404 } else {
405 $this->loginSecurityLevel = 'superchallenged';
406 }
407
408 $t3Configuration = array(
409 'siteUrl' => t3lib_div::getIndpEnv('TYPO3_SITE_URL'),
410 'PATH_typo3' => $pathTYPO3,
411 'PATH_typo3_enc' => rawurlencode($pathTYPO3),
412 'username' => htmlspecialchars($GLOBALS['BE_USER']->user['username']),
413 'uniqueID' => t3lib_div::shortMD5(uniqid('')),
414 'securityLevel' => $this->loginSecurityLevel,
415 'TYPO3_mainDir' => TYPO3_mainDir,
416 'pageModule' => $pageModule,
417 'condensedMode' => $GLOBALS['BE_USER']->uc['condensedMode'] ? 1 : 0 ,
418 'inWorkspace' => $GLOBALS['BE_USER']->workspace !== 0 ? 1 : 0,
419 'workspaceFrontendPreviewEnabled' => $GLOBALS['BE_USER']->user['workspace_preview'] ? 1 : 0,
420 'veriCode' => $GLOBALS['BE_USER']->veriCode(),
421 'denyFileTypes' => PHP_EXTENSIONS_DEFAULT,
422 'moduleMenuWidth' => $this->menuWidth - 1,
423 'topBarHeight' => (isset($GLOBALS['TBE_STYLES']['dims']['topFrameH']) ? intval($GLOBALS['TBE_STYLES']['dims']['topFrameH']) : 30),
424 'showRefreshLoginPopup' => isset($GLOBALS['TYPO3_CONF_VARS']['BE']['showRefreshLoginPopup']) ? intval($GLOBALS['TYPO3_CONF_VARS']['BE']['showRefreshLoginPopup']) : FALSE,
425 'listModulePath' => t3lib_extMgm::isLoaded('list') ? t3lib_extMgm::extRelPath('list') . 'mod1/' : '',
426 'debugInWindow' => $GLOBALS['BE_USER']->uc['debugInWindow'] ? 1 : 0,
427 'ContextHelpWindows' => array(
428 'width' => 600,
429 'height' => 400
430 )
431 );
432 $t3LLLcore = array(
433 'waitTitle' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_logging_in') ,
434 'refresh_login_failed' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_failed'),
435 'refresh_login_failed_message' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_failed_message'),
436 'refresh_login_title' => sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_title'), htmlspecialchars($GLOBALS['BE_USER']->user['username'])),
437 'login_expired' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.login_expired'),
438 'refresh_login_username' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_username'),
439 'refresh_login_password' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_password'),
440 'refresh_login_emptyPassword' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_emptyPassword'),
441 'refresh_login_button' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_button'),
442 'refresh_logout_button' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_logout_button'),
443 'please_wait' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.please_wait'),
444 'loadingIndicator' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:loadingIndicator'),
445 'be_locked' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.be_locked'),
446 'refresh_login_countdown_singular' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_countdown_singular'),
447 'refresh_login_countdown' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_countdown'),
448 'login_about_to_expire' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.login_about_to_expire'),
449 'login_about_to_expire_title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.login_about_to_expire_title'),
450 'refresh_login_refresh_button' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_refresh_button'),
451 'refresh_direct_logout_button' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_direct_logout_button'),
452 'tabs_closeAll' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:tabs.closeAll'),
453 'tabs_closeOther' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:tabs.closeOther'),
454 'tabs_close' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:tabs.close'),
455 'tabs_openInBrowserWindow' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:tabs.openInBrowserWindow'),
456 'donateWindow_title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:donateWindow.title'),
457 'donateWindow_message' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:donateWindow.message'),
458 'donateWindow_button_donate' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:donateWindow.button_donate'),
459 'donateWindow_button_disable' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:donateWindow.button_disable'),
460 'donateWindow_button_postpone' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:donateWindow.button_postpone'),
461 );
462 $t3LLLfileUpload = array(
463 'windowTitle' => $GLOBALS['LANG']->getLL('fileUpload_windowTitle'),
464 'buttonSelectFiles' => $GLOBALS['LANG']->getLL('fileUpload_buttonSelectFiles'),
465 'buttonCancelAll' => $GLOBALS['LANG']->getLL('fileUpload_buttonCancelAll'),
466 'infoComponentMaxFileSize' => $GLOBALS['LANG']->getLL('fileUpload_infoComponentMaxFileSize'),
467 'infoComponentFileUploadLimit' => $GLOBALS['LANG']->getLL('fileUpload_infoComponentFileUploadLimit'),
468 'infoComponentFileTypeLimit' => $GLOBALS['LANG']->getLL('fileUpload_infoComponentFileTypeLimit'),
469 'infoComponentOverrideFiles' => $GLOBALS['LANG']->getLL('fileUpload_infoComponentOverrideFiles'),
470 'processRunning' => $GLOBALS['LANG']->getLL('fileUpload_processRunning'),
471 'uploadWait' => $GLOBALS['LANG']->getLL('fileUpload_uploadWait'),
472 'uploadStarting' => $GLOBALS['LANG']->getLL('fileUpload_uploadStarting'),
473 'uploadProgress' => $GLOBALS['LANG']->getLL('fileUpload_uploadProgress'),
474 'uploadSuccess' => $GLOBALS['LANG']->getLL('fileUpload_uploadSuccess'),
475 'errorQueueLimitExceeded' => $GLOBALS['LANG']->getLL('fileUpload_errorQueueLimitExceeded'),
476 'errorQueueFileSizeLimit' => $GLOBALS['LANG']->getLL('fileUpload_errorQueueFileSizeLimit'),
477 'errorQueueZeroByteFile' => $GLOBALS['LANG']->getLL('fileUpload_errorQueueZeroByteFile'),
478 'errorQueueInvalidFiletype' => $GLOBALS['LANG']->getLL('fileUpload_errorQueueInvalidFiletype'),
479 'errorUploadHttp' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadHttpError'),
480 'errorUploadMissingUrl' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadMissingUrl'),
481 'errorUploadIO' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadIO'),
482 'errorUploadSecurityError' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadSecurityError'),
483 'errorUploadLimit' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadLimit'),
484 'errorUploadFailed' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadFailed'),
485 'errorUploadFileIDNotFound' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadFileIDNotFound'),
486 'errorUploadFileValidation' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadFileValidation'),
487 'errorUploadFileCancelled' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadFileCancelled'),
488 'errorUploadStopped' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadStopped'),
489 'allErrorMessageTitle' => $GLOBALS['LANG']->getLL('fileUpload_allErrorMessageTitle'),
490 'allErrorMessageText' => $GLOBALS['LANG']->getLL('fileUpload_allErrorMessageText'),
491 'allError401' => $GLOBALS['LANG']->getLL('fileUpload_allError401'),
492 'allError2038' => $GLOBALS['LANG']->getLL('fileUpload_allError2038'),
493 );
494
495 // Convert labels/settings back to UTF-8 since json_encode() only works with UTF-8:
496 if ($GLOBALS['LANG']->charSet !== 'utf-8') {
497 $t3Configuration['username'] = $GLOBALS['LANG']->csConvObj->conv($t3Configuration['username'], $GLOBALS['LANG']->charSet, 'utf-8');
498 $GLOBALS['LANG']->csConvObj->convArray($t3LLLcore, $GLOBALS['LANG']->charSet, 'utf-8');
499 $GLOBALS['LANG']->csConvObj->convArray($t3LLLfileUpload, $GLOBALS['LANG']->charSet, 'utf-8');
500 }
501
502 $this->js .= '
503 TYPO3.configuration = ' . json_encode($t3Configuration) . ';
504 TYPO3.LLL = {
505 core : ' . json_encode($t3LLLcore) . ',
506 fileUpload: ' . json_encode($t3LLLfileUpload) . '
507 };
508
509 /**
510 * TypoSetup object.
511 */
512 function typoSetup() { //
513 this.PATH_typo3 = TYPO3.configuration.PATH_typo3;
514 this.PATH_typo3_enc = TYPO3.configuration.PATH_typo3_enc;
515 this.username = TYPO3.configuration.username;
516 this.uniqueID = TYPO3.configuration.uniqueID;
517 this.navFrameWidth = 0;
518 this.securityLevel = TYPO3.configuration.securityLevel;
519 this.veriCode = TYPO3.configuration.veriCode;
520 this.denyFileTypes = TYPO3.configuration.denyFileTypes;
521 }
522 var TS = new typoSetup();
523 //backwards compatibility
524 /**
525 * Frameset Module object
526 *
527 * Used in main modules with a frameset for submodules to keep the ID between modules
528 * Typically that is set by something like this in a Web>* sub module:
529 * if (top.fsMod) top.fsMod.recentIds["web"] = "\'.intval($this->id).\'";
530 * if (top.fsMod) top.fsMod.recentIds["file"] = "...(file reference/string)...";
531 */
532 function fsModules() { //
533 this.recentIds=new Array(); // used by frameset modules to track the most recent used id for list frame.
534 this.navFrameHighlightedID=new Array(); // used by navigation frames to track which row id was highlighted last time
535 this.currentMainLoaded="";
536 this.currentBank="0";
537 }
538 var fsMod = new fsModules();
539
540 top.goToModule = function(modName, cMR_flag, addGetVars) {
541 TYPO3.ModuleMenu.App.showModule(modName, addGetVars);
542 }
543 ' . $this->setStartupModule();
544
545 // Check editing of page:
546 $this->handlePageEditing();
547
548 }
549
550 /**
551 * Checking if the "&edit" variable was sent so we can open it for editing the page.
552 * Code based on code from "alt_shortcut.php"
553 *
554 * @return void
555 */
556 protected function handlePageEditing() {
557
558 if(!t3lib_extMgm::isLoaded('cms')) {
559 return;
560 }
561
562 // EDIT page:
563 $editId = preg_replace('/[^[:alnum:]_]/', '', t3lib_div::_GET('edit'));
564 $editRecord = '';
565
566 if($editId) {
567
568 // Looking up the page to edit, checking permissions:
569 $where = ' AND ('.$GLOBALS['BE_USER']->getPagePermsClause(2)
570 .' OR '.$GLOBALS['BE_USER']->getPagePermsClause(16).')';
571
572 if(t3lib_div::testInt($editId)) {
573 $editRecord = t3lib_BEfunc::getRecordWSOL('pages', $editId, '*', $where);
574 } else {
575 $records = t3lib_BEfunc::getRecordsByField('pages', 'alias', $editId, $where);
576
577 if(is_array($records)) {
578 reset($records);
579 $editRecord = current($records);
580 t3lib_BEfunc::workspaceOL('pages', $editRecord);
581 }
582 }
583
584 // If the page was accessible, then let the user edit it.
585 if(is_array($editRecord) && $GLOBALS['BE_USER']->isInWebMount($editRecord['uid'])) {
586 // Setting JS code to open editing:
587 $this->js .= '
588 // Load page to edit:
589 window.setTimeout("top.loadEditId('.intval($editRecord['uid']).');", 500);
590 ';
591
592 // "Shortcuts" have been renamed to "Bookmarks"
593 // @deprecated remove shortcuts code in TYPO3 4.7
594 $shortcutSetPageTree = $GLOBALS['BE_USER']->getTSConfigVal('options.shortcut_onEditId_dontSetPageTree');
595 $bookmarkSetPageTree = $GLOBALS['BE_USER']->getTSConfigVal('options.bookmark_onEditId_dontSetPageTree');
596 if ($shortcutSetPageTree !== '') {
597 t3lib_div::deprecationLog('options.shortcut_onEditId_dontSetPageTree - since TYPO3 4.5, will be removed in TYPO3 4.7 - use options.bookmark_onEditId_dontSetPageTree instead');
598 }
599
600 // Checking page edit parameter:
601 if (!$shortcutSetPageTree && !$bookmarkSetPageTree) {
602
603 $shortcutKeepExpanded = $GLOBALS['BE_USER']->getTSConfigVal('options.shortcut_onEditId_keepExistingExpanded');
604 $bookmarkKeepExpanded = $GLOBALS['BE_USER']->getTSConfigVal('options.bookmark_onEditId_keepExistingExpanded');
605 $keepExpanded = ($shortcutKeepExpanded || $bookmarkKeepExpanded);
606
607 // Expanding page tree:
608 t3lib_BEfunc::openPageTree(intval($editRecord['pid']), !$keepExpanded);
609
610 if ($shortcutKeepExpanded) {
611 t3lib_div::deprecationLog('options.shortcut_onEditId_keepExistingExpanded - since TYPO3 4.5, will be removed in TYPO3 4.7 - use options.bookmark_onEditId_keepExistingExpanded instead');
612 }
613 }
614 } else {
615 $this->js .= '
616 // Warning about page editing:
617 alert('.$GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->getLL('noEditPage'), $editId)).');
618 ';
619 }
620 }
621 }
622
623 /**
624 * Sets the startup module from either GETvars module and mpdParams or user configuration.
625 *
626 * @return void
627 */
628 protected function setStartupModule() {
629 $startModule = preg_replace('/[^[:alnum:]_]/', '', t3lib_div::_GET('module'));
630
631 if(!$startModule) {
632 if ($GLOBALS['BE_USER']->uc['startModule']) {
633 $startModule = $GLOBALS['BE_USER']->uc['startModule'];
634 } else if($GLOBALS['BE_USER']->uc['startInTaskCenter']) {
635 $startModule = 'user_task';
636 }
637 }
638
639 $moduleParameters = t3lib_div::_GET('modParams');
640 if($startModule) {
641 return '
642 // start in module:
643 top.startInModule = [\'' . $startModule . '\', ' . t3lib_div::quoteJSvalue($moduleParameters) . '];
644 ';
645 } else {
646 return '';
647 }
648
649 }
650
651 /**
652 * adds a javascript snippet to the backend
653 *
654 * @param string javascript snippet
655 * @return void
656 */
657 public function addJavascript($javascript) {
658 // TODO do we need more checks?
659 if(!is_string($javascript)) {
660 throw new InvalidArgumentException('parameter $javascript must be of type string', 1195129553);
661 }
662
663 $this->js .= $javascript;
664 }
665
666 /**
667 * adds a javscript file to the backend after it has been checked that it exists
668 *
669 * @param string javascript file reference
670 * @return boolean true if the javascript file was successfully added, false otherwise
671 */
672 public function addJavascriptFile($javascriptFile) {
673 $jsFileAdded = false;
674
675 //TODO add more checks if neccessary
676 if(file_exists(t3lib_div::resolveBackPath(PATH_typo3.$javascriptFile))) {
677 $this->jsFiles[] = $javascriptFile;
678 $jsFileAdded = true;
679 }
680
681 return $jsFileAdded;
682 }
683
684 /**
685 * adds a css snippet to the backend
686 *
687 * @param string css snippet
688 * @return void
689 */
690 public function addCss($css) {
691 if(!is_string($css)) {
692 throw new InvalidArgumentException('parameter $css must be of type string', 1195129642);
693 }
694
695 $this->css .= $css;
696 }
697
698 /**
699 * adds a css file to the backend after it has been checked that it exists
700 *
701 * @param string the css file's name with out the .css ending
702 * @param string css file reference
703 * @return boolean true if the css file was added, false otherwise
704 */
705 public function addCssFile($cssFileName, $cssFile) {
706 $cssFileAdded = false;
707
708 if(empty($this->cssFiles[$cssFileName])) {
709 $this->cssFiles[$cssFileName] = $cssFile;
710 $cssFileAdded = true;
711 }
712
713 return $cssFileAdded;
714 }
715
716 /**
717 * adds an item to the toolbar, the class file for the toolbar item must be loaded at this point
718 *
719 * @param string toolbar item name, f.e. tx_toolbarExtension_coolItem
720 * @param string toolbar item class name, f.e. tx_toolbarExtension_coolItem
721 * @return void
722 */
723 public function addToolbarItem($toolbarItemName, $toolbarItemClassName) {
724 $toolbarItem = t3lib_div::makeInstance($toolbarItemClassName, $this);
725
726 if(!($toolbarItem instanceof backend_toolbarItem)) {
727 throw new UnexpectedValueException('$toolbarItem "'.$toolbarItemName.'" must implement interface backend_toolbarItem', 1195125501);
728 }
729
730 if($toolbarItem->checkAccess()) {
731 $this->toolbarItems[$toolbarItemName] = $toolbarItem;
732 } else {
733 unset($toolbarItem);
734 }
735 }
736
737 /**
738 * Executes defined hooks functions for the given identifier.
739 *
740 * These hook identifiers are valid:
741 * + constructPostProcess
742 * + renderPreProcess
743 * + renderPostProcess
744 *
745 * @param string $identifier Specific hook identifier
746 * @param array $hookConfiguration Additional configuration passed to hook functions
747 * @return void
748 */
749 protected function executeHook($identifier, array $hookConfiguration = array()) {
750 $options =& $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/backend.php'];
751
752 if(isset($options[$identifier]) && is_array($options[$identifier])) {
753 foreach($options[$identifier] as $hookFunction) {
754 t3lib_div::callUserFunction($hookFunction, $hookConfiguration, $this);
755 }
756 }
757 }
758 }
759
760
761 // include XCLASS
762 if(defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/backend.php']) {
763 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/backend.php']);
764 }
765
766
767 // document generation
768 $TYPO3backend = t3lib_div::makeInstance('TYPO3backend');
769
770 // include extensions which may add css, javascript or toolbar items
771 if(is_array($GLOBALS['TYPO3_CONF_VARS']['typo3/backend.php']['additionalBackendItems'])) {
772 foreach($GLOBALS['TYPO3_CONF_VARS']['typo3/backend.php']['additionalBackendItems'] as $additionalBackendItem) {
773 include_once($additionalBackendItem);
774 }
775 }
776
777 $TYPO3backend->render();
778
779 ?>