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