See changelog (2004-08-21). Localization features, Tab menus, few bugs fixed.
[Packages/TYPO3.CMS.git] / typo3 / alt_main.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2004 Kasper Skaarhoj (kasper@typo3.com)
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 * Main frameset of the TYPO3 backend
29 * Sending the GET var "alt_main.php?edit=[page id]" will load the page id in the editing module configured.
30 *
31 * $Id$
32 * Revised for TYPO3 3.6 2/2003 by Kasper Skaarhoj
33 * XHTML Compliant (almost)
34 *
35 * @author Kasper Skaarhoj <kasper@typo3.com>
36 */
37 /**
38 * [CLASS/FUNCTION INDEX of SCRIPT]
39 *
40 *
41 *
42 * 67: class SC_alt_main
43 * 86: function init()
44 * 108: function generateJScode()
45 * 305: function main()
46 * 379: function printContent()
47 *
48 * TOTAL FUNCTIONS: 4
49 * (This index is automatically created/updated by the extension "extdeveval")
50 *
51 */
52
53 require ('init.php');
54 require ('template.php');
55 require_once (PATH_t3lib.'class.t3lib_loadmodules.php');
56 require_once (PATH_t3lib.'class.t3lib_basicfilefunc.php');
57 require_once ('class.alt_menu_functions.inc');
58 $LANG->includeLLFile('EXT:lang/locallang_misc.xml');
59
60
61
62
63 /**
64 * Script Class for rendering of the main frameset for the TYPO3 backend.
65 *
66 * @author Kasper Skaarhoj <kasper@typo3.com>
67 * @package TYPO3
68 * @subpackage core
69 */
70 class SC_alt_main {
71
72 // Internal, dynamic:
73 var $content;
74 var $mainJScode;
75 var $loadModules; // Load modules-object
76 var $alt_menuObj; // Menu functions object.
77
78 // Internal, static:
79 var $leftMenuFrameW = 130;
80 var $selMenuFrame = 130;
81 var $topFrameH = 32;
82 var $shortcutFrameH = 30;
83
84 /**
85 * Initialization of the script class
86 *
87 * @return void
88 */
89 function init() {
90 global $TBE_MODULES,$TBE_STYLES;
91
92 // Initializes the backend modules structure for use later.
93 $this->loadModules = t3lib_div::makeInstance('t3lib_loadModules');
94 $this->loadModules->load($TBE_MODULES);
95
96 // Instantiates thee menu object which will generate some JavaScript for the goToModule() JS function in this frameset.
97 $this->alt_menuObj = t3lib_div::makeInstance('alt_menu_functions');
98
99 // Check for distances defined in the styles array:
100 if ($TBE_STYLES['dims']['leftMenuFrameW']) $this->leftMenuFrameW = $TBE_STYLES['dims']['leftMenuFrameW'];
101 if ($TBE_STYLES['dims']['topFrameH']) $this->topFrameH = $TBE_STYLES['dims']['topFrameH'];
102 if ($TBE_STYLES['dims']['shortcutFrameH']) $this->shortcutFrameH = $TBE_STYLES['dims']['shortcutFrameH'];
103 if ($TBE_STYLES['dims']['selMenuFrame']) $this->selMenuFrame = $TBE_STYLES['dims']['selMenuFrame'];
104 }
105
106 /**
107 * Generates the JavaScript code for the frameset.
108 *
109 * @return void
110 */
111 function generateJScode() {
112 global $BE_USER,$LANG;
113
114 $pt3 = t3lib_div::dirname(t3lib_div::getIndpEnv('SCRIPT_NAME')).'/';
115 $goToModule_switch = $this->alt_menuObj->topMenu($this->loadModules->modules,0,"",4);
116 $fsMod = implode(chr(10),$this->alt_menuObj->fsMod);
117
118 // If another page module was specified, replace the default Page module with the new one
119 $newPageModule = trim($GLOBALS['BE_USER']->getTSConfigVal('options.overridePageModule'));
120 $pageModule = t3lib_BEfunc::isModuleSetInTBE_MODULES($newPageModule) ? $newPageModule : 'web_layout';
121
122 $this->mainJScode='
123 /**
124 * Function similar to PHPs rawurlencode();
125 */
126 function rawurlencode(str) { //
127 var output = escape(str);
128 output = str_replace("*","%2A", output);
129 output = str_replace("+","%2B", output);
130 output = str_replace("/","%2F", output);
131 output = str_replace("@","%40", output);
132 return output;
133 }
134
135 /**
136 * String-replace function
137 */
138 function str_replace(match,replace,string) { //
139 var input = ""+string;
140 var matchStr = ""+match;
141 if (!matchStr) {return string;}
142 var output = "";
143 var pointer=0;
144 var pos = input.indexOf(matchStr);
145 while (pos!=-1) {
146 output+=""+input.substr(pointer, pos-pointer)+replace;
147 pointer=pos+matchStr.length;
148 pos = input.indexOf(match,pos+1);
149 }
150 output+=""+input.substr(pointer);
151 return output;
152 }
153
154 /**
155 * TypoSetup object.
156 */
157 function typoSetup() { //
158 this.PATH_typo3 = "'.$pt3.'";
159 this.PATH_typo3_enc = "'.rawurlencode($pt3).'";
160 this.username = "'.$BE_USER->user['username'].'";
161 this.uniqueID = "'.t3lib_div::shortMD5(uniqid('')).'";
162 this.navFrameWidth = 0;
163 }
164 var TS = new typoSetup();
165
166 /**
167 * Functions for session-expiry detection:
168 */
169 function busy() { //
170 this.loginRefreshed = busy_loginRefreshed;
171 this.checkLoginTimeout = busy_checkLoginTimeout;
172 this.openRefreshWindow = busy_OpenRefreshWindow;
173 this.busyloadTime=0;
174 this.openRefreshW=0;
175 }
176 function busy_loginRefreshed() { //
177 var date = new Date();
178 this.busyloadTime = Math.floor(date.getTime()/1000);
179 this.openRefreshW=0;
180 }
181 function busy_checkLoginTimeout() { //
182 var date = new Date();
183 var theTime = Math.floor(date.getTime()/1000);
184 if (theTime > this.busyloadTime+'.intval($BE_USER->auth_timeout_field).'-10) {
185 return true;
186 }
187 }
188 function busy_OpenRefreshWindow() { //
189 vHWin=window.open("login_frameset.php","relogin","height=350,width=700,status=0,menubar=0");
190 vHWin.focus();
191 this.openRefreshW=1;
192 }
193 function busy_checkLoginTimeout_timer() { //
194
195 if (busy.checkLoginTimeout()) {
196 if (!busy.openRefreshW && confirm('.$GLOBALS['LANG']->JScharCode($LANG->sL('LLL:EXT:lang/locallang_core.php:mess.refresh_login')).')) {
197 busy.openRefreshWindow();
198 }
199 }
200 window.setTimeout("busy_checkLoginTimeout_timer();",2*1000); // Each 2nd second is enough for checking. The popup will be triggered 10 seconds before the login expires (see above, busy_checkLoginTimeout())
201
202 // Detecting the frameset module navigation frame widths (do this AFTER setting new timeout so that any errors in the code below does not prevent another time to be set!)
203 if (top && top.content && top.content.nav_frame && top.content.nav_frame.document && top.content.nav_frame.document.body) {
204 TS.navFrameWidth = (top.content.nav_frame.document.documentElement && top.content.nav_frame.document.documentElement.clientWidth) ? top.content.nav_frame.document.documentElement.clientWidth : top.content.nav_frame.document.body.clientWidth;
205 }
206 }
207
208 /**
209 * Launcing information window for records/files (fileref as "table" argument)
210 */
211 function launchView(table,uid,bP) { //
212 var backPath= bP ? bP : "";
213 var thePreviewWindow="";
214 thePreviewWindow = window.open(TS.PATH_typo3+"show_item.php?table="+escape(table)+"&uid="+escape(uid),"ShowItem"+TS.uniqueID,"height=300,width=410,status=0,menubar=0,resizable=0,location=0,directories=0,scrollbars=1,toolbar=0");
215 if (thePreviewWindow && thePreviewWindow.focus) {
216 thePreviewWindow.focus();
217 }
218 }
219
220 /**
221 * Opens plain window with url
222 */
223 function openUrlInWindow(url,windowName) { //
224 regularWindow = window.open(url,windowName,"status=1,menubar=1,resizable=1,location=1,directories=0,scrollbars=1,toolbar=1");
225 regularWindow.focus();
226 return false;
227 }
228
229 /**
230 * Loads a URL in the topmenuFrame
231 */
232 function loadTopMenu(url) { //
233 top.topmenuFrame.location = url;
234 }
235
236 /**
237 * Loads a page id for editing in the page edit module:
238 */
239 function loadEditId(id,addGetVars) { //
240 top.fsMod.recentIds["web"]=id;
241 top.fsMod.navFrameHighlightedID["web"]="pages"+id+"_0"; // For highlighting
242
243 if (top.content && top.content.nav_frame && top.content.nav_frame.refresh_nav) {
244 top.content.nav_frame.refresh_nav();
245 }
246
247 top.goToModule("'.$pageModule.'", 0, addGetVars?addGetVars:"");
248 }
249
250 /**
251 * Returns incoming URL (to a module) unless nextLoadModuleUrl is set. If that is the case nextLoadModuleUrl is returned (and cleared)
252 * Used by the shortcut frame to set a "intermediate URL"
253 */
254 var nextLoadModuleUrl="";
255 function getModuleUrl(inUrl) { //
256 var nMU;
257 if (top.nextLoadModuleUrl) {
258 nMU=top.nextLoadModuleUrl;
259 top.nextLoadModuleUrl="";
260 return nMU;
261 } else {
262 return inUrl;
263 }
264 }
265
266 /**
267 * Print properties of an object
268 */
269 function debugObj(obj,name) { //
270 var acc;
271 for (i in obj) {
272 if (obj[i]) {
273 acc+=i+": "+obj[i]+"\n";
274 }
275 }
276 alert("Object: "+name+"\n\n"+acc);
277 }
278
279 /**
280 * Initialize login expiration warning object
281 */
282 var busy = new busy();
283 busy.loginRefreshed();
284 busy_checkLoginTimeout_timer();
285
286
287 /**
288 * Highlight module:
289 */
290 var currentlyHighLightedId = "";
291 var currentlyHighLighted_restoreValue = "";
292 function highlightModuleMenuItem(trId, mainModule) {
293 // Get document object:
294 if (top.menu && top.menu.document) {
295 var docObj = top.menu.document;
296 var HLclass = mainModule ? "c-mainitem-HL" : "c-subitem-row-HL";
297 } else if (top.topmenuFrame && top.topmenuFrame.document) {
298 var docObj = top.topmenuFrame.document;
299 var HLclass = mainModule ? "c-mainitem-HL" : "c-subitem-HL";
300 }
301
302 if (docObj) {
303 // Reset old:
304 if (currentlyHighLightedId && docObj.getElementById(currentlyHighLightedId)) {
305 docObj.getElementById(currentlyHighLightedId).attributes.getNamedItem("class").nodeValue = currentlyHighLighted_restoreValue;
306 }
307 // Set new:
308 currentlyHighLightedId = trId;
309 if (currentlyHighLightedId && docObj.getElementById(currentlyHighLightedId)) {
310 var classAttribObject = docObj.getElementById(currentlyHighLightedId).attributes.getNamedItem("class");
311 currentlyHighLighted_restoreValue = classAttribObject.nodeValue;
312 classAttribObject.nodeValue = HLclass;
313 }
314 }
315 }
316
317 /**
318 * Function used to switch switch module.
319 */
320 var currentModuleLoaded = "";
321 function goToModule(modName,cMR_flag,addGetVars) { //
322 var additionalGetVariables = "";
323 if (addGetVars) additionalGetVariables = addGetVars;
324
325 var cMR = 0;
326 if (cMR_flag) cMR = 1;
327
328 currentModuleLoaded = modName;
329
330 switch(modName) {'.$goToModule_switch.'
331 }
332 }
333
334 /**
335 * Frameset Module object
336 *
337 * Used in main modules with a frameset for submodules to keep the ID between modules
338 * Typically that is set by something like this in a Web>* sub module:
339 * if (top.fsMod) top.fsMod.recentIds["web"] = "\'.intval($this->id).\'";
340 * if (top.fsMod) top.fsMod.recentIds["file"] = "...(file reference/string)...";
341 */
342 function fsModules() { //
343 this.recentIds=new Array(); // used by frameset modules to track the most recent used id for list frame.
344 this.navFrameHighlightedID=new Array(); // used by navigation frames to track which row id was highlighted last time
345 this.currentMainLoaded="";
346 }
347 var fsMod = new fsModules();
348 '.$fsMod.'
349
350 // Used by Frameset Modules
351 var condensedMode = '.($BE_USER->uc['condensedMode']?1:0).';
352 var currentSubScript = "";
353 var currentSubNavScript = "";
354
355 // Used for tab-panels:
356 var DTM_currentTabs = new Array();
357 ';
358
359 // Check editing of page:
360 $this->editPageHandling();
361 }
362
363 /**
364 * Checking if the "&edit" variable was sent so we can open for editing the page.
365 * Code based on code from "alt_shortcut.php"
366 *
367 * @return void
368 */
369 function editPageHandling() {
370 global $BE_USER;
371
372 if (!t3lib_extMgm::isLoaded('cms')) return;
373
374 // EDIT page:
375 $editId = ereg_replace('[^[:alnum:]_]','',t3lib_div::_GET('edit'));
376 $theEditRec = '';
377
378 if ($editId) {
379
380 // Looking up the page to edit, checking permissions:
381 $where = ' AND ('.$BE_USER->getPagePermsClause(2).' OR '.$BE_USER->getPagePermsClause(16).')';
382 if (t3lib_div::testInt($editId)) {
383 $theEditRec = t3lib_BEfunc::getRecord('pages',$editId,'*',$where);
384 } else {
385 $records = t3lib_BEfunc::getRecordsByField('pages','alias',$editId,$where);
386 if (is_array($records)) {
387 reset($records);
388 $theEditRec = current($records);
389 }
390 }
391
392 // If the page was accessible, then let the user edit it.
393 if (is_array($theEditRec) && $BE_USER->isInWebMount($theEditRec['uid'])) {
394 // Setting JS code to open editing:
395 $this->mainJScode.='
396 // Load page to edit:
397 window.setTimeout("top.loadEditId('.intval($theEditRec['uid']).');",500);
398 ';
399 // Checking page edit parameter:
400 if(!$BE_USER->getTSConfigVal('options.shortcut_onEditId_dontSetPageTree')) {
401
402 // Expanding page tree:
403 t3lib_BEfunc::openPageTree(intval($theEditRec['pid']),!$BE_USER->getTSConfigVal('options.shortcut_onEditId_keepExistingExpanded'));
404 }
405 } else {
406 $this->mainJScode.='
407 // Warning about page editing:
408 alert('.$GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->getLL('noEditPage'),$editId)).');
409 ';
410 }
411 }
412 }
413
414 /**
415 * Creates the header and frameset of the backend interface
416 *
417 * @return void
418 */
419 function main() {
420 global $BE_USER,$TYPO3_CONF_VARS,$TYPO_VERSION;
421
422 // Set doktype:
423 $GLOBALS['TBE_TEMPLATE']->docType='xhtml_frames';
424
425 // Make JS:
426 $this->generateJScode();
427 $GLOBALS['TBE_TEMPLATE']->JScode= '
428 <script type="text/javascript" src="md5.js"></script>
429 <script type="text/javascript" src="t3lib/jsfunc.evalfield.js"></script>
430 ';
431 $GLOBALS['TBE_TEMPLATE']->JScode.=$GLOBALS['TBE_TEMPLATE']->wrapScriptTags($this->mainJScode);
432
433 // Title:
434 $title = $TYPO3_CONF_VARS['SYS']['sitename'] ? $TYPO3_CONF_VARS['SYS']['sitename'].' [TYPO3 '.$TYPO_VERSION.']' : 'TYPO3 '.$TYPO_VERSION;
435
436 // Start page header:
437 $this->content.=$GLOBALS['TBE_TEMPLATE']->startPage($title);
438
439 // Creates frameset
440 $fr_content = '<frame name="content" src="'.($BE_USER->uc['startInTaskCenter']&&t3lib_extMgm::isLoaded('taskcenter')?t3lib_extMgm::extRelPath('taskcenter').'task/frameset.php':'alt_intro.php').'" marginwidth="0" marginheight="0" frameborder="0" scrolling="auto" noresize="noresize" />';
441 $fr_toplogo = '<frame name="toplogo" src="alt_toplogo.php" marginwidth="0" marginheight="0" frameborder="0" scrolling="no" noresize="noresize" />';
442 $fr_topmenu = '<frame name="topmenuFrame" src="alt_topmenu_dummy.php" marginwidth="0" marginheight="0" frameborder="0" scrolling="no" noresize="noresize" />';
443
444 $shortcutFrame=array();
445 if ($BE_USER->getTSConfigVal('options.shortcutFrame')) {
446 $shortcutFrame['rowH']=','.$this->shortcutFrameH;
447 $shortcutFrame['frameDef']='<frame name="shortcutFrame" src="alt_shortcut.php" marginwidth="0" marginheight="0" frameborder="0" scrolling="no" noresize="noresize" />';
448 }
449
450 // XHTML notice: ' framespacing="0" frameborder="0" border="0"' in FRAMESET elements breaks compatibility with XHTML-frames, but HOW ELSE can I control the visual appearance?
451 if ($GLOBALS['BE_USER']->uc['noMenuMode']) {
452 $this->content.= '
453 <frameset rows="'.$this->topFrameH.',*'.$shortcutFrame['rowH'].'" framespacing="0" frameborder="0" border="0">
454 '.(!strcmp($BE_USER->uc['noMenuMode'],'icons') ? '
455 <frameset cols="'.$this->leftMenuFrameW.',*" framespacing="0" frameborder="0" border="0">
456 '.$fr_toplogo.'
457 '.$fr_topmenu.'
458 </frameset>' : '
459 <frameset cols="'.$this->leftMenuFrameW.','.$this->selMenuFrame.',*" framespacing="0" frameborder="0" border="0">
460 '.$fr_toplogo.'
461 <frame name="menu" src="alt_menu_sel.php" scrolling="no" noresize="noresize" />
462 '.$fr_topmenu.'
463 </frameset>').'
464 '.$fr_content.'
465 '.$shortcutFrame['frameDef'].'
466 </frameset>
467 ';
468 } else {
469 $this->content.='
470 <frameset rows="'.$this->topFrameH.',*'.$shortcutFrame['rowH'].'" framespacing="0" frameborder="0" border="0">
471 <frameset cols="'.$this->leftMenuFrameW.',*" framespacing="0" frameborder="0" border="0">
472 '.$fr_toplogo.'
473 '.$fr_topmenu.'
474 </frameset>
475 <frameset cols="'.$this->leftMenuFrameW.',*" framespacing="0" frameborder="0" border="0">
476 <frame name="menu" src="alt_menu.php" marginwidth="0" marginheight="0" scrolling="auto" noresize="noresize" />
477 '.$fr_content.'
478 </frameset>
479 '.$shortcutFrame['frameDef'].'
480 </frameset>
481 ';
482 }
483 $this->content.='
484
485 </html>';
486 }
487
488 /**
489 * Outputting the accumulated content to screen
490 *
491 * @return void
492 */
493 function printContent() {
494 echo $this->content;
495 }
496 }
497
498 // Include extension?
499 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/alt_main.php']) {
500 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/alt_main.php']);
501 }
502
503
504
505
506
507
508
509
510 // ******************************
511 // Starting document output
512 // ******************************
513
514 // Make instance:
515 $SOBE = t3lib_div::makeInstance('SC_alt_main');
516 $SOBE->init();
517 $SOBE->main();
518 $SOBE->printContent();
519 ?>