Committed DBAL-related changes, see RFC mail from Dec 24th.
[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 * 100: class SC_alt_doc
44 * 174: function preInit()
45 * 232: function doProcessData()
46 * 242: function processData()
47 * 370: function init()
48 * 462: function main()
49 * 531: function printContent()
50 *
51 * SECTION: Sub-content functions, rendering specific parts of the module content.
52 * 566: function makeEditForm()
53 * 749: function makeButtonPanel()
54 * 828: function makeDocSel()
55 * 870: function makeCmenu()
56 * 891: function compileForm($panel,$docSel,$cMenu,$editForm)
57 * 953: function functionMenus()
58 * 984: function shortCutLink()
59 * 1015: function tceformMessages()
60 *
61 * SECTION: Other functions
62 * 1054: function fixWSversioningInEditConf($mapArray=FALSE)
63 * 1103: function getRecordForEdit($table,$theUid)
64 * 1138: function editRegularContentFromId()
65 * 1165: function compileStoreDat()
66 * 1178: function getNewIconMode($table,$key='saveDocNew')
67 * 1191: function closeDocument($code=0)
68 * 1223: function setDocument($currentDocFromHandlerMD5='',$retUrl='alt_doc_nodoc.php')
69 *
70 * TOTAL FUNCTIONS: 21
71 * (This index is automatically created/updated by the extension "extdeveval")
72 *
73 */
74
75
76 require('init.php');
77 require('template.php');
78 $LANG->includeLLFile('EXT:lang/locallang_alt_doc.xml');
79 require_once (PATH_t3lib.'class.t3lib_tceforms.php');
80 require_once (PATH_t3lib.'class.t3lib_clipboard.php');
81
82 require_once (PATH_t3lib.'class.t3lib_tcemain.php');
83 require_once (PATH_t3lib.'class.t3lib_loaddbgroup.php');
84 require_once (PATH_t3lib.'class.t3lib_transferdata.php');
85
86
87 t3lib_BEfunc::lockRecords();
88
89
90
91
92 /**
93 * Script Class: Drawing the editing form for editing records in TYPO3.
94 * Notice: It does NOT use tce_db.php to submit data to, rather it handles submissions itself
95 *
96 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
97 * @package TYPO3
98 * @subpackage core
99 */
100 class SC_alt_doc {
101
102 // Internal, static: GPvars:
103 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).
104 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
105 var $defVals; // Default values for fields (array with tablenames, fields etc. as keys). Can be seen modified internally.
106 var $overrideVals; // Array of values to force being set (as hidden fields). Will be set as $this->defVals IF defVals does not exist.
107 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
108 var $closeDoc; // Close-document command. Not really sure of all options...
109 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).
110
111 var $data; // GPvar (for processing only) : The data array from which the data comes...
112 var $mirror; // GPvar (for processing only) : ?
113 var $cacheCmd; // GPvar (for processing only) : Clear-cache cmd.
114 var $redirect; // GPvar (for processing only) : Redirect (not used???)
115 var $disableRTE; // GPvar (for processing only) : If set, the rich text editor is disabled in the forms.
116 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.
117 var $vC; // GPvar (for processing only) : Verification code, internal stuff.
118
119 var $popViewId; // GPvar (module) : ID for displaying the page in the frontend (used for SAVE/VIEW operations)
120 var $popViewId_addParams; // GPvar (module) : Additional GET vars for the link, eg. "&L=xxx"
121 var $viewUrl; // GPvar (module) : Alternative URL for viewing the frontend pages.
122 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!
123 var $recTitle; // Alternative title for the document handler.
124 var $disHelp; // Disable help... ?
125 var $noView; // If set, then no SAVE/VIEW button is printed
126 var $returnEditConf; // If set, the $this->editconf array is returned to the calling script (used by wizard_add.php for instance)
127 var $localizationMode; // GP var, localization mode for TCEforms (eg. "text")
128
129
130 // Internal, static:
131 var $doc; // Document template object
132 var $content; // Content accumulation
133
134 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.
135 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...
136 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.)
137 var $R_URI; // Set to the URL of this script including variables which is needed to re-display the form. See main()
138
139 var $storeTitle; // Is loaded with the "title" of the currently "open document" - this is used in the Document Selector box. (see makeDocSel())
140 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())
141 var $storeUrl; // Contains storeArray, but imploded into a GET parameter string (see compileStoreDat())
142 var $storeUrlMd5; // Hashed value of storeURL (see compileStoreDat())
143
144 var $docDat; // Module session data
145 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".
146
147
148 // Internal: Related to the form rendering:
149 var $elementsData; // Array of the elements to create edit forms for.
150 var $firstEl; // Pointer to the first element in $elementsData
151 var $errorC; // Counter, used to count the number of errors (when users do not have edit permissions)
152 var $newC; // Counter, used to count the number of new record forms displayed
153 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
154 var $viewId_addParams; // Is set to additional parameters (like "&L=xxx") if the record supports it.
155 var $modTSconfig; // Module TSconfig, loaded from main() based on the page id value of viewId
156 var $tceforms; // Contains the instance of TCEforms class.
157 var $generalPathOfForm; // Contains the root-line path of the currently edited record(s) - for display.
158
159
160 // Internal, dynamic:
161 var $dontStoreDocumentRef; // Used internally to disable the storage of the document reference (eg. new records)
162
163
164
165
166
167
168
169 /**
170 * First initialization.
171 *
172 * @return void
173 */
174 function preInit() {
175 global $BE_USER;
176
177 // Setting GPvars:
178 $this->editconf = t3lib_div::_GP('edit');
179 $this->defVals = t3lib_div::_GP('defVals');
180 $this->overrideVals = t3lib_div::_GP('overrideVals');
181 $this->columnsOnly = t3lib_div::_GP('columnsOnly');
182 $this->returnUrl = t3lib_div::_GP('returnUrl');
183 $this->closeDoc = t3lib_div::_GP('closeDoc');
184 $this->doSave = t3lib_div::_GP('doSave');
185 $this->returnEditConf = t3lib_div::_GP('returnEditConf');
186 $this->localizationMode = t3lib_div::_GP('localizationMode');
187
188
189 // Setting override values as default if defVals does not exist.
190 if (!is_array($this->defVals) && is_array($this->overrideVals)) {
191 $this->defVals = $this->overrideVals;
192 }
193
194 // Setting return URL
195 $this->retUrl = $this->returnUrl ? $this->returnUrl : 'dummy.php';
196
197 // Fix $this->editconf if versioning applies to any of the records
198 $this->fixWSversioningInEditConf();
199
200 // Make R_URL (request url) based on input GETvars:
201 $this->R_URL_parts = parse_url(t3lib_div::getIndpEnv('REQUEST_URI'));
202 $this->R_URL_getvars = t3lib_div::_GET();
203 $this->R_URL_getvars['edit'] = $this->editconf;
204
205 // MAKE url for storing
206 $this->compileStoreDat();
207
208 // Initialize more variables.
209 $this->dontStoreDocumentRef=0;
210 $this->storeTitle='';
211
212 // Get session data for the module:
213 $this->docDat = $BE_USER->getModuleData('alt_doc.php','ses');
214 $this->docHandler = $this->docDat[0];
215
216 // If a request for closing the document has been sent, act accordingly:
217 if ($this->closeDoc>0) {
218 $this->closeDocument($this->closeDoc);
219 }
220
221 // If NO vars are sent to the script, try to read first document:
222 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...
223 $this->setDocument($this->docDat[1]);
224 }
225 }
226
227 /**
228 * Detects, if a save command has been triggered.
229 *
230 * @return boolean True, then save the document (data submitted)
231 */
232 function doProcessData() {
233 $out = $this->doSave || isset($_POST['_savedok_x']) || isset($_POST['_saveandclosedok_x']) || isset($_POST['_savedokview_x']) || isset($_POST['_savedoknew_x']);
234 return $out;
235 }
236
237 /**
238 * Do processing of data, submitting it to TCEmain.
239 *
240 * @return void
241 */
242 function processData() {
243 global $BE_USER,$TYPO3_CONF_VARS;
244
245 // GPvars specifically for processing:
246 $this->data = t3lib_div::_GP('data');
247 $this->mirror = t3lib_div::_GP('mirror');
248 $this->cacheCmd = t3lib_div::_GP('cacheCmd');
249 $this->redirect = t3lib_div::_GP('redirect');
250 $this->disableRTE = t3lib_div::_GP('_disableRTE');
251 $this->returnNewPageId = t3lib_div::_GP('returnNewPageId');
252 $this->vC = t3lib_div::_GP('vC');
253
254 // See tce_db.php for relevate options here:
255 // Only options related to $this->data submission are included here.
256 $tce = t3lib_div::makeInstance('t3lib_TCEmain');
257 $tce->stripslashes_values=0;
258
259 // Setting default values specific for the user:
260 $TCAdefaultOverride = $BE_USER->getTSConfigProp('TCAdefaults');
261 if (is_array($TCAdefaultOverride)) {
262 $tce->setDefaultsFromUserTS($TCAdefaultOverride);
263 }
264
265 // Setting internal vars:
266 if ($BE_USER->uc['neverHideAtCopy']) { $tce->neverHideAtCopy = 1; }
267 $tce->debug=0;
268 $tce->disableRTE = $this->disableRTE;
269
270 // Loading TCEmain with data:
271 $tce->start($this->data,array());
272 if (is_array($this->mirror)) { $tce->setMirror($this->mirror); }
273
274 // If pages are being edited, we set an instruction about updating the page tree after this operation.
275 if (isset($this->data['pages'])) {
276 t3lib_BEfunc::getSetUpdateSignal('updatePageTree');
277 }
278
279
280 // Checking referer / executing
281 $refInfo=parse_url(t3lib_div::getIndpEnv('HTTP_REFERER'));
282 $httpHost = t3lib_div::getIndpEnv('TYPO3_HOST_ONLY');
283 if ($httpHost!=$refInfo['host'] && $this->vC!=$BE_USER->veriCode() && !$TYPO3_CONF_VARS['SYS']['doNotCheckReferer']) {
284 $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));
285 debug('Error: Referer host did not match with server host.');
286 } else {
287
288 // Perform the saving operation with TCEmain:
289 $tce->process_uploads($_FILES);
290 $tce->process_datamap();
291
292 // If there was saved any new items, load them:
293 if (count($tce->substNEWwithIDs_table)) {
294
295 // Resetting editconf:
296 $this->editconf = array();
297
298 // Traverse all new records and forge the content of ->editconf so we can continue to EDIT these records!
299 foreach($tce->substNEWwithIDs_table as $nKey => $nTable) {
300 $editId = $tce->substNEWwithIDs[$nKey];
301 // translate new id to the workspace version:
302 if ($versionRec = t3lib_BEfunc::getWorkspaceVersionOfRecord($GLOBALS['BE_USER']->workspace, $nTable, $editId,'uid')) {
303 $editId = $versionRec['uid'];
304 }
305
306 $this->editconf[$nTable][$editId]='edit';
307 if ($nTable=='pages' && $this->retUrl!='dummy.php' && $this->returnNewPageId) {
308 $this->retUrl.='&id='.$tce->substNEWwithIDs[$nKey];
309 }
310 }
311
312 // Finally, set the editconf array in the "getvars" so they will be passed along in URLs as needed.
313 $this->R_URL_getvars['edit']=$this->editconf;
314
315 // Unsetting default values since we don't need them anymore.
316 unset($this->R_URL_getvars['defVals']);
317
318 // Re-compile the store* values since editconf changed...
319 $this->compileStoreDat();
320 }
321
322 // See if any records was auto-created as new versions?
323 if (count($tce->autoVersionIdMap)) {
324 $this->fixWSversioningInEditConf($tce->autoVersionIdMap);
325 }
326
327 // If a document is saved and a new one is created right after.
328 if (isset($_POST['_savedoknew_x']) && is_array($this->editconf)) {
329
330 // Finding the current table:
331 reset($this->editconf);
332 $nTable=key($this->editconf);
333
334 // Finding the first id, getting the records pid+uid
335 reset($this->editconf[$nTable]);
336 $nUid=key($this->editconf[$nTable]);
337 $nRec = t3lib_BEfunc::getRecord($nTable,$nUid,'pid,uid');
338
339 // Setting a blank editconf array for a new record:
340 $this->editconf=array();
341 if ($this->getNewIconMode($nTable)=='top') {
342 $this->editconf[$nTable][$nRec['pid']]='new';
343 } else {
344 $this->editconf[$nTable][-$nRec['uid']]='new';
345 }
346
347 // Finally, set the editconf array in the "getvars" so they will be passed along in URLs as needed.
348 $this->R_URL_getvars['edit']=$this->editconf;
349
350 // Re-compile the store* values since editconf changed...
351 $this->compileStoreDat();
352 }
353
354 $tce->printLogErrorMessages(
355 isset($_POST['_saveandclosedok_x']) ?
356 $this->retUrl :
357 $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?
358 );
359 }
360 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!
361 $this->closeDocument(abs($this->closeDoc));
362 }
363 }
364
365 /**
366 * Initialize the normal module operation
367 *
368 * @return void
369 */
370 function init() {
371 global $BE_USER,$LANG,$BACK_PATH;
372
373 // Setting more GPvars:
374 $this->popViewId = t3lib_div::_GP('popViewId');
375 $this->popViewId_addParams = t3lib_div::_GP('popViewId_addParams');
376 $this->viewUrl = t3lib_div::_GP('viewUrl');
377 $this->editRegularContentFromId = t3lib_div::_GP('editRegularContentFromId');
378 $this->recTitle = t3lib_div::_GP('recTitle');
379 $this->disHelp = t3lib_div::_GP('disHelp');
380 $this->noView = t3lib_div::_GP('noView');
381
382 // Set other internal variables:
383 $this->R_URL_getvars['returnUrl']=$this->retUrl;
384 $this->R_URI = $this->R_URL_parts['path'].'?'.t3lib_div::implodeArrayForUrl('',$this->R_URL_getvars);
385
386 // MENU-ITEMS:
387 // If array, then it's a selector box menu
388 // If empty string it's just a variable, that'll be saved.
389 // Values NOT in this array will not be saved in the settings-array for the module.
390 $this->MOD_MENU = array(
391 'showPalettes' => '',
392 'showDescriptions' => '',
393 'disableRTE' => ''
394 );
395
396 // Setting virtual document name
397 $this->MCONF['name']='xMOD_alt_doc.php';
398
399 // CLEANSE SETTINGS
400 $this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), $this->MCONF['name']);
401
402 // Create an instance of the document template object
403 $this->doc = t3lib_div::makeInstance('mediumDoc');
404 $this->doc->bodyTagMargins['x']=5;
405 $this->doc->bodyTagMargins['y']=5;
406 $this->doc->backPath = $BACK_PATH;
407 $this->doc->docType = 'xhtml_trans';
408
409 $this->doc->form='<form action="'.htmlspecialchars($this->R_URI).'" method="post" enctype="'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'].'" name="editform" onsubmit="return TBE_EDITOR_checkSubmit(1);">';
410
411 $this->doc->JScode = $this->doc->wrapScriptTags('
412 function jumpToUrl(URL,formEl) { //
413 if (!TBE_EDITOR_isFormChanged()) {
414 document.location = URL;
415 } else if (formEl && formEl.type=="checkbox") {
416 formEl.checked = formEl.checked ? 0 : 1;
417 }
418 }
419
420 // Object: TS:
421 function typoSetup () { //
422 this.uniqueID = "";
423 }
424 var TS = new typoSetup();
425
426 // Info view:
427 function launchView(table,uid,bP) { //
428 var backPath= bP ? bP : "";
429 var thePreviewWindow="";
430 thePreviewWindow = window.open(backPath+"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");
431 if (thePreviewWindow && thePreviewWindow.focus) {
432 thePreviewWindow.focus();
433 }
434 }
435 function deleteRecord(table,id,url) { //
436 if (
437 '.($GLOBALS['BE_USER']->jsConfirmation(4)?'confirm('.$LANG->JScharCode($LANG->getLL('deleteWarning')).')':'1==1').'
438 ) {
439 document.location = "tce_db.php?cmd["+table+"]["+id+"][delete]=1&redirect="+escape(url)+"&vC='.$BE_USER->veriCode().'&prErr=1&uPT=1";
440 }
441 return false;
442 }
443 '.(isset($_POST['_savedokview_x']) && $this->popViewId ?
444 'if (window.opener) { '.
445 t3lib_BEfunc::viewOnClick($this->popViewId,'',t3lib_BEfunc::BEgetRootLine($this->popViewId),'',$this->viewUrl,$this->popViewId_addParams,FALSE).
446 ' } else { '.
447 t3lib_BEfunc::viewOnClick($this->popViewId,'',t3lib_BEfunc::BEgetRootLine($this->popViewId),'',$this->viewUrl,$this->popViewId_addParams).
448 ' } '
449 : '')
450 ).$this->doc->getDynTabMenuJScode();
451
452 // Setting up the context sensitive menu:
453 $CMparts = $this->doc->getContextMenuCode();
454 $this->doc->JScode.= $CMparts[0];
455 $this->doc->bodyTagAdditions = $CMparts[1];
456 $this->doc->postCode.= $CMparts[2];
457 }
458
459 /**
460 * Main module operation
461 *
462 * @return void
463 */
464 function main() {
465 global $BE_USER,$LANG;
466
467 // Starting content accumulation:
468 $this->content='';
469 $this->content.=$this->doc->startPage('TYPO3 Edit Document');
470
471 // Begin edit:
472 if (is_array($this->editconf)) {
473
474 // Initialize TCEforms (rendering the forms)
475 $this->tceforms = t3lib_div::makeInstance('t3lib_TCEforms');
476 $this->tceforms->initDefaultBEMode();
477 $this->tceforms->doSaveFieldName = 'doSave';
478 $this->tceforms->localizationMode = t3lib_div::inList('text,media',$this->localizationMode) ? $this->localizationMode : ''; // text,media is keywords defined in TYPO3 Core API..., see "l10n_cat"
479 $this->tceforms->returnUrl = $this->R_URI;
480 $this->tceforms->palettesCollapsed = !$this->MOD_SETTINGS['showPalettes'];
481 $this->tceforms->disableRTE = $this->MOD_SETTINGS['disableRTE'];
482 $this->tceforms->enableClickMenu = TRUE;
483 $this->tceforms->enableTabMenu = TRUE;
484
485 // Clipboard is initialized:
486 $this->tceforms->clipObj = t3lib_div::makeInstance('t3lib_clipboard'); // Start clipboard
487 $this->tceforms->clipObj->initializeClipboard(); // Initialize - reads the clipboard content from the user session
488
489 // Setting external variables:
490 if ($BE_USER->uc['edit_showFieldHelp']!='text' && $this->MOD_SETTINGS['showDescriptions']) $this->tceforms->edit_showFieldHelp='text';
491
492 if ($this->editRegularContentFromId) {
493 $this->editRegularContentFromId();
494 }
495
496 // Creating the editing form, wrap it with buttons, document selector etc.
497 $editForm = $this->makeEditForm();
498 if ($editForm) {
499 reset($this->elementsData);
500 $this->firstEl = current($this->elementsData);
501
502 if ($this->viewId) {
503 // Module configuration:
504 $this->modTSconfig = t3lib_BEfunc::getModTSconfig($this->viewId,'mod.xMOD_alt_doc');
505 } else $this->modTSconfig=array();
506
507 $panel = $this->makeButtonPanel();
508 $docSel = $this->makeDocSel();
509 $cMenu = $this->makeCmenu();
510
511 $formContent = $this->compileForm($panel,$docSel,$cMenu,$editForm);
512
513 $this->content.= $this->tceforms->printNeededJSFunctions_top().
514 $formContent.
515 $this->tceforms->printNeededJSFunctions();
516 $this->content.= $this->functionMenus();
517
518 // Add CSH:
519 $this->content.= t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'TCEforms', $GLOBALS['BACK_PATH'],'<br/>|',FALSE,'margin-top: 20px;');
520
521 $this->content.= $this->shortCutLink();
522
523 $this->tceformMessages();
524 }
525 }
526 }
527
528 /**
529 * Outputting the accumulated content to screen
530 *
531 * @return void
532 */
533 function printContent() {
534
535 echo $this->content.$this->doc->endPage();
536 }
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557 /***************************
558 *
559 * Sub-content functions, rendering specific parts of the module content.
560 *
561 ***************************/
562
563 /**
564 * Creates the editing form with TCEforms, based on the input from GPvars.
565 *
566 * @return string HTML form elements wrapped in tables
567 */
568 function makeEditForm() {
569 global $BE_USER,$LANG,$TCA;
570
571 // Initialize variables:
572 $this->elementsData=array();
573 $this->errorC=0;
574 $this->newC=0;
575 $thePrevUid='';
576 $editForm='';
577
578 // Traverse the GPvar edit array
579 foreach($this->editconf as $table => $conf) { // Tables:
580 if (is_array($conf) && $TCA[$table] && $BE_USER->check('tables_modify',$table)) {
581
582 // Traverse the keys/comments of each table (keys can be a commalist of uids)
583 foreach($conf as $cKey => $cmd) {
584 if ($cmd=='edit' || $cmd=='new') {
585
586 // Get the ids:
587 $ids = t3lib_div::trimExplode(',',$cKey,1);
588
589 // Traverse the ids:
590 foreach($ids as $theUid) {
591
592 // 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...)
593 // First, resetting flags.
594 $hasAccess = 1;
595 $deniedAccessReason = '';
596 $deleteAccess = 0;
597 $this->viewId = 0;
598
599 // If the command is to create a NEW record...:
600 if ($cmd=='new') {
601 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.
602
603 // Find parent page on which the new record reside
604 if ($theUid<0) { // Less than zero - find parent page
605 $calcPRec=t3lib_BEfunc::getRecord($table,abs($theUid));
606 $calcPRec=t3lib_BEfunc::getRecord('pages',$calcPRec['pid']);
607 } else { // always a page
608 $calcPRec=t3lib_BEfunc::getRecord('pages',abs($theUid));
609 }
610
611 // Now, calculate whether the user has access to creating new records on this position:
612 if (is_array($calcPRec)) {
613 $CALC_PERMS = $BE_USER->calcPerms($calcPRec); // Permissions for the parent page
614 if ($table=='pages') { // If pages:
615 $hasAccess = $CALC_PERMS&8 ? 1 : 0;
616 $this->viewId = $calcPRec['pid'];
617 } else {
618 $hasAccess = $CALC_PERMS&16 ? 1 : 0;
619 $this->viewId = $calcPRec['uid'];
620 }
621 }
622 }
623 $this->dontStoreDocumentRef=1; // Don't save this document title in the document selector if the document is new.
624 } else { // Edit:
625 $calcPRec = t3lib_BEfunc::getRecord($table,$theUid);
626 t3lib_BEfunc::fixVersioningPid($table,$calcPRec);
627 if (is_array($calcPRec)) {
628 if ($table=='pages') { // If pages:
629 $CALC_PERMS = $BE_USER->calcPerms($calcPRec);
630 $hasAccess = $CALC_PERMS&2 ? 1 : 0;
631 $deleteAccess = $CALC_PERMS&4 ? 1 : 0;
632 $this->viewId = $calcPRec['uid'];
633 } else {
634 $CALC_PERMS = $BE_USER->calcPerms(t3lib_BEfunc::getRecord('pages',$calcPRec['pid'])); // Fetching pid-record first.
635 $hasAccess = $CALC_PERMS&16 ? 1 : 0;
636 $deleteAccess = $CALC_PERMS&16 ? 1 : 0;
637 $this->viewId = $calcPRec['pid'];
638
639 // Adding "&L=xx" if the record being edited has a languageField with a value larger than zero!
640 if ($TCA[$table]['ctrl']['languageField'] && $calcPRec[$TCA[$table]['ctrl']['languageField']]>0) {
641 $this->viewId_addParams = '&L='.$calcPRec[$TCA[$table]['ctrl']['languageField']];
642 }
643 }
644
645 // Check internals regarding access:
646 if ($hasAccess) {
647 $hasAccess = $BE_USER->recordEditAccessInternals($table, $calcPRec);
648 $deniedAccessReason = $BE_USER->errorMsg;
649 }
650 } else $hasAccess = 0;
651 }
652
653 // 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:
654
655 if ($hasAccess) {
656 $prevPageID = is_object($trData)?$trData->prevPageID:'';
657 $trData = t3lib_div::makeInstance('t3lib_transferData');
658 $trData->addRawData = TRUE;
659 $trData->defVals = $this->defVals;
660 $trData->lockRecords=1;
661 $trData->disableRTE = $this->MOD_SETTINGS['disableRTE'];
662 $trData->prevPageID = $prevPageID;
663 $trData->fetchRecord($table,$theUid,$cmd=='new'?'new':''); // 'new'
664 reset($trData->regTableItems_data);
665 $rec = current($trData->regTableItems_data);
666 $rec['uid'] = $cmd=='new' ? uniqid('NEW') : $theUid;
667 $this->elementsData[]=array(
668 'table' => $table,
669 'uid' => $rec['uid'],
670 'cmd' => $cmd,
671 'deleteAccess' => $deleteAccess
672 );
673 if ($cmd=='new') {
674 $rec['pid'] = $theUid=='prev'?$thePrevUid:$theUid;
675 }
676
677 // Now, render the form:
678 if (is_array($rec)) {
679
680 // Setting visual path / title of form:
681 $this->generalPathOfForm = $this->tceforms->getRecordPath($table,$rec);
682 if (!$this->storeTitle) {
683 $this->storeTitle = $this->recTitle ? htmlspecialchars($this->recTitle) : t3lib_BEfunc::getRecordTitle($table,$rec,1);
684 }
685
686 // Setting variables in TCEforms object:
687 $this->tceforms->hiddenFieldList = '';
688 $this->tceforms->globalShowHelp = $this->disHelp ? 0 : 1;
689 if (is_array($this->overrideVals[$table])) {
690 $this->tceforms->hiddenFieldListArr = array_keys($this->overrideVals[$table]);
691 }
692
693 // Register default language labels, if any:
694 $this->tceforms->registerDefaultLanguageData($table,$rec);
695
696 // Create form for the record (either specific list of fields or the whole record):
697 $panel = '';
698 if ($this->columnsOnly) {
699 $panel.= $this->tceforms->getListedFields($table,$rec,$this->columnsOnly);
700 } else {
701 $panel.= $this->tceforms->getMainFields($table,$rec);
702 }
703 $panel = $this->tceforms->wrapTotal($panel,$rec,$table);
704
705 // Setting the pid value for new records:
706 if ($cmd=='new') {
707 $panel.= '<input type="hidden" name="data['.$table.']['.$rec['uid'].'][pid]" value="'.$rec['pid'].'" />';
708 $this->newC++;
709 }
710
711 // Display "is-locked" message:
712 if ($lockInfo = t3lib_BEfunc::isRecordLocked($table,$rec['uid'])) {
713 $lockIcon = '
714
715 <!--
716 Warning box:
717 -->
718 <table border="0" cellpadding="0" cellspacing="0" class="warningbox">
719 <tr>
720 <td><img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/recordlock_warning3.gif','width="17" height="12"').' alt="" /></td>
721 <td>'.htmlspecialchars($lockInfo['msg']).'</td>
722 </tr>
723 </table>
724 ';
725 } else $lockIcon = '';
726
727 // Combine it all:
728 $editForm.= $lockIcon.$panel;
729 }
730
731 $thePrevUid = $rec['uid'];
732 } else {
733 $this->errorC++;
734 $editForm.=$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.noEditPermission',1).'<br /><br />'.
735 ($deniedAccessReason ? 'Reason: '.htmlspecialchars($deniedAccessReason).'<br/><br/>' : '');
736 }
737 }
738 }
739 }
740 }
741 }
742
743 return $editForm;
744 }
745
746 /**
747 * Create the panel of buttons for submitting the form or otherwise perform operations.
748 *
749 * @return string HTML code, comprised of images linked to various actions.
750 */
751 function makeButtonPanel() {
752 global $TCA,$LANG;
753
754 $panel='';
755
756 // Render SAVE type buttons:
757 // The action of each button is decided by its name attribute. (See doProcessData())
758 if (!$this->errorC && !$TCA[$this->firstEl['table']]['ctrl']['readOnly']) {
759
760 // SAVE button:
761 $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).'" />';
762
763 // SAVE / VIEW button:
764 if ($this->viewId && !$this->noView && t3lib_extMgm::isLoaded('cms')) {
765 $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).'" />';
766 }
767
768 // SAVE / NEW button:
769 if (count($this->elementsData)==1 && $this->getNewIconMode($this->firstEl['table'])) {
770 $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).'" />';
771 }
772
773 // SAVE / CLOSE
774 $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).'" />';
775 }
776
777 // CLOSE button:
778 $panel.= '<a href="#" onclick="document.editform.closeDoc.value=1; document.editform.submit(); return false;">'.
779 '<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="" />'.
780 '</a>';
781
782 // DELETE + UNDO buttons:
783 if (!$this->errorC && !$TCA[$this->firstEl['table']]['ctrl']['readOnly'] && count($this->elementsData)==1) {
784 if ($this->firstEl['cmd']!='new' && t3lib_div::testInt($this->firstEl['uid'])) {
785
786 // Delete:
787 if ($this->firstEl['deleteAccess'] && !$TCA[$this->firstEl['table']]['ctrl']['readOnly'] && !$this->getNewIconMode($this->firstEl['table'],'disableDelete')) {
788 $aOnClick = 'return deleteRecord(\''.$this->firstEl['table'].'\',\''.$this->firstEl['uid'].'\',unescape(\''.rawurlencode($this->retUrl).'\'));';
789 $panel.= '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.
790 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/deletedok.gif','width="21" height="16"').' class="c-inputButton" title="'.$LANG->getLL('deleteItem',1).'" alt="" />'.
791 '</a>';
792 }
793
794 // Undo:
795 $undoButton = 0;
796 $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');
797 if ($undoButtonR = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($undoRes)) {
798 $undoButton = 1;
799 }
800 if ($undoButton) {
801 $aOnClick = 'document.location=\'show_rechis.php?element='.rawurlencode($this->firstEl['table'].':'.$this->firstEl['uid']).'&revert=ALL_FIELDS&sumUp=-1&returnUrl='.rawurlencode($this->R_URI).'\'; return false;';
802 $panel.= '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.
803 '<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="" />'.
804 '</a>';
805 }
806 if ($this->getNewIconMode($this->firstEl['table'],'showHistory')) {
807 $aOnClick = 'document.location=\'show_rechis.php?element='.rawurlencode($this->firstEl['table'].':'.$this->firstEl['uid']).'&returnUrl='.rawurlencode($this->R_URI).'\'; return false;';
808 $panel.= '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.
809 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/history2.gif','width="13" height="12"').' class="c-inputButton" alt="" />'.
810 '</a>';
811 }
812
813 // If only SOME fields are shown in the form, this will link the user to the FULL form:
814 if ($this->columnsOnly) {
815 $panel.= '<a href="'.htmlspecialchars($this->R_URI.'&columnsOnly=').'">'.
816 '<img'.t3lib_iconWorks::skinImg($this->doc->backPath,'gfx/edit2.gif','width="11" height="12"').' class="c-inputButton" title="'.$LANG->getLL('editWholeRecord',1).'" alt="" />'.
817 '</a>';
818 }
819 }
820 }
821 return $panel;
822 }
823
824 /**
825 * Create the selector box form element which allows to select between open documents.
826 * Can be disabled through Page TSconfig.
827 *
828 * @return string HTML <select> element (if applicable)
829 */
830 function makeDocSel() {
831 global $BE_USER,$LANG;
832
833 // Render the selector ONLY if it has not been disabled:
834 if (!$this->modTSconfig['properties']['disableDocSelector']) {
835
836 // Checking if the currently open document is stored in the list of "open documents" - if not, then add it:
837 if ((strcmp($this->docDat[1],$this->storeUrlMd5)||!isset($this->docHandler[$this->storeUrlMd5])) && !$this->dontStoreDocumentRef) {
838 $this->docHandler[$this->storeUrlMd5]=array($this->storeTitle,$this->storeArray,$this->storeUrl);
839 $BE_USER->pushModuleData('alt_doc.php',array($this->docHandler,$this->storeUrlMd5));
840 }
841
842 // Now, create the document selector box:
843 $docSel='';
844 if (is_array($this->docHandler)) {
845 $opt = array();
846 $opt[] = '<option>[ '.$LANG->getLL('openDocs',1).': ]</option>';
847
848 // Traverse the list of open documents:
849 foreach($this->docHandler as $md5k => $setupArr) {
850 $theValue = 'alt_doc.php?'.$setupArr[2].'&returnUrl='.rawurlencode($this->retUrl);
851 $opt[]='<option value="'.htmlspecialchars($theValue).'"'.(!strcmp($md5k,$this->storeUrlMd5)?' selected="selected"':'').'>'.htmlspecialchars(strip_tags(t3lib_div::htmlspecialchars_decode($setupArr[0]))).'</option>';
852 }
853
854 // Compile the selector box finally:
855 $onChange = 'if(this.options[this.selectedIndex].value && !TBE_EDITOR_isFormChanged()){document.location=(this.options[this.selectedIndex].value);}';
856 $docSel='<select name="_docSelector" onchange="'.htmlspecialchars($onChange).'">'.implode('',$opt).'</select>';
857
858 // Add CSH:
859 $docSel.=t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'TCEforms_docSelector', $GLOBALS['BACK_PATH'],'', TRUE);
860 }
861 } else $docSel='';
862 return $docSel;
863 }
864
865 /**
866 * Create the selector box form element which allows to select a clear-cache operation.
867 * Can be disabled through Page TSconfig.
868 *
869 * @return string HTML <select> element (if applicable)
870 * @see template::clearCacheMenu()
871 */
872 function makeCmenu() {
873
874 // Generate the menu if NOT disabled:
875 if (!$this->modTSconfig['properties']['disableCacheSelector']) {
876 $cMenu = $this->doc->clearCacheMenu(intval($this->viewId),!$this->modTSconfig['properties']['disableDocSelector']);
877
878 // Add CSH:
879 $cMenu.=t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'TCEforms_cacheSelector', $GLOBALS['BACK_PATH'],'', TRUE);
880 } else $cMenu ='';
881 return $cMenu;
882 }
883
884 /**
885 * Put together the various elements (buttons, selectors, form) into a table
886 *
887 * @param string The button panel HTML
888 * @param string Document selector HTML
889 * @param string Clear-cache menu HTML
890 * @param string HTML form.
891 * @return string Composite HTML
892 */
893 function compileForm($panel,$docSel,$cMenu,$editForm) {
894 global $LANG;
895
896
897 $formContent='';
898 $formContent.='
899
900 <!--
901 Header of the editing page.
902 Contains the buttons for saving/closing, the document selector and menu selector.
903 Shows the path of the editing operation as well.
904 -->
905 <table border="0" cellpadding="0" cellspacing="1" width="470" id="typo3-altdoc-header">
906 <tr>
907 <td nowrap="nowrap" valign="top">'.$panel.'</td>
908 <td nowrap="nowrap" valign="top" align="right">'.$docSel.$cMenu.'</td>
909 </tr>
910 <tr>
911 <td colspan="2">'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.path',1).': '.htmlspecialchars($this->generalPathOfForm).'</td>
912 </tr>
913 </table>
914 <img src="clear.gif" width="1" height="4" alt="" /><br />
915
916
917
918
919 <!--
920 EDITING FORM:
921 -->
922
923 '.$editForm.'
924
925
926
927 <!--
928 Saving buttons (same as in top)
929 -->
930
931 '.$panel.
932 '<input type="hidden" name="returnUrl" value="'.htmlspecialchars($this->retUrl).'" />
933 <input type="hidden" name="viewUrl" value="'.htmlspecialchars($this->viewUrl).'" />';
934
935 if ($this->returnNewPageId) {
936 $formContent.='<input type="hidden" name="returnNewPageId" value="1" />';
937 }
938 $formContent.='<input type="hidden" name="popViewId" value="'.htmlspecialchars($this->viewId).'" />';
939 if ($this->viewId_addParams) {
940 $formContent.='<input type="hidden" name="popViewId_addParams" value="'.htmlspecialchars($this->viewId_addParams).'" />';
941 }
942 $formContent.='<input type="hidden" name="closeDoc" value="0" />';
943 $formContent.='<input type="hidden" name="doSave" value="0" />';
944 $formContent.='<input type="hidden" name="_serialNumber" value="'.md5(microtime()).'" />';
945 $formContent.='<input type="hidden" name="_disableRTE" value="'.$this->tceforms->disableRTE.'" />';
946
947 return $formContent;
948 }
949
950 /**
951 * Create the checkbox buttons in the bottom of the pages.
952 *
953 * @return string HTML for function menus.
954 */
955 function functionMenus() {
956 global $BE_USER,$LANG;
957
958 $funcMenus = '';
959
960 // Show palettes:
961 $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'=>'')))).$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.showPalettes',1);
962
963 // Show descriptions/help texts:
964 if ($BE_USER->uc['edit_showFieldHelp']!='text') {
965 $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'=>'')))).$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.showDescriptions',1);
966 }
967
968 // Show disable RTE checkbox:
969 if ($BE_USER->isRTE()) {
970 $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'=>'')))).$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.disableRTE',1);
971 }
972
973 return '
974
975 <!--
976 Function menus (checkboxes for selecting options):
977 -->
978 '.$funcMenus;
979 }
980
981 /**
982 * Create shortcut and open-in-window link in the bottom of the page
983 *
984 * @return string
985 */
986 function shortCutLink() {
987 global $BE_USER,$LANG;
988
989 // ShortCut
990 if ($this->returnUrl!='close.html') {
991 $content.='<br /><br />';
992
993 // Shortcut:
994 if ($BE_USER->mayMakeShortcut()) {
995 $content.=$this->doc->makeShortcutIcon('returnUrl,edit,defVals,overrideVals,columnsOnly,returnNewPageId,editRegularContentFromId,disHelp,noView',implode(',',array_keys($this->MOD_MENU)),$this->MCONF['name'],1);
996 }
997
998 // Open in new window:
999 $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;';
1000 $content.='<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.
1001 '<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="" />'.
1002 '</a>';
1003 }
1004 return '
1005
1006 <!--
1007 Shortcut link:
1008 -->
1009 '.$content;
1010 }
1011
1012 /**
1013 * Reads comment messages from TCEforms and prints them in a HTML comment in the buttom of the page.
1014 *
1015 * @return void
1016 */
1017 function tceformMessages() {
1018 if (count($this->tceforms->commentMessages)) {
1019 $this->content.='
1020
1021 <!-- TCEFORM messages
1022 '.htmlspecialchars(implode(chr(10),$this->tceforms->commentMessages)).'
1023 -->
1024
1025 ';
1026 }
1027 }
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044 /***************************
1045 *
1046 * Other functions
1047 *
1048 ***************************/
1049
1050 /**
1051 * Fix $this->editconf if versioning applies to any of the records
1052 *
1053 * @param array Mapping between old and new ids if auto-versioning has been performed.
1054 * @return void
1055 */
1056 function fixWSversioningInEditConf($mapArray=FALSE) {
1057 global $TCA,$BE_USER;
1058
1059 // Traverse the editConf array
1060 if (is_array($this->editconf)) {
1061 foreach($this->editconf as $table => $conf) { // Tables:
1062 if (is_array($conf) && $TCA[$table]) {
1063
1064 // Traverse the keys/comments of each table (keys can be a commalist of uids)
1065 $newConf = array();
1066 foreach($conf as $cKey => $cmd) {
1067 if ($cmd=='edit') {
1068 // Traverse the ids:
1069 $ids = t3lib_div::trimExplode(',', $cKey, 1);
1070 foreach($ids as $idKey => $theUid) {
1071 if (is_array($mapArray)) {
1072 if ($mapArray[$table][$theUid]) {
1073 $ids[$idKey] = $mapArray[$table][$theUid];
1074 }
1075 } else { // Default, look for versions in workspace for record:
1076 $calcPRec = $this->getRecordForEdit($table,$theUid);
1077 if (is_array($calcPRec)) {
1078 // Setting UID again if it had changed, eg. due to workspace versioning.
1079 $ids[$idKey] = $calcPRec['uid'];
1080 }
1081 }
1082 #else unset($ids[$idKey]);
1083 }
1084
1085 // Add the possibly manipulated IDs to the new-build newConf array:
1086 $newConf[implode(',',$ids)] = $cmd;
1087 } else {
1088 $newConf[$cKey] = $cmd;
1089 }
1090 }
1091 // Store the new conf array:
1092 $this->editconf[$table] = $newConf;
1093 }
1094 }
1095 }
1096 }
1097
1098 /**
1099 * Get record for editing.
1100 *
1101 * @param string Table name
1102 * @param integer Record UID
1103 * @return array Returns record to edit, false if none
1104 */
1105 function getRecordForEdit($table,$theUid) {
1106 global $TCA;
1107
1108 // Fetch requested record:
1109 $reqRecord = t3lib_BEfunc::getRecord($table,$theUid,'uid,pid');
1110
1111 if (is_array($reqRecord)) {
1112 // If workspace is OFFLINE:
1113 if ($GLOBALS['BE_USER']->workspace!=0) {
1114
1115 // Check for versioning support of the table:
1116 if ($TCA[$table] && $TCA[$table]['ctrl']['versioningWS']) {
1117
1118 // If the record is already a version of "something" pass it by.
1119 if ($reqRecord['pid']==-1) {
1120
1121 // (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)
1122 return $reqRecord;
1123 } else { // The input record was online and an offline version must be found or made:
1124
1125 // Look for version of this workspace:
1126 $versionRec = t3lib_BEfunc::getWorkspaceVersionOfRecord($GLOBALS['BE_USER']->workspace, $table, $reqRecord['uid'],'uid,pid,t3ver_oid');
1127 return is_array($versionRec) ? $versionRec : $reqRecord;
1128 }
1129 } 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.
1130 } else return $reqRecord; // In ONLINE workspace, just return the originally requested record:
1131 } else return FALSE; // Return false because the table/uid was not found anyway.
1132 }
1133
1134 /**
1135 * 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
1136 *
1137 * @return void
1138 */
1139 function editRegularContentFromId() {
1140 if (t3lib_extMgm::isLoaded('cms')) {
1141 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1142 'uid',
1143 'tt_content',
1144 'pid='.intval($this->editRegularContentFromId).
1145 t3lib_BEfunc::deleteClause('tt_content').
1146 t3lib_BEfunc::versioningPlaceholderClause('tt_content').
1147 ' AND colPos=0 AND sys_language_uid=0',
1148 '',
1149 'sorting'
1150 );
1151 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res)) {
1152 $ecUids=array();
1153 while($ecRec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
1154 $ecUids[]=$ecRec['uid'];
1155 }
1156 $this->editconf['tt_content'][implode(',',$ecUids)]='edit';
1157 }
1158 }
1159 }
1160
1161 /**
1162 * Populates the variables $this->storeArray, $this->storeUrl, $this->storeUrlMd5
1163 *
1164 * @return void
1165 * @see makeDocSel()
1166 */
1167 function compileStoreDat() {
1168 $this->storeArray = t3lib_div::compileSelectedGetVarsFromArray('edit,defVals,overrideVals,columnsOnly,disHelp,noView,editRegularContentFromId',$this->R_URL_getvars);
1169 $this->storeUrl = t3lib_div::implodeArrayForUrl('',$this->storeArray);
1170 $this->storeUrlMd5 = md5($this->storeUrl);
1171 }
1172
1173 /**
1174 * Function used to look for configuration of buttons in the form: Fx. disabling buttons or showing them at various positions.
1175 *
1176 * @param string The table for which the configuration may be specific
1177 * @param string The option for look for. Default is checking if the saveDocNew button should be displayed.
1178 * @return string Return value fetched from USER TSconfig
1179 */
1180 function getNewIconMode($table,$key='saveDocNew') {
1181 global $BE_USER;
1182 $TSconfig = $BE_USER->getTSConfig('options.'.$key);
1183 $output = trim(isset($TSconfig['properties'][$table]) ? $TSconfig['properties'][$table] : $TSconfig['value']);
1184 return $output;
1185 }
1186
1187 /**
1188 * Handling the closing of a document
1189 *
1190 * @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
1191 * @return void
1192 */
1193 function closeDocument($code=0) {
1194 global $BE_USER;
1195
1196 // If current document is found in docHandler, then unset it, possibly unset it ALL and finally, write it to the session data:
1197 if (isset($this->docHandler[$this->storeUrlMd5])) {
1198 unset($this->docHandler[$this->storeUrlMd5]);
1199 if ($code=='3') $this->docHandler=array();
1200 $BE_USER->pushModuleData('alt_doc.php',array($this->docHandler,$this->docDat[1]));
1201 }
1202
1203 // 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...)
1204 if ($this->returnEditConf && $this->retUrl!='dummy.php') {
1205 $this->retUrl.='&returnEditConf='.rawurlencode(serialize($this->editconf));
1206 }
1207
1208 // If code is NOT set OR set to 1, then make a header location redirect to $this->retUrl
1209 if (!$code || $code==1) {
1210 Header('Location: '.t3lib_div::locationHeaderUrl($this->retUrl));
1211 exit;
1212 } else {
1213 $this->setDocument('',$this->retUrl);
1214 }
1215 }
1216
1217 /**
1218 * Redirects to the document pointed to by $currentDocFromHandlerMD5 OR $retUrl (depending on some internal calculations).
1219 * Most likely you will get a header-location redirect from this function.
1220 *
1221 * @param string Pointer to the document in the docHandler array
1222 * @param string Alternative/Default retUrl
1223 * @return void
1224 */
1225 function setDocument($currentDocFromHandlerMD5='',$retUrl='alt_doc_nodoc.php') {
1226 if (!t3lib_extMgm::isLoaded('cms') && !strcmp($retUrl,'alt_doc_nodoc.php')) return;
1227
1228 if (!$this->modTSconfig['properties']['disableDocSelector'] && is_array($this->docHandler) && count($this->docHandler)) {
1229 if (isset($this->docHandler[$currentDocFromHandlerMD5])) {
1230 $setupArr=$this->docHandler[$currentDocFromHandlerMD5];
1231 } else {
1232 reset($this->docHandler);
1233 $setupArr=current($this->docHandler);
1234 }
1235 if ($setupArr[2]) {
1236 $sParts = parse_url(t3lib_div::getIndpEnv('REQUEST_URI'));
1237 $retUrl = $sParts['path'].'?'.$setupArr[2].'&returnUrl='.rawurlencode($retUrl);
1238 }
1239 }
1240 Header('Location: '.t3lib_div::locationHeaderUrl($retUrl));
1241 exit;
1242 }
1243 }
1244
1245 // Include extension?
1246 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/alt_doc.php']) {
1247 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/alt_doc.php']);
1248 }
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265 // Make instance:
1266 $SOBE = t3lib_div::makeInstance('SC_alt_doc');
1267
1268 // Preprocessing, storing data if submitted to
1269 $SOBE->preInit();
1270 if ($SOBE->doProcessData()) { // Checks, if a save button has been clicked (or the doSave variable is sent)
1271 $SOBE->processData();
1272 }
1273
1274
1275 // Main:
1276 $SOBE->init();
1277 $SOBE->main();
1278 $SOBE->printContent();
1279 ?>