(bugfix) Fixed Image Generation bug. Call in t3lib_div now uses the IM wrapper to...
[Packages/TYPO3.CMS.git] / typo3 / alt_doc.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@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 form rendering script
29 * By sending certain parameters to this script you can bring up a form
30 * which allows the user to edit the content of one or more database records.
31 *
32 * $Id$
33 * Revised for TYPO3 3.6 November/2003 by Kasper Skaarhoj
34 * XHTML compliant
35 *
36 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
37 */
38 /**
39 * [CLASS/FUNCTION INDEX of SCRIPT]
40 *
41 *
42 *
43 * 105: class SC_alt_doc
44 * 179: function preInit()
45 * 241: function doProcessData()
46 * 251: function processData()
47 * 379: function init()
48 * 473: function main()
49 * 551: function printContent()
50 *
51 * SECTION: Sub-content functions, rendering specific parts of the module content.
52 * 587: function makeEditForm()
53 * 771: function makeButtonPanel()
54 * 850: function makeDocSel()
55 * 892: function makeCmenu()
56 * 914: function compileForm($panel,$docSel,$cMenu,$editForm, $langSelector='')
57 * 982: function functionMenus()
58 * 1013: function shortCutLink()
59 * 1044: function tceformMessages()
60 *
61 * SECTION: Localization stuff
62 * 1083: function languageSwitch($table, $uid, $pid=NULL)
63 * 1179: function localizationRedirect($justLocalized)
64 * 1213: function getLanguages($id)
65 *
66 * SECTION: Other functions
67 * 1275: function fixWSversioningInEditConf($mapArray=FALSE)
68 * 1324: function getRecordForEdit($table,$theUid)
69 * 1358: function editRegularContentFromId()
70 * 1386: function compileStoreDat()
71 * 1399: function getNewIconMode($table,$key='saveDocNew')
72 * 1412: function closeDocument($code=0)
73 * 1444: function setDocument($currentDocFromHandlerMD5='',$retUrl='alt_doc_nodoc.php')
74 *
75 * TOTAL FUNCTIONS: 24
76 * (This index is automatically created/updated by the extension "extdeveval")
77 *
78 */
79
80
81 require('init.php');
82 require('template.php');
83 $LANG->includeLLFile('EXT:lang/locallang_alt_doc.xml');
84 require_once (PATH_t3lib.'class.t3lib_tceforms.php');
85 require_once (PATH_t3lib.'class.t3lib_clipboard.php');
86
87 require_once (PATH_t3lib.'class.t3lib_tcemain.php');
88 require_once (PATH_t3lib.'class.t3lib_loaddbgroup.php');
89 require_once (PATH_t3lib.'class.t3lib_transferdata.php');
90
91
92 t3lib_BEfunc::lockRecords();
93
94
95
96
97 /**
98 * Script Class: Drawing the editing form for editing records in TYPO3.
99 * Notice: It does NOT use tce_db.php to submit data to, rather it handles submissions itself
100 *
101 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
102 * @package TYPO3
103 * @subpackage core
104 */
105 class SC_alt_doc {
106
107 // Internal, static: GPvars:
108 var $editconf; // GPvar "edit": Is an array looking approx like [tablename][list-of-ids]=command, eg. "&edit[pages][123]=edit". See t3lib_BEfunc::editOnClick(). Value can be seen modified internally (converting NEW keyword to id, workspace/versioning etc).
109 var $columnsOnly; // Commalist of fieldnames to edit. The point is IF you specify this list, only those fields will be rendered in the form. Otherwise all (available) fields in the record is shown according to the types configuration in $TCA
110 var $defVals; // Default values for fields (array with tablenames, fields etc. as keys). Can be seen modified internally.
111 var $overrideVals; // Array of values to force being set (as hidden fields). Will be set as $this->defVals IF defVals does not exist.
112 var $returnUrl; // If set, this value will be set in $this->retUrl (which is used quite many places as the return URL). If not set, "dummy.php" will be set in $this->retUrl
113 var $closeDoc; // Close-document command. Not really sure of all options...
114 var $doSave; // Quite simply, if this variable is set, then the processing of incoming data will be performed - as if a save-button is pressed. Used in the forms as a hidden field which can be set through JavaScript if the form is somehow submitted by JavaScript).
115
116 var $data; // GPvar (for processing only) : The data array from which the data comes...
117 var $mirror; // GPvar (for processing only) : ?
118 var $cacheCmd; // GPvar (for processing only) : Clear-cache cmd.
119 var $redirect; // GPvar (for processing only) : Redirect (not used???)
120 var $disableRTE; // GPvar (for processing only) : If set, the rich text editor is disabled in the forms.
121 var $returnNewPageId; // GPvar (for processing only) : Boolean: If set, then the GET var "&id=" will be added to the retUrl string so that the NEW id of something is returned to the script calling the form.
122 var $vC; // GPvar (for processing only) : Verification code, internal stuff.
123 var $uc; // GPvar : update BE_USER->uc
124
125 var $popViewId; // GPvar (module) : ID for displaying the page in the frontend (used for SAVE/VIEW operations)
126 var $popViewId_addParams; // GPvar (module) : Additional GET vars for the link, eg. "&L=xxx"
127 var $viewUrl; // GPvar (module) : Alternative URL for viewing the frontend pages.
128 var $editRegularContentFromId; // If this is pointing to a page id it will automatically load all content elements (NORMAL column/default language) from that page into the form!
129 var $recTitle; // Alternative title for the document handler.
130 var $disHelp; // Disable help... ?
131 var $noView; // If set, then no SAVE/VIEW button is printed
132 var $returnEditConf; // If set, the $this->editconf array is returned to the calling script (used by wizard_add.php for instance)
133 var $localizationMode; // GP var, localization mode for TCEforms (eg. "text")
134
135
136 // Internal, static:
137 /**
138 * document template object
139 *
140 * @var mediumDoc
141 */
142 var $doc;
143 var $content; // Content accumulation
144
145 var $retUrl; // Return URL script, processed. This contains the script (if any) that we should RETURN TO from the alt_doc.php script IF we press the close button. Thus this variable is normally passed along from the calling script so we can properly return if needed.
146 var $R_URL_parts; // Contains the parts of the REQUEST_URI (current url). By parts we mean the result of resolving REQUEST_URI (current url) by the parse_url() function. The result is an array where eg. "path" is the script path and "query" is the parameters...
147 var $R_URL_getvars; // Contains the current GET vars array; More specifically this array is the foundation for creating the R_URI internal var (which becomes the "url of this script" to which we submit the forms etc.)
148 var $R_URI; // Set to the URL of this script including variables which is needed to re-display the form. See main()
149
150 var $storeTitle; // Is loaded with the "title" of the currently "open document" - this is used in the Document Selector box. (see makeDocSel())
151 var $storeArray; // Contains an array with key/value pairs of GET parameters needed to reach the current document displayed - used in the Document Selector box. (see compileStoreDat())
152 var $storeUrl; // Contains storeArray, but imploded into a GET parameter string (see compileStoreDat())
153 var $storeUrlMd5; // Hashed value of storeURL (see compileStoreDat())
154
155 var $docDat; // Module session data
156 var $docHandler; // An array of the "open documents" - keys are md5 hashes (see $storeUrlMd5) identifying the various documents on the GET parameter list needed to open it. The values are arrays with 0,1,2 keys with information about the document (see compileStoreDat()). The docHandler variable is stored in the $docDat session data, key "0".
157
158
159 // Internal: Related to the form rendering:
160 var $elementsData; // Array of the elements to create edit forms for.
161 var $firstEl; // Pointer to the first element in $elementsData
162 var $errorC; // Counter, used to count the number of errors (when users do not have edit permissions)
163 var $newC; // Counter, used to count the number of new record forms displayed
164 var $viewId; // Is set to the pid value of the last shown record - thus indicating which page to show when clicking the SAVE/VIEW button
165 var $viewId_addParams; // Is set to additional parameters (like "&L=xxx") if the record supports it.
166 var $modTSconfig; // Module TSconfig, loaded from main() based on the page id value of viewId
167
168 /**
169 * instance of TCEforms class
170 *
171 * @var t3lib_TCEforms
172 */
173 var $tceforms;
174 var $generalPathOfForm; // Contains the root-line path of the currently edited record(s) - for display.
175
176
177 // Internal, dynamic:
178 var $dontStoreDocumentRef; // Used internally to disable the storage of the document reference (eg. new records)
179
180
181
182
183
184
185
186 /**
187 * First initialization.
188 *
189 * @return void
190 */
191 function preInit() {
192 global $BE_USER;
193
194 if (t3lib_div::_GP('justLocalized')) {
195 $this->localizationRedirect(t3lib_div::_GP('justLocalized'));
196 }
197
198 // Setting GPvars:
199 $this->editconf = t3lib_div::_GP('edit');
200 $this->defVals = t3lib_div::_GP('defVals');
201 $this->overrideVals = t3lib_div::_GP('overrideVals');
202 $this->columnsOnly = t3lib_div::_GP('columnsOnly');
203 $this->returnUrl = t3lib_div::_GP('returnUrl');
204 $this->closeDoc = t3lib_div::_GP('closeDoc');
205 $this->doSave = t3lib_div::_GP('doSave');
206 $this->returnEditConf = t3lib_div::_GP('returnEditConf');
207 $this->localizationMode = t3lib_div::_GP('localizationMode');
208 $this->uc = t3lib_div::_GP('uc');
209
210
211 // Setting override values as default if defVals does not exist.
212 if (!is_array($this->defVals) && is_array($this->overrideVals)) {
213 $this->defVals = $this->overrideVals;
214 }
215
216 // Setting return URL
217 $this->retUrl = $this->returnUrl ? $this->returnUrl : 'dummy.php';
218
219 // Fix $this->editconf if versioning applies to any of the records
220 $this->fixWSversioningInEditConf();
221
222 // Make R_URL (request url) based on input GETvars:
223 $this->R_URL_parts = parse_url(t3lib_div::getIndpEnv('REQUEST_URI'));
224 $this->R_URL_getvars = t3lib_div::_GET();
225 $this->R_URL_getvars['edit'] = $this->editconf;
226
227 // MAKE url for storing
228 $this->compileStoreDat();
229
230 // Initialize more variables.
231 $this->dontStoreDocumentRef=0;
232 $this->storeTitle='';
233
234 // Get session data for the module:
235 $this->docDat = $BE_USER->getModuleData('alt_doc.php','ses');
236 $this->docHandler = $this->docDat[0];
237
238 // If a request for closing the document has been sent, act accordingly:
239 if ($this->closeDoc>0) {
240 $this->closeDocument($this->closeDoc);
241 }
242
243 // If NO vars are sent to the script, try to read first document:
244 if (is_array($this->R_URL_getvars) && count($this->R_URL_getvars)<2 && !is_array($this->editconf)) { // Added !is_array($this->editconf) because editConf must not be set either. Anyways I can't figure out when this situation here will apply...
245 $this->setDocument($this->docDat[1]);
246 }
247 }
248
249 /**
250 * Detects, if a save command has been triggered.
251 *
252 * @return boolean True, then save the document (data submitted)
253 */
254 function doProcessData() {
255 $out = $this->doSave || isset($_POST['_savedok_x']) || isset($_POST['_saveandclosedok_x']) || isset($_POST['_savedokview_x']) || isset($_POST['_savedoknew_x']);
256 return $out;
257 }
258
259 /**
260 * Do processing of data, submitting it to TCEmain.
261 *
262 * @return void
263 */
264 function processData() {
265 global $BE_USER,$TYPO3_CONF_VARS;
266
267 // GPvars specifically for processing:
268 $this->data = t3lib_div::_GP('data');
269 $this->cmd = t3lib_div::_GP('cmd');
270 $this->mirror = t3lib_div::_GP('mirror');
271 $this->cacheCmd = t3lib_div::_GP('cacheCmd');
272 $this->redirect = t3lib_div::_GP('redirect');
273 $this->disableRTE = t3lib_div::_GP('_disableRTE');
274 $this->returnNewPageId = t3lib_div::_GP('returnNewPageId');
275 $this->vC = t3lib_div::_GP('vC');
276
277 // See tce_db.php for relevate options here:
278 // Only options related to $this->data submission are included here.
279 $tce = t3lib_div::makeInstance('t3lib_TCEmain');
280 $tce->stripslashes_values=0;
281
282 // Setting default values specific for the user:
283 $TCAdefaultOverride = $BE_USER->getTSConfigProp('TCAdefaults');
284 if (is_array($TCAdefaultOverride)) {
285 $tce->setDefaultsFromUserTS($TCAdefaultOverride);
286 }
287
288 // Setting internal vars:
289 if ($BE_USER->uc['neverHideAtCopy']) { $tce->neverHideAtCopy = 1; }
290 $tce->debug=0;
291 $tce->disableRTE = $this->disableRTE;
292
293 // Loading TCEmain with data:
294 $tce->start($this->data,$this->cmd);
295 if (is_array($this->mirror)) { $tce->setMirror($this->mirror); }
296
297 // If pages are being edited, we set an instruction about updating the page tree after this operation.
298 if (isset($this->data['pages'])) {
299 t3lib_BEfunc::getSetUpdateSignal('updatePageTree');
300 }
301
302
303 // Checking referer / executing
304 $refInfo=parse_url(t3lib_div::getIndpEnv('HTTP_REFERER'));
305 $httpHost = t3lib_div::getIndpEnv('TYPO3_HOST_ONLY');
306 if ($httpHost!=$refInfo['host'] && $this->vC!=$BE_USER->veriCode() && !$TYPO3_CONF_VARS['SYS']['doNotCheckReferer']) {
307 $tce->log('',0,0,0,1,"Referer host '%s' and server host '%s' did not match and veriCode was not valid either!",1,array($refInfo['host'],$httpHost));
308 debug('Error: Referer host did not match with server host.');
309 } else {
310
311 // Perform the saving operation with TCEmain:
312 $tce->process_uploads($_FILES);
313 $tce->process_datamap();
314 $tce->process_cmdmap();
315
316 // If there was saved any new items, load them:
317 if (count($tce->substNEWwithIDs_table)) {
318 // save the expanded/collapsed states for new inline records, if any
319 t3lib_TCEforms_inline::updateInlineView($this->uc, $tce);
320
321 $newEditConf = array();
322
323 foreach($this->editconf as $tableName => $tableCmds) {
324 $keys = array_keys($tce->substNEWwithIDs_table, $tableName);
325 if(count($keys) > 0) {
326 foreach($keys as $key) {
327 $editId = $tce->substNEWwithIDs[$key];
328 // check if the $editId isn't a child record of an IRRE action
329 if (!(is_array($tce->newRelatedIDs[$tableName]) && in_array($editId, $tce->newRelatedIDs[$tableName]))) {
330 // translate new id to the workspace version:
331 if ($versionRec = t3lib_BEfunc::getWorkspaceVersionOfRecord($GLOBALS['BE_USER']->workspace, $tableName, $editId,'uid')) {
332 $editId = $versionRec['uid'];
333 }
334 $newEditConf[$tableName][$editId] = 'edit';
335 }
336
337 // Traverse all new records and forge the content of ->editconf so we can continue to EDIT these records!
338 if ($tableName=='pages' && $this->retUrl!='dummy.php' && $this->returnNewPageId) {
339 $this->retUrl.='&id='.$tce->substNEWwithIDs[$key];
340 }
341 }
342 } else {
343 $newEditConf[$tableName] = $tableCmds;
344 }
345 }
346
347 // Resetting editconf if newEditConf has values:
348 if (count($newEditConf)) {
349 $this->editconf = $newEditConf;
350 }
351
352 // Finally, set the editconf array in the "getvars" so they will be passed along in URLs as needed.
353 $this->R_URL_getvars['edit']=$this->editconf;
354
355 // Unsetting default values since we don't need them anymore.
356 unset($this->R_URL_getvars['defVals']);
357
358 // Re-compile the store* values since editconf changed...
359 $this->compileStoreDat();
360 }
361
362 // See if any records was auto-created as new versions?
363 if (count($tce->autoVersionIdMap)) {
364 $this->fixWSversioningInEditConf($tce->autoVersionIdMap);
365 }
366
367 // If a document is saved and a new one is created right after.
368 if (isset($_POST['_savedoknew_x']) && is_array($this->editconf)) {
369
370 // Finding the current table:
371 reset($this->editconf);
372 $nTable=key($this->editconf);
373
374 // Finding the first id, getting the records pid+uid
375 reset($this->editconf[$nTable]);
376 $nUid=key($this->editconf[$nTable]);
377 $nRec = t3lib_BEfunc::getRecord($nTable,$nUid,'pid,uid');
378
379 // Setting a blank editconf array for a new record:
380 $this->editconf=array();
381 if ($this->getNewIconMode($nTable)=='top') {
382 $this->editconf[$nTable][$nRec['pid']]='new';
383 } else {
384 $this->editconf[$nTable][-$nRec['uid']]='new';
385 }
386
387 // Finally, set the editconf array in the "getvars" so they will be passed along in URLs as needed.
388 $this->R_URL_getvars['edit']=$this->editconf;
389
390 // Re-compile the store* values since editconf changed...
391 $this->compileStoreDat();
392 }
393
394 $tce->printLogErrorMessages(
395 isset($_POST['_saveandclosedok_x']) ?
396 $this->retUrl :
397 $this->R_URL_parts['path'].'?'.t3lib_div::implodeArrayForUrl('',$this->R_URL_getvars) // popView will not be invoked here, because the information from the submit button for save/view will be lost .... But does it matter if there is an error anyways?
398 );
399 }
400 if (isset($_POST['_saveandclosedok_x']) || $this->closeDoc<0) { // || count($tce->substNEWwithIDs)... If any new items has been save, the document is CLOSED because if not, we just get that element re-listed as new. And we don't want that!
401 $this->closeDocument(abs($this->closeDoc));
402 }
403 }
404
405 /**
406 * Initialize the normal module operation
407 *
408 * @return void
409 */
410 function init() {
411 global $BE_USER,$LANG,$BACK_PATH;
412
413 // Setting more GPvars:
414 $this->popViewId = t3lib_div::_GP('popViewId');
415 $this->popViewId_addParams = t3lib_div::_GP('popViewId_addParams');
416 $this->viewUrl = t3lib_div::_GP('viewUrl');
417 $this->editRegularContentFromId = t3lib_div::_GP('editRegularContentFromId');
418 $this->recTitle = t3lib_div::_GP('recTitle');
419 $this->disHelp = t3lib_div::_GP('disHelp');
420 $this->noView = t3lib_div::_GP('noView');
421
422 // Set other internal variables:
423 $this->R_URL_getvars['returnUrl']=$this->retUrl;
424 $this->R_URI = $this->R_URL_parts['path'].'?'.t3lib_div::implodeArrayForUrl('',$this->R_URL_getvars);
425
426 // MENU-ITEMS:
427 // If array, then it's a selector box menu
428 // If empty string it's just a variable, that'll be saved.
429 // Values NOT in this array will not be saved in the settings-array for the module.
430 $this->MOD_MENU = array(
431 'showPalettes' => '',
432 'showDescriptions' => '',
433 'disableRTE' => ''
434 );
435
436 // Setting virtual document name
437 $this->MCONF['name']='xMOD_alt_doc.php';
438
439 // CLEANSE SETTINGS
440 $this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), $this->MCONF['name']);
441
442 // Create an instance of the document template object
443 $this->doc = t3lib_div::makeInstance('mediumDoc');
444 $this->doc->bodyTagMargins['x']=5;
445 $this->doc->bodyTagMargins['y']=5;
446 $this->doc->backPath = $BACK_PATH;
447 $this->doc->docType = 'xhtml_trans';
448
449 $this->doc->form='<form action="'.htmlspecialchars($this->R_URI).'" method="post" enctype="'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'].'" name="editform" onsubmit="document.editform._scrollPosition.value=(document.documentElement.scrollTop || document.body.scrollTop); return TBE_EDITOR.checkSubmit(1);">';
450
451 $this->doc->JScode = $this->doc->wrapScriptTags('
452 function jumpToUrl(URL,formEl) { //
453 if (!TBE_EDITOR.isFormChanged()) {
454 window.location.href = URL;
455 } else if (formEl && formEl.type=="checkbox") {
456 formEl.checked = formEl.checked ? 0 : 1;
457 }
458 }
459
460 // Object: TS:
461 function typoSetup () { //
462 this.uniqueID = "";
463 }
464 var TS = new typoSetup();
465
466 // Info view:
467 function launchView(table,uid,bP) { //
468 var backPath= bP ? bP : "";
469 var thePreviewWindow="";
470 thePreviewWindow = window.open(backPath+"show_item.php?table="+encodeURIComponent(table)+"&uid="+encodeURIComponent(uid),"ShowItem"+TS.uniqueID,"height=300,width=410,status=0,menubar=0,resizable=0,location=0,directories=0,scrollbars=1,toolbar=0");
471 if (thePreviewWindow && thePreviewWindow.focus) {
472 thePreviewWindow.focus();
473 }
474 }
475 function deleteRecord(table,id,url) { //
476 if (
477 '.($GLOBALS['BE_USER']->jsConfirmation(4)?'confirm('.$LANG->JScharCode($LANG->getLL('deleteWarning')).')':'1==1').'
478 ) {
479 window.location.href = "tce_db.php?cmd["+table+"]["+id+"][delete]=1&redirect="+escape(url)+"&vC='.$BE_USER->veriCode().'&prErr=1&uPT=1";
480 }
481 return false;
482 }
483 '.(isset($_POST['_savedokview_x']) && $this->popViewId ?
484 'if (window.opener) { '.
485 t3lib_BEfunc::viewOnClick($this->popViewId,'',t3lib_BEfunc::BEgetRootLine($this->popViewId),'',$this->viewUrl,$this->popViewId_addParams,FALSE).
486 ' } else { '.
487 t3lib_BEfunc::viewOnClick($this->popViewId,'',t3lib_BEfunc::BEgetRootLine($this->popViewId),'',$this->viewUrl,$this->popViewId_addParams).
488 ' } '
489 : '')
490 ).$this->doc->getDynTabMenuJScode();
491
492 // Setting up the context sensitive menu:
493 $CMparts = $this->doc->getContextMenuCode();
494 $this->doc->JScode.= $CMparts[0];
495 $this->doc->bodyTagAdditions = str_replace('onload="','onload="window.scrollTo(0,'.t3lib_div::intInRange(t3lib_div::_GP('_scrollPosition'),0,10000).');',$CMparts[1]);
496 $this->doc->postCode.= $CMparts[2];
497 }
498
499 /**
500 * Main module operation
501 *
502 * @return void
503 */
504 function main() {
505 global $BE_USER,$LANG;
506
507 // Starting content accumulation:
508 $this->content='';
509 $this->content.=$this->doc->startPage('TYPO3 Edit Document');
510
511 // Begin edit:
512 if (is_array($this->editconf)) {
513
514 // Initialize TCEforms (rendering the forms)
515 $this->tceforms = t3lib_div::makeInstance('t3lib_TCEforms');
516 $this->tceforms->initDefaultBEMode();
517 $this->tceforms->doSaveFieldName = 'doSave';
518 $this->tceforms->localizationMode = t3lib_div::inList('text,media',$this->localizationMode) ? $this->localizationMode : ''; // text,media is keywords defined in TYPO3 Core API..., see "l10n_cat"
519 $this->tceforms->returnUrl = $this->R_URI;
520 $this->tceforms->palettesCollapsed = !$this->MOD_SETTINGS['showPalettes'];
521 $this->tceforms->disableRTE = $this->MOD_SETTINGS['disableRTE'];
522 $this->tceforms->enableClickMenu = TRUE;
523 $this->tceforms->enableTabMenu = TRUE;
524
525 // Clipboard is initialized:
526 $this->tceforms->clipObj = t3lib_div::makeInstance('t3lib_clipboard'); // Start clipboard
527 $this->tceforms->clipObj->initializeClipboard(); // Initialize - reads the clipboard content from the user session
528
529 // Setting external variables:
530 if ($BE_USER->uc['edit_showFieldHelp']!='text' && $this->MOD_SETTINGS['showDescriptions']) $this->tceforms->edit_showFieldHelp='text';
531
532 if ($this->editRegularContentFromId) {
533 $this->editRegularContentFromId();
534 }
535
536 // Creating the editing form, wrap it with buttons, document selector etc.
537 $editForm = $this->makeEditForm();
538
539 if ($editForm) {
540 reset($this->elementsData);
541 $this->firstEl = current($this->elementsData);
542
543 // language switch/selector for editing
544 // show only when a single record is edited - multiple records are too confusing
545 if (count($this->elementsData)==1) {
546 $languageSwitch = $this->languageSwitch($this->firstEl['table'], $this->firstEl['uid'], $this->firstEl['pid']);
547 }
548
549
550 if ($this->viewId) {
551 // Module configuration:
552 $this->modTSconfig = t3lib_BEfunc::getModTSconfig($this->viewId,'mod.xMOD_alt_doc');
553 } else $this->modTSconfig=array();
554
555 $panel = $this->makeButtonPanel();
556 $docSel = $this->makeDocSel();
557 $cMenu = $this->makeCmenu();
558
559 $formContent = $this->compileForm($panel,$docSel,$cMenu,$editForm,$languageSwitch);
560
561 $this->content.= $this->tceforms->printNeededJSFunctions_top().
562 $formContent.
563 $this->tceforms->printNeededJSFunctions();
564 $this->content.= $this->functionMenus();
565
566 // Add CSH:
567 $this->content.= t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'TCEforms', $GLOBALS['BACK_PATH'],'<br/>|',FALSE,'margin-top: 20px;');
568
569 $this->content.= $this->shortCutLink();
570
571 $this->tceformMessages();
572 }
573 }
574 }
575
576
577 /**
578 * Outputting the accumulated content to screen
579 *
580 * @return void
581 */
582 function printContent() {
583 $this->content.= $this->doc->endPage();
584 $this->content = $this->doc->insertStylesAndJS($this->content);
585 echo $this->content;
586 }
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607 /***************************
608 *
609 * Sub-content functions, rendering specific parts of the module content.
610 *
611 ***************************/
612
613 /**
614 * Creates the editing form with TCEforms, based on the input from GPvars.
615 *
616 * @return string HTML form elements wrapped in tables
617 */
618 function makeEditForm() {
619 global $BE_USER,$LANG,$TCA;
620
621 // Initialize variables:
622 $this->elementsData=array();
623 $this->errorC=0;
624 $this->newC=0;
625 $thePrevUid='';
626 $editForm='';
627
628 // Traverse the GPvar edit array
629 foreach($this->editconf as $table => $conf) { // Tables:
630 if (is_array($conf) && $TCA[$table] && $BE_USER->check('tables_modify',$table)) {
631
632 // Traverse the keys/comments of each table (keys can be a commalist of uids)
633 foreach($conf as $cKey => $cmd) {
634 if ($cmd=='edit' || $cmd=='new') {
635
636 // Get the ids:
637 $ids = t3lib_div::trimExplode(',',$cKey,1);
638
639 // Traverse the ids:
640 foreach($ids as $theUid) {
641
642 // Checking if the user has permissions? (Only working as a precaution, because the final permission check is always down in TCE. But it's good to notify the user on beforehand...)
643 // First, resetting flags.
644 $hasAccess = 1;
645 $deniedAccessReason = '';
646 $deleteAccess = 0;
647 $this->viewId = 0;
648
649 // If the command is to create a NEW record...:
650 if ($cmd=='new') {
651 if (intval($theUid)) { // NOTICE: the id values in this case points to the page uid onto which the record should be create OR (if the id is negativ) to a record from the same table AFTER which to create the record.
652
653 // Find parent page on which the new record reside
654 if ($theUid<0) { // Less than zero - find parent page
655 $calcPRec=t3lib_BEfunc::getRecord($table,abs($theUid));
656 $calcPRec=t3lib_BEfunc::getRecord('pages',$calcPRec['pid']);
657 } else { // always a page
658 $calcPRec=t3lib_BEfunc::getRecord('pages',abs($theUid));
659 }
660
661 // Now, calculate whether the user has access to creating new records on this position:
662 if (is_array($calcPRec)) {
663 $CALC_PERMS = $BE_USER->calcPerms($calcPRec); // Permissions for the parent page
664 if ($table=='pages') { // If pages:
665 $hasAccess = $CALC_PERMS&8 ? 1 : 0;
666 $this->viewId = $calcPRec['pid'];
667 } else {
668 $hasAccess = $CALC_PERMS&16 ? 1 : 0;
669 $this->viewId = $calcPRec['uid'];
670 }
671 }
672 }
673 $this->dontStoreDocumentRef=1; // Don't save this document title in the document selector if the document is new.
674 } else { // Edit:
675 $calcPRec = t3lib_BEfunc::getRecord($table,$theUid);
676 t3lib_BEfunc::fixVersioningPid($table,$calcPRec);
677 if (is_array($calcPRec)) {
678 if ($table=='pages') { // If pages:
679 $CALC_PERMS = $BE_USER->calcPerms($calcPRec);
680 $hasAccess = $CALC_PERMS&2 ? 1 : 0;
681 $deleteAccess = $CALC_PERMS&4 ? 1 : 0;
682 $this->viewId = $calcPRec['uid'];
683 } else {
684 $CALC_PERMS = $BE_USER->calcPerms(t3lib_BEfunc::getRecord('pages',$calcPRec['pid'])); // Fetching pid-record first.
685 $hasAccess = $CALC_PERMS&16 ? 1 : 0;
686 $deleteAccess = $CALC_PERMS&16 ? 1 : 0;
687 $this->viewId = $calcPRec['pid'];
688
689 // Adding "&L=xx" if the record being edited has a languageField with a value larger than zero!
690 if ($TCA[$table]['ctrl']['languageField'] && $calcPRec[$TCA[$table]['ctrl']['languageField']]>0) {
691 $this->viewId_addParams = '&L='.$calcPRec[$TCA[$table]['ctrl']['languageField']];
692 }
693 }
694
695 // Check internals regarding access:
696 if ($hasAccess) {
697 $hasAccess = $BE_USER->recordEditAccessInternals($table, $calcPRec);
698 $deniedAccessReason = $BE_USER->errorMsg;
699 }
700 } else $hasAccess = 0;
701 }
702
703 // AT THIS POINT we have checked the access status of the editing/creation of records and we can now proceed with creating the form elements:
704
705 if ($hasAccess) {
706 $prevPageID = is_object($trData)?$trData->prevPageID:'';
707 $trData = t3lib_div::makeInstance('t3lib_transferData');
708 $trData->addRawData = TRUE;
709 $trData->defVals = $this->defVals;
710 $trData->lockRecords=1;
711 $trData->disableRTE = $this->MOD_SETTINGS['disableRTE'];
712 $trData->prevPageID = $prevPageID;
713 $trData->fetchRecord($table,$theUid,$cmd=='new'?'new':''); // 'new'
714 reset($trData->regTableItems_data);
715 $rec = current($trData->regTableItems_data);
716 $rec['uid'] = $cmd=='new' ? uniqid('NEW') : $theUid;
717 if ($cmd=='new') {
718 $rec['pid'] = $theUid=='prev'?$thePrevUid:$theUid;
719 }
720 $this->elementsData[]=array(
721 'table' => $table,
722 'uid' => $rec['uid'],
723 'pid' => $rec['pid'],
724 'cmd' => $cmd,
725 'deleteAccess' => $deleteAccess
726 );
727
728 // Now, render the form:
729 if (is_array($rec)) {
730
731 // Setting visual path / title of form:
732 $this->generalPathOfForm = $this->tceforms->getRecordPath($table,$rec);
733 if (!$this->storeTitle) {
734 $this->storeTitle = $this->recTitle ? htmlspecialchars($this->recTitle) : t3lib_BEfunc::getRecordTitle($table,$rec,TRUE);
735 }
736
737 // Setting variables in TCEforms object:
738 $this->tceforms->hiddenFieldList = '';
739 $this->tceforms->globalShowHelp = $this->disHelp ? 0 : 1;
740 if (is_array($this->overrideVals[$table])) {
741 $this->tceforms->hiddenFieldListArr = array_keys($this->overrideVals[$table]);
742 }
743
744 // Register default language labels, if any:
745 $this->tceforms->registerDefaultLanguageData($table,$rec);
746
747 // Create form for the record (either specific list of fields or the whole record):
748 $panel = '';
749 if ($this->columnsOnly) {
750 if(is_array($this->columnsOnly)){
751 $panel.= $this->tceforms->getListedFields($table,$rec,$this->columnsOnly[$table]);
752 } else {
753 $panel.= $this->tceforms->getListedFields($table,$rec,$this->columnsOnly);
754 }
755 } else {
756 $panel.= $this->tceforms->getMainFields($table,$rec);
757 }
758 $panel = $this->tceforms->wrapTotal($panel,$rec,$table);
759
760 // Setting the pid value for new records:
761 if ($cmd=='new') {
762 $panel.= '<input type="hidden" name="data['.$table.']['.$rec['uid'].'][pid]" value="'.$rec['pid'].'" />';
763 $this->newC++;
764 }
765
766 // Display "is-locked" message:
767 if ($lockInfo = t3lib_BEfunc::isRecordLocked($table,$rec['uid'])) {
768 $lockIcon = '
769
770 <!--
771 Warning box:
772 -->
773 <table border="0" cellpadding="0" cellspacing="0" class="warningbox">
774 <tr>
775 <td><img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/recordlock_warning3.gif','width="17" height="12"').' alt="" /></td>
776 <td>'.htmlspecialchars($lockInfo['msg']).'</td>
777 </tr>
778 </table>
779 ';
780 } else $lockIcon = '';
781
782 // Combine it all:
783 $editForm.= $lockIcon.$panel;
784 }
785
786 $thePrevUid = $rec['uid'];
787 } else {
788 $this->errorC++;
789 $editForm.=$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.noEditPermission',1).'<br /><br />'.
790 ($deniedAccessReason ? 'Reason: '.htmlspecialchars($deniedAccessReason).'<br/><br/>' : '');
791 }
792 }
793 }
794 }
795 }
796 }
797
798 return $editForm;
799 }
800
801 /**
802 * Create the panel of buttons for submitting the form or otherwise perform operations.
803 *
804 * @return string HTML code, comprised of images linked to various actions.
805 */
806 function makeButtonPanel() {
807 global $TCA,$LANG;
808
809 $panel='';
810
811 // Render SAVE type buttons:
812 // The action of each button is decided by its name attribute. (See doProcessData())
813 if (!$this->errorC && !$TCA[$this->firstEl['table']]['ctrl']['readOnly']) {
814
815 // SAVE button:
816 $panel.= '<input type="image" class="c-inputButton" name="_savedok"'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/savedok.gif','').' title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:rm.saveDoc',1).'" />';
817
818 // SAVE / VIEW button:
819 if ($this->viewId && !$this->noView && t3lib_extMgm::isLoaded('cms')) {
820 $panel.= '<input type="image" class="c-inputButton" name="_savedokview"'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/savedokshow.gif','').' title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:rm.saveDocShow',1).'" />';
821 }
822
823 // SAVE / NEW button:
824 if (count($this->elementsData)==1 && $this->getNewIconMode($this->firstEl['table'])) {
825 $panel.= '<input type="image" class="c-inputButton" name="_savedoknew"'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/savedoknew.gif','').' title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:rm.saveNewDoc',1).'" />';
826 }
827
828 // SAVE / CLOSE
829 $panel.= '<input type="image" class="c-inputButton" name="_saveandclosedok"'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/saveandclosedok.gif','').' title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:rm.saveCloseDoc',1).'" />';
830 }
831
832 // CLOSE button:
833 $panel.= '<a href="#" onclick="document.editform.closeDoc.value=1; document.editform.submit(); return false;">'.
834 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/closedok.gif','width="21" height="16"').' class="c-inputButton" title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:rm.closeDoc',1).'" alt="" />'.
835 '</a>';
836
837 // DELETE + UNDO buttons:
838 if (!$this->errorC && !$TCA[$this->firstEl['table']]['ctrl']['readOnly'] && count($this->elementsData)==1) {
839 if ($this->firstEl['cmd']!='new' && t3lib_div::testInt($this->firstEl['uid'])) {
840
841 // Delete:
842 if ($this->firstEl['deleteAccess'] && !$TCA[$this->firstEl['table']]['ctrl']['readOnly'] && !$this->getNewIconMode($this->firstEl['table'],'disableDelete')) {
843 $aOnClick = 'return deleteRecord(\''.$this->firstEl['table'].'\',\''.$this->firstEl['uid'].'\',unescape(\''.rawurlencode($this->retUrl).'\'));';
844 $panel.= '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.
845 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/deletedok.gif','width="21" height="16"').' class="c-inputButton" title="'.$LANG->getLL('deleteItem',1).'" alt="" />'.
846 '</a>';
847 }
848
849 // Undo:
850 $undoButton = 0;
851 $undoRes = $GLOBALS['TYPO3_DB']->exec_SELECTquery('tstamp', 'sys_history', 'tablename='.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->firstEl['table'], 'sys_history').' AND recuid='.intval($this->firstEl['uid']), '', 'tstamp DESC', '1');
852 if ($undoButtonR = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($undoRes)) {
853 $undoButton = 1;
854 }
855 if ($undoButton) {
856 $aOnClick = 'window.location.href=\'show_rechis.php?element='.rawurlencode($this->firstEl['table'].':'.$this->firstEl['uid']).'&revert=ALL_FIELDS&sumUp=-1&returnUrl='.rawurlencode($this->R_URI).'\'; return false;';
857 $panel.= '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.
858 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/undo.gif','width="21" height="16"').' class="c-inputButton" title="'.htmlspecialchars(sprintf($LANG->getLL('undoLastChange'),t3lib_BEfunc::calcAge(time()-$undoButtonR['tstamp'],$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears')))).'" alt="" />'.
859 '</a>';
860 }
861 if ($this->getNewIconMode($this->firstEl['table'],'showHistory')) {
862 $aOnClick = 'window.location.href=\'show_rechis.php?element='.rawurlencode($this->firstEl['table'].':'.$this->firstEl['uid']).'&returnUrl='.rawurlencode($this->R_URI).'\'; return false;';
863 $panel.= '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.
864 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/history2.gif','width="13" height="12"').' class="c-inputButton" alt="" />'.
865 '</a>';
866 }
867
868 // If only SOME fields are shown in the form, this will link the user to the FULL form:
869 if ($this->columnsOnly) {
870 $panel.= '<a href="'.htmlspecialchars($this->R_URI.'&columnsOnly=').'">'.
871 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/edit2.gif','width="11" height="12"').' class="c-inputButton" title="'.$LANG->getLL('editWholeRecord',1).'" alt="" />'.
872 '</a>';
873 }
874 }
875 }
876 return $panel;
877 }
878
879 /**
880 * Create the selector box form element which allows to select between open documents.
881 * Can be disabled through Page TSconfig.
882 *
883 * @return string HTML <select> element (if applicable)
884 */
885 function makeDocSel() {
886 global $BE_USER,$LANG;
887
888 // Render the selector ONLY if it has not been disabled:
889 if (!$this->modTSconfig['properties']['disableDocSelector']) {
890
891 // Checking if the currently open document is stored in the list of "open documents" - if not, then add it:
892 if ((strcmp($this->docDat[1],$this->storeUrlMd5)||!isset($this->docHandler[$this->storeUrlMd5])) && !$this->dontStoreDocumentRef) {
893 $this->docHandler[$this->storeUrlMd5]=array($this->storeTitle,$this->storeArray,$this->storeUrl);
894 $BE_USER->pushModuleData('alt_doc.php',array($this->docHandler,$this->storeUrlMd5));
895 }
896
897 // Now, create the document selector box:
898 $docSel='';
899 if (is_array($this->docHandler)) {
900 $opt = array();
901 $opt[] = '<option value="">[ '.$LANG->getLL('openDocs',1).': ]</option>';
902
903 // Traverse the list of open documents:
904 foreach($this->docHandler as $md5k => $setupArr) {
905 $theValue = 'alt_doc.php?'.$setupArr[2].'&returnUrl='.rawurlencode($this->retUrl);
906 $opt[]='<option value="'.htmlspecialchars($theValue).'"'.(!strcmp($md5k,$this->storeUrlMd5)?' selected="selected"':'').'>'.htmlspecialchars(strip_tags(t3lib_div::htmlspecialchars_decode($setupArr[0]))).'</option>';
907 }
908
909 // Compile the selector box finally:
910 $onChange = 'if(this.options[this.selectedIndex].value && !TBE_EDITOR.isFormChanged()){window.location.href=(this.options[this.selectedIndex].value);}';
911 $docSel='<select name="_docSelector" onchange="'.htmlspecialchars($onChange).'">'.implode('',$opt).'</select>';
912
913 // Add CSH:
914 $docSel.=t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'TCEforms_docSelector', $GLOBALS['BACK_PATH'],'', TRUE);
915 }
916 } else $docSel='';
917 return $docSel;
918 }
919
920 /**
921 * Create the selector box form element which allows to select a clear-cache operation.
922 * Can be disabled through Page TSconfig.
923 *
924 * @return string HTML <select> element (if applicable)
925 * @see template::clearCacheMenu()
926 */
927 function makeCmenu() {
928
929 // Generate the menu if NOT disabled:
930 if (!$this->modTSconfig['properties']['disableCacheSelector']) {
931 $cMenu = $this->doc->clearCacheMenu(intval($this->viewId),!$this->modTSconfig['properties']['disableDocSelector']);
932
933 // Add CSH:
934 $cMenu.=t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'TCEforms_cacheSelector', $GLOBALS['BACK_PATH'],'', TRUE);
935 } else $cMenu ='';
936 return $cMenu;
937 }
938
939 /**
940 * Put together the various elements (buttons, selectors, form) into a table
941 *
942 * @param string The button panel HTML
943 * @param string Document selector HTML
944 * @param string Clear-cache menu HTML
945 * @param string HTML form.
946 * @param string Language selector HTML for localization
947 * @return string Composite HTML
948 */
949 function compileForm($panel,$docSel,$cMenu,$editForm, $langSelector='') {
950 global $LANG;
951
952
953 $formContent='';
954 $formContent.='
955
956 <!--
957 Header of the editing page.
958 Contains the buttons for saving/closing, the document selector and menu selector.
959 Shows the path of the editing operation as well.
960 -->
961 <table border="0" cellpadding="0" cellspacing="1" width="470" id="typo3-altdoc-header">
962 <tr>
963 <td nowrap="nowrap" valign="top"><div class="bgColor4" style="position:fixed; padding: 5px 5px 5px 5px; border: 1px solid black;">'.$panel.'</div></td>
964 <td nowrap="nowrap" valign="top" align="right">'.$docSel.$cMenu.'</td>
965 </tr>';
966
967 if ($langSelector) {
968 $langSelector ='<div id="typo3-altdoc-lang-selector">'.$langSelector.'</div>';
969 }
970
971 if (is_array($this->tceforms->extraFormHeaders)) {
972 $formContent .= implode(chr(10), $this->tceforms->extraFormHeaders);
973 }
974
975 $pagePath = '<div id="typo3-altdoc-page-path">'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.path',1).': '.htmlspecialchars($this->generalPathOfForm).'</div>';
976
977 $formContent.='
978 <tr>
979 <td colspan="2"><div id="typo3-altdoc-header-info-options">'.$pagePath.$langSelector.'</div></td>
980 </tr>
981 </table>
982
983
984
985
986 <!--
987 EDITING FORM:
988 -->
989
990 '.$editForm.'
991
992
993
994 <!--
995 Saving buttons (same as in top)
996 -->
997
998 '.$panel.
999 '<input type="hidden" name="returnUrl" value="'.htmlspecialchars($this->retUrl).'" />
1000 <input type="hidden" name="viewUrl" value="'.htmlspecialchars($this->viewUrl).'" />';
1001
1002 if ($this->returnNewPageId) {
1003 $formContent.='<input type="hidden" name="returnNewPageId" value="1" />';
1004 }
1005 $formContent.='<input type="hidden" name="popViewId" value="'.htmlspecialchars($this->viewId).'" />';
1006 if ($this->viewId_addParams) {
1007 $formContent.='<input type="hidden" name="popViewId_addParams" value="'.htmlspecialchars($this->viewId_addParams).'" />';
1008 }
1009 $formContent.='<input type="hidden" name="closeDoc" value="0" />';
1010 $formContent.='<input type="hidden" name="doSave" value="0" />';
1011 $formContent.='<input type="hidden" name="_serialNumber" value="'.md5(microtime()).'" />';
1012 $formContent.='<input type="hidden" name="_disableRTE" value="'.$this->tceforms->disableRTE.'" />';
1013 $formContent.='<input type="hidden" name="_scrollPosition" value="" />';
1014
1015 return $formContent;
1016 }
1017
1018 /**
1019 * Create the checkbox buttons in the bottom of the pages.
1020 *
1021 * @return string HTML for function menus.
1022 */
1023 function functionMenus() {
1024 global $BE_USER,$LANG;
1025
1026 $funcMenus = '';
1027
1028 // Show palettes:
1029 $funcMenus.= '<br /><br />'.t3lib_BEfunc::getFuncCheck('','SET[showPalettes]',$this->MOD_SETTINGS['showPalettes'],'alt_doc.php',t3lib_div::implodeArrayForUrl('',array_merge($this->R_URL_getvars,array('SET'=>''))),'id="checkShowPalettes"').'<label for="checkShowPalettes">'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.showPalettes',1).'</label>';
1030
1031 // Show descriptions/help texts:
1032 if ($BE_USER->uc['edit_showFieldHelp']!='text') {
1033 $funcMenus.= '<br />'.t3lib_BEfunc::getFuncCheck('','SET[showDescriptions]',$this->MOD_SETTINGS['showDescriptions'],'alt_doc.php',t3lib_div::implodeArrayForUrl('',array_merge($this->R_URL_getvars,array('SET'=>''))),'id="checkShowDescriptions"').'<label for="checkShowDescriptions">'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.showDescriptions',1).'</label>';
1034 }
1035
1036 // Show disable RTE checkbox:
1037 if ($BE_USER->isRTE()) {
1038 $funcMenus.= '<br />'.t3lib_BEfunc::getFuncCheck('','SET[disableRTE]',$this->MOD_SETTINGS['disableRTE'],'alt_doc.php',t3lib_div::implodeArrayForUrl('',array_merge($this->R_URL_getvars,array('SET'=>''))),'id="checkDisableRTE"').'<label for="checkDisableRTE">'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.disableRTE',1).'</label>';
1039 }
1040
1041 return '
1042
1043 <!--
1044 Function menus (checkboxes for selecting options):
1045 -->
1046 '.$funcMenus;
1047 }
1048
1049 /**
1050 * Create shortcut and open-in-window link in the bottom of the page
1051 *
1052 * @return string
1053 */
1054 function shortCutLink() {
1055 global $BE_USER,$LANG;
1056
1057 // ShortCut
1058 if ($this->returnUrl!='close.html') {
1059 $content.='<br /><br />';
1060
1061 // Shortcut:
1062 if ($BE_USER->mayMakeShortcut()) {
1063 $content.=$this->doc->makeShortcutIcon('returnUrl,edit,defVals,overrideVals,columnsOnly,returnNewPageId,editRegularContentFromId,disHelp,noView',implode(',',array_keys($this->MOD_MENU)),$this->MCONF['name'],1);
1064 }
1065
1066 // Open in new window:
1067 $aOnClick = 'vHWin=window.open(\''.t3lib_div::linkThisScript(array('returnUrl'=>'close.html')).'\',\''.md5($this->R_URI).'\',\''.($BE_USER->uc['edit_wideDocument']?'width=670,height=500':'width=600,height=400').',status=0,menubar=0,scrollbars=1,resizable=1\');vHWin.focus();return false;';
1068 $content.='<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.
1069 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/open_in_new_window.gif','width="19" height="14"').' title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.openInNewWindow',1).'" alt="" />'.
1070 '</a>';
1071 }
1072 return '
1073
1074 <!--
1075 Shortcut link:
1076 -->
1077 '.$content;
1078 }
1079
1080 /**
1081 * Reads comment messages from TCEforms and prints them in a HTML comment in the buttom of the page.
1082 *
1083 * @return void
1084 */
1085 function tceformMessages() {
1086 if (count($this->tceforms->commentMessages)) {
1087 $this->content.='
1088
1089 <!-- TCEFORM messages
1090 '.htmlspecialchars(implode(chr(10),$this->tceforms->commentMessages)).'
1091 -->
1092
1093 ';
1094 }
1095 }
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109 /***************************
1110 *
1111 * Localization stuff
1112 *
1113 ***************************/
1114
1115 /**
1116 * Make selector box for creating new translation for a record or switching to edit the record in an existing language.
1117 * Displays only languages which are available for the current page.
1118 *
1119 * @param string Table name
1120 * @param integer uid for which to create a new language
1121 * @param integer pid of the record
1122 * @return string <select> HTML element (if there were items for the box anyways...)
1123 */
1124 function languageSwitch($table, $uid, $pid=NULL) {
1125 global $TCA;
1126
1127 $content = '';
1128
1129 $languageField = $TCA[$table]['ctrl']['languageField'];
1130 $transOrigPointerField = $TCA[$table]['ctrl']['transOrigPointerField'];
1131
1132 // table editable and activated for languages?
1133 if ($GLOBALS['BE_USER']->check('tables_modify',$table) && $languageField && $transOrigPointerField && !$TCA[$table]['ctrl']['transOrigPointerTable']) {
1134
1135 if(is_null($pid)) {
1136 $row = t3lib_befunc::getRecord($table, $uid, 'pid');
1137 $pid = $row['pid'];
1138 }
1139
1140 // get all avalibale languages for the page
1141 $langRows = $this->getLanguages($pid);
1142
1143 // page available in other languages than default language?
1144 if (is_array($langRows) && count($langRows)>1) {
1145
1146 $rowsByLang = array();
1147 $fetchFields = 'uid,'.$languageField.','.$transOrigPointerField;
1148
1149 // get record in current language
1150 $rowCurrent = t3lib_befunc::getRecord($table, $uid, $fetchFields);
1151 $currentLanguage = $rowCurrent[$languageField];
1152
1153 if ($currentLanguage>-1) { // Disabled for records with [all] language!
1154 // get record in default language if needed
1155 if ($currentLanguage) {
1156 $rowsByLang[0] = t3lib_befunc::getRecord($table, $rowCurrent[$transOrigPointerField], $fetchFields);
1157 } else {
1158 $rowsByLang[0] = $rowCurrent;
1159 }
1160
1161 // get record in other languages to see what's already available
1162 $translations = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
1163 $fetchFields,
1164 $table,
1165 'pid='.intval($pid).
1166 ' AND '.$languageField.'>0'.
1167 ' AND '.$transOrigPointerField.'='.intval($rowsByLang[0]['uid']).
1168 t3lib_BEfunc::deleteClause($table).
1169 t3lib_BEfunc::versioningPlaceholderClause($table)
1170 );
1171 foreach ($translations as $row) {
1172 $rowsByLang[$row[$languageField]] = $row;
1173 }
1174
1175 $langSelItems=array();
1176 foreach ($langRows as $lang) {
1177 if ($GLOBALS['BE_USER']->checkLanguageAccess($lang['uid'])) {
1178
1179 $newTranslation = isset($rowsByLang[$lang['uid']]) ? '' : ' ['.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:labels.new',1).']';
1180
1181 // create url for creating a localized record
1182 if($newTranslation) {
1183 $href = $this->doc->issueCommand(
1184 '&cmd['.$table.']['.$rowsByLang[0]['uid'].'][localize]='.$lang['uid'],
1185 $this->backPath.'alt_doc.php?justLocalized='.rawurlencode($table.':'.$rowsByLang[0]['uid'].':'.$lang['uid']).'&returnUrl='.rawurlencode($this->retUrl)
1186 );
1187
1188 // create edit url
1189 } else {
1190 $href = $this->backPath.'alt_doc.php?';
1191 $href .= '&edit['.$table.']['.$rowsByLang[$lang['uid']]['uid'].']=edit';
1192 $href .= '&returnUrl='.rawurlencode($this->retUrl);
1193 }
1194
1195 $langSelItems[$lang['uid']]='
1196 <option value="'.htmlspecialchars($href).'"'.($currentLanguage==$lang['uid']?' selected="selected"':'').'>'.htmlspecialchars($lang['title'].$newTranslation).'</option>';
1197 }
1198 }
1199
1200 // If any languages are left, make selector:
1201 if (count($langSelItems)>1) {
1202 $onChange = 'if(this.options[this.selectedIndex].value){window.location.href=(this.options[this.selectedIndex].value);}';
1203 $content = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_general.xml:LGL.language',1).' <select name="_langSelector" onchange="'.htmlspecialchars($onChange).'">
1204 '.implode('',$langSelItems).'
1205 </select>';
1206 }
1207 }
1208 }
1209 }
1210 return $content;
1211 }
1212
1213
1214 /**
1215 * Redirects to alt_doc with new parameters to edit a just created localized record
1216 *
1217 * @param string String passed by GET &justLocalized=
1218 * @return void
1219 */
1220 function localizationRedirect($justLocalized) {
1221 global $TCA;
1222
1223 list($table,$orig_uid,$language) = explode(':',$justLocalized);
1224
1225 if ($TCA[$table] && $TCA[$table]['ctrl']['languageField'] && $TCA[$table]['ctrl']['transOrigPointerField']) {
1226 list($localizedRecord) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
1227 'uid',
1228 $table,
1229 $TCA[$table]['ctrl']['languageField'].'='.intval($language).' AND '.
1230 $TCA[$table]['ctrl']['transOrigPointerField'].'='.intval($orig_uid).
1231 t3lib_BEfunc::deleteClause($table).
1232 t3lib_BEfunc::versioningPlaceholderClause($table)
1233 );
1234
1235 if (is_array($localizedRecord)) {
1236 // Create parameters and finally run the classic page module for creating a new page translation
1237 $params = '&edit['.$table.']['.$localizedRecord['uid'].']=edit';
1238 $returnUrl = '&returnUrl='.rawurlencode(t3lib_div::_GP('returnUrl'));
1239 $location = $GLOBALS['BACK_PATH'].'alt_doc.php?'.$params.$returnUrl;
1240
1241 header('Location: '.t3lib_div::locationHeaderUrl($location));
1242 exit;
1243 }
1244 }
1245 }
1246
1247
1248 /**
1249 * Returns sys_language records.
1250 *
1251 * @param integer Page id: If zero, the query will select all sys_language records from root level which are NOT hidden. If set to another value, the query will select all sys_language records that has a pages_language_overlay record on that page (and is not hidden, unless you are admin user)
1252 * @return array Language records including faked record for default language
1253 */
1254 function getLanguages($id) {
1255 global $LANG;
1256
1257 $modSharedTSconfig = t3lib_BEfunc::getModTSconfig($id, 'mod.SHARED');
1258
1259 $languages = array(
1260 0 => array(
1261 'uid' => 0,
1262 'pid' => 0,
1263 'hidden' => 0,
1264 'title' => strlen($modSharedTSconfig['properties']['defaultLanguageLabel']) ? $modSharedTSconfig['properties']['defaultLanguageLabel'].' ('.$GLOBALS['LANG']->sl('LLL:EXT:lang/locallang_mod_web_list.xml:defaultLanguage').')' : $GLOBALS['LANG']->sl('LLL:EXT:lang/locallang_mod_web_list.xml:defaultLanguage'),
1265 'flag' => $modSharedTSconfig['properties']['defaultLanguageFlag'],
1266 )
1267 );
1268
1269 $exQ = $GLOBALS['BE_USER']->isAdmin() ? '' : ' AND sys_language.hidden=0';
1270 if ($id) {
1271 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
1272 'sys_language.*',
1273 'pages_language_overlay,sys_language',
1274 'pages_language_overlay.sys_language_uid=sys_language.uid AND pages_language_overlay.pid='.intval($id).$exQ,
1275 'pages_language_overlay.sys_language_uid,sys_language.uid,sys_language.pid,sys_language.tstamp,sys_language.hidden,sys_language.title,sys_language.static_lang_isocode,sys_language.flag',
1276 'sys_language.title'
1277 );
1278 } else {
1279 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
1280 'sys_language.*',
1281 'sys_language',
1282 'sys_language.hidden=0',
1283 '',
1284 'sys_language.title'
1285 );
1286 }
1287 if ($rows) {
1288 foreach ($rows as $row) {
1289 $languages[$row['uid']] = $row;
1290 }
1291 }
1292 return $languages;
1293 }
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304 /***************************
1305 *
1306 * Other functions
1307 *
1308 ***************************/
1309
1310 /**
1311 * Fix $this->editconf if versioning applies to any of the records
1312 *
1313 * @param array Mapping between old and new ids if auto-versioning has been performed.
1314 * @return void
1315 */
1316 function fixWSversioningInEditConf($mapArray=FALSE) {
1317 global $TCA,$BE_USER;
1318
1319 // Traverse the editConf array
1320 if (is_array($this->editconf)) {
1321 foreach($this->editconf as $table => $conf) { // Tables:
1322 if (is_array($conf) && $TCA[$table]) {
1323
1324 // Traverse the keys/comments of each table (keys can be a commalist of uids)
1325 $newConf = array();
1326 foreach($conf as $cKey => $cmd) {
1327 if ($cmd=='edit') {
1328 // Traverse the ids:
1329 $ids = t3lib_div::trimExplode(',', $cKey, 1);
1330 foreach($ids as $idKey => $theUid) {
1331 if (is_array($mapArray)) {
1332 if ($mapArray[$table][$theUid]) {
1333 $ids[$idKey] = $mapArray[$table][$theUid];
1334 }
1335 } else { // Default, look for versions in workspace for record:
1336 $calcPRec = $this->getRecordForEdit($table,$theUid);
1337 if (is_array($calcPRec)) {
1338 // Setting UID again if it had changed, eg. due to workspace versioning.
1339 $ids[$idKey] = $calcPRec['uid'];
1340 }
1341 }
1342 #else unset($ids[$idKey]);
1343 }
1344
1345 // Add the possibly manipulated IDs to the new-build newConf array:
1346 $newConf[implode(',',$ids)] = $cmd;
1347 } else {
1348 $newConf[$cKey] = $cmd;
1349 }
1350 }
1351 // Store the new conf array:
1352 $this->editconf[$table] = $newConf;
1353 }
1354 }
1355 }
1356 }
1357
1358 /**
1359 * Get record for editing.
1360 *
1361 * @param string Table name
1362 * @param integer Record UID
1363 * @return array Returns record to edit, false if none
1364 */
1365 function getRecordForEdit($table,$theUid) {
1366 global $TCA;
1367
1368 // Fetch requested record:
1369 $reqRecord = t3lib_BEfunc::getRecord($table,$theUid,'uid,pid');
1370
1371 if (is_array($reqRecord)) {
1372 // If workspace is OFFLINE:
1373 if ($GLOBALS['BE_USER']->workspace!=0) {
1374
1375 // Check for versioning support of the table:
1376 if ($TCA[$table] && $TCA[$table]['ctrl']['versioningWS']) {
1377
1378 // If the record is already a version of "something" pass it by.
1379 if ($reqRecord['pid']==-1) {
1380
1381 // (If it turns out not to be a version of the current workspace there will be trouble, but that is handled inside TCEmain then and in the interface it would clearly be an error of links if the user accesses such a scenario)
1382 return $reqRecord;
1383 } else { // The input record was online and an offline version must be found or made:
1384
1385 // Look for version of this workspace:
1386 $versionRec = t3lib_BEfunc::getWorkspaceVersionOfRecord($GLOBALS['BE_USER']->workspace, $table, $reqRecord['uid'],'uid,pid,t3ver_oid');
1387 return is_array($versionRec) ? $versionRec : $reqRecord;
1388 }
1389 } else return FALSE; // This means that editing cannot occur on this record because it was not supporting versioning which is required inside an offline workspace.
1390 } else return $reqRecord; // In ONLINE workspace, just return the originally requested record:
1391 } else return FALSE; // Return false because the table/uid was not found anyway.
1392 }
1393
1394 /**
1395 * Function, which populates the internal editconf array with editing commands for all tt_content elements from the normal column in normal language from the page pointed to by $this->editRegularContentFromId
1396 *
1397 * @return void
1398 */
1399 function editRegularContentFromId() {
1400 if (t3lib_extMgm::isLoaded('cms')) {
1401 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1402 'uid',
1403 'tt_content',
1404 'pid='.intval($this->editRegularContentFromId).
1405 t3lib_BEfunc::deleteClause('tt_content').
1406 t3lib_BEfunc::versioningPlaceholderClause('tt_content').
1407 ' AND colPos=0 AND sys_language_uid=0',
1408 '',
1409 'sorting'
1410 );
1411 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res)) {
1412 $ecUids=array();
1413 while($ecRec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
1414 $ecUids[]=$ecRec['uid'];
1415 }
1416 $this->editconf['tt_content'][implode(',',$ecUids)]='edit';
1417 }
1418 }
1419 }
1420
1421 /**
1422 * Populates the variables $this->storeArray, $this->storeUrl, $this->storeUrlMd5
1423 *
1424 * @return void
1425 * @see makeDocSel()
1426 */
1427 function compileStoreDat() {
1428 $this->storeArray = t3lib_div::compileSelectedGetVarsFromArray('edit,defVals,overrideVals,columnsOnly,disHelp,noView,editRegularContentFromId',$this->R_URL_getvars);
1429 $this->storeUrl = t3lib_div::implodeArrayForUrl('',$this->storeArray);
1430 $this->storeUrlMd5 = md5($this->storeUrl);
1431 }
1432
1433 /**
1434 * Function used to look for configuration of buttons in the form: Fx. disabling buttons or showing them at various positions.
1435 *
1436 * @param string The table for which the configuration may be specific
1437 * @param string The option for look for. Default is checking if the saveDocNew button should be displayed.
1438 * @return string Return value fetched from USER TSconfig
1439 */
1440 function getNewIconMode($table,$key='saveDocNew') {
1441 global $BE_USER;
1442 $TSconfig = $BE_USER->getTSConfig('options.'.$key);
1443 $output = trim(isset($TSconfig['properties'][$table]) ? $TSconfig['properties'][$table] : $TSconfig['value']);
1444 return $output;
1445 }
1446
1447 /**
1448 * Handling the closing of a document
1449 *
1450 * @param integer Close code: 0/1 will redirect to $this->retUrl, 3 will clear the docHandler (thus closing all documents) and otehr values will call setDocument with ->retUrl
1451 * @return void
1452 */
1453 function closeDocument($code=0) {
1454 global $BE_USER;
1455
1456 // If current document is found in docHandler, then unset it, possibly unset it ALL and finally, write it to the session data:
1457 if (isset($this->docHandler[$this->storeUrlMd5])) {
1458 unset($this->docHandler[$this->storeUrlMd5]);
1459 if ($code=='3') $this->docHandler=array();
1460 $BE_USER->pushModuleData('alt_doc.php',array($this->docHandler,$this->docDat[1]));
1461 }
1462
1463 // If ->returnEditConf is set, then add the current content of editconf to the ->retUrl variable: (used by other scripts, like wizard_add, to know which records was created or so...)
1464 if ($this->returnEditConf && $this->retUrl!='dummy.php') {
1465 $this->retUrl.='&returnEditConf='.rawurlencode(serialize($this->editconf));
1466 }
1467
1468 // If code is NOT set OR set to 1, then make a header location redirect to $this->retUrl
1469 if (!$code || $code==1) {
1470 Header('Location: '.t3lib_div::locationHeaderUrl($this->retUrl));
1471 exit;
1472 } else {
1473 $this->setDocument('',$this->retUrl);
1474 }
1475 }
1476
1477 /**
1478 * Redirects to the document pointed to by $currentDocFromHandlerMD5 OR $retUrl (depending on some internal calculations).
1479 * Most likely you will get a header-location redirect from this function.
1480 *
1481 * @param string Pointer to the document in the docHandler array
1482 * @param string Alternative/Default retUrl
1483 * @return void
1484 */
1485 function setDocument($currentDocFromHandlerMD5='',$retUrl='alt_doc_nodoc.php') {
1486 if (!t3lib_extMgm::isLoaded('cms') && !strcmp($retUrl,'alt_doc_nodoc.php')) return;
1487
1488 if (!$this->modTSconfig['properties']['disableDocSelector'] && is_array($this->docHandler) && count($this->docHandler)) {
1489 if (isset($this->docHandler[$currentDocFromHandlerMD5])) {
1490 $setupArr=$this->docHandler[$currentDocFromHandlerMD5];
1491 } else {
1492 reset($this->docHandler);
1493 $setupArr=current($this->docHandler);
1494 }
1495 if ($setupArr[2]) {
1496 $sParts = parse_url(t3lib_div::getIndpEnv('REQUEST_URI'));
1497 $retUrl = $sParts['path'].'?'.$setupArr[2].'&returnUrl='.rawurlencode($retUrl);
1498 }
1499 }
1500 Header('Location: '.t3lib_div::locationHeaderUrl($retUrl));
1501 exit;
1502 }
1503 }
1504
1505 // Include extension?
1506 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/alt_doc.php']) {
1507 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/alt_doc.php']);
1508 }
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525 // Make instance:
1526 $SOBE = t3lib_div::makeInstance('SC_alt_doc');
1527
1528 // Preprocessing, storing data if submitted to
1529 $SOBE->preInit();
1530 if ($SOBE->doProcessData()) { // Checks, if a save button has been clicked (or the doSave variable is sent)
1531 $SOBE->processData();
1532 }
1533
1534
1535 // Main:
1536 $SOBE->init();
1537 $SOBE->main();
1538 $SOBE->printContent();
1539 ?>