78f93cd1d65ae397f6d0ee1433bec55cbac41e68
2 /***************************************************************
5 * (c) 1999-2008 Kasper Skaarhoj (kasperYYYY@typo3.com)
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.
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.
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.
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
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.
33 * Revised for TYPO3 3.6 November/2003 by Kasper Skaarhoj
36 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
39 * [CLASS/FUNCTION INDEX of SCRIPT]
43 * 105: class SC_alt_doc
44 * 179: function preInit()
45 * 241: function doProcessData()
46 * 251: function processData()
47 * 379: function init()
48 * 473: function main()
49 * 551: function printContent()
51 * SECTION: Sub-content functions, rendering specific parts of the module content.
52 * 587: function makeEditForm()
53 * 771: function makeButtonPanel()
54 * 850: function makeDocSel()
55 * 892: function makeCmenu()
56 * 914: function compileForm($panel,$docSel,$cMenu,$editForm, $langSelector='')
57 * 982: function functionMenus()
58 * 1013: function shortCutLink()
59 * 1044: function tceformMessages()
61 * SECTION: Localization stuff
62 * 1083: function languageSwitch($table, $uid, $pid=NULL)
63 * 1179: function localizationRedirect($justLocalized)
64 * 1213: function getLanguages($id)
66 * SECTION: Other functions
67 * 1275: function fixWSversioningInEditConf($mapArray=FALSE)
68 * 1324: function getRecordForEdit($table,$theUid)
69 * 1358: function editRegularContentFromId()
70 * 1386: function compileStoreDat()
71 * 1399: function getNewIconMode($table,$key='saveDocNew')
72 * 1412: function closeDocument($code=0)
73 * 1444: function setDocument($currentDocFromHandlerMD5='',$retUrl='alt_doc_nodoc.php')
76 * (This index is automatically created/updated by the extension "extdeveval")
82 require('template.php');
83 $LANG->includeLLFile('EXT:lang/locallang_alt_doc.xml');
84 require_once (PATH_t3lib
.'class.t3lib_tceforms.php');
85 require_once (PATH_t3lib
.'class.t3lib_clipboard.php');
87 require_once (PATH_t3lib
.'class.t3lib_tcemain.php');
88 require_once (PATH_t3lib
.'class.t3lib_loaddbgroup.php');
89 require_once (PATH_t3lib
.'class.t3lib_transferdata.php');
92 t3lib_BEfunc
::lockRecords();
98 * Script Class: Drawing the editing form for editing records in TYPO3.
99 * Notice: It does NOT use tce_db.php to submit data to, rather it handles submissions itself
101 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
107 // Internal, static: GPvars:
108 var $editconf; // GPvar "edit": Is an array looking approx like [tablename][list-of-ids]=command, eg. "&edit[pages][123]=edit". See t3lib_BEfunc::editOnClick(). Value can be seen modified internally (converting NEW keyword to id, workspace/versioning etc).
109 var $columnsOnly; // Commalist of fieldnames to edit. The point is IF you specify this list, only those fields will be rendered in the form. Otherwise all (available) fields in the record is shown according to the types configuration in $TCA
110 var $defVals; // Default values for fields (array with tablenames, fields etc. as keys). Can be seen modified internally.
111 var $overrideVals; // Array of values to force being set (as hidden fields). Will be set as $this->defVals IF defVals does not exist.
112 var $returnUrl; // If set, this value will be set in $this->retUrl (which is used quite many places as the return URL). If not set, "dummy.php" will be set in $this->retUrl
113 var $closeDoc; // Close-document command. Not really sure of all options...
114 var $doSave; // Quite simply, if this variable is set, then the processing of incoming data will be performed - as if a save-button is pressed. Used in the forms as a hidden field which can be set through JavaScript if the form is somehow submitted by JavaScript).
116 var $data; // GPvar (for processing only) : The data array from which the data comes...
117 var $mirror; // GPvar (for processing only) : ?
118 var $cacheCmd; // GPvar (for processing only) : Clear-cache cmd.
119 var $redirect; // GPvar (for processing only) : Redirect (not used???)
120 var $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.
121 var $vC; // GPvar (for processing only) : Verification code, internal stuff.
122 var $uc; // GPvar : update BE_USER->uc
124 var $popViewId; // GPvar (module) : ID for displaying the page in the frontend (used for SAVE/VIEW operations)
125 var $popViewId_addParams; // GPvar (module) : Additional GET vars for the link, eg. "&L=xxx"
126 var $viewUrl; // GPvar (module) : Alternative URL for viewing the frontend pages.
127 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!
128 var $recTitle; // Alternative title for the document handler.
129 var $disHelp; // Disable help... ?
130 var $noView; // If set, then no SAVE/VIEW button is printed
131 var $returnEditConf; // If set, the $this->editconf array is returned to the calling script (used by wizard_add.php for instance)
132 var $localizationMode; // GP var, localization mode for TCEforms (eg. "text")
137 * document template object
142 var $template; // a static HTML template, usually in templates/alt_doc.html
143 var $content; // Content accumulation
145 var $retUrl; // Return URL script, processed. This contains the script (if any) that we should RETURN TO from the alt_doc.php script IF we press the close button. Thus this variable is normally passed along from the calling script so we can properly return if needed.
146 var $R_URL_parts; // Contains the parts of the REQUEST_URI (current url). By parts we mean the result of resolving REQUEST_URI (current url) by the parse_url() function. The result is an array where eg. "path" is the script path and "query" is the parameters...
147 var $R_URL_getvars; // Contains the current GET vars array; More specifically this array is the foundation for creating the R_URI internal var (which becomes the "url of this script" to which we submit the forms etc.)
148 var $R_URI; // Set to the URL of this script including variables which is needed to re-display the form. See main()
150 var $storeTitle; // Is loaded with the "title" of the currently "open document" - this is used in the Document Selector box. (see makeDocSel())
151 var $storeArray; // Contains an array with key/value pairs of GET parameters needed to reach the current document displayed - used in the Document Selector box. (see compileStoreDat())
152 var $storeUrl; // Contains storeArray, but imploded into a GET parameter string (see compileStoreDat())
153 var $storeUrlMd5; // Hashed value of storeURL (see compileStoreDat())
155 var $docDat; // Module session data
156 var $docHandler; // An array of the "open documents" - keys are md5 hashes (see $storeUrlMd5) identifying the various documents on the GET parameter list needed to open it. The values are arrays with 0,1,2 keys with information about the document (see compileStoreDat()). The docHandler variable is stored in the $docDat session data, key "0".
159 // Internal: Related to the form rendering:
160 var $elementsData; // Array of the elements to create edit forms for.
161 var $firstEl; // Pointer to the first element in $elementsData
162 var $errorC; // Counter, used to count the number of errors (when users do not have edit permissions)
163 var $newC; // Counter, used to count the number of new record forms displayed
164 var $viewId; // Is set to the pid value of the last shown record - thus indicating which page to show when clicking the SAVE/VIEW button
165 var $viewId_addParams; // Is set to additional parameters (like "&L=xxx") if the record supports it.
166 var $modTSconfig; // Module TSconfig, loaded from main() based on the page id value of viewId
169 * instance of TCEforms class
171 * @var t3lib_TCEforms
174 var $generalPathOfForm; // Contains the root-line path of the currently edited record(s) - for display.
177 // Internal, dynamic:
178 var $dontStoreDocumentRef; // Used internally to disable the storage of the document reference (eg. new records)
187 * First initialization.
194 if (t3lib_div
::_GP('justLocalized')) {
195 $this->localizationRedirect(t3lib_div
::_GP('justLocalized'));
199 $this->editconf
= t3lib_div
::_GP('edit');
200 $this->defVals
= t3lib_div
::_GP('defVals');
201 $this->overrideVals
= t3lib_div
::_GP('overrideVals');
202 $this->columnsOnly
= t3lib_div
::_GP('columnsOnly');
203 $this->returnUrl
= t3lib_div
::_GP('returnUrl');
204 $this->closeDoc
= t3lib_div
::_GP('closeDoc');
205 $this->doSave
= t3lib_div
::_GP('doSave');
206 $this->returnEditConf
= t3lib_div
::_GP('returnEditConf');
207 $this->localizationMode
= t3lib_div
::_GP('localizationMode');
208 $this->uc
= t3lib_div
::_GP('uc');
211 // Setting override values as default if defVals does not exist.
212 if (!is_array($this->defVals
) && is_array($this->overrideVals
)) {
213 $this->defVals
= $this->overrideVals
;
216 // Setting return URL
217 $this->retUrl
= $this->returnUrl ?
$this->returnUrl
: 'dummy.php';
219 // Fix $this->editconf if versioning applies to any of the records
220 $this->fixWSversioningInEditConf();
222 // Make R_URL (request url) based on input GETvars:
223 $this->R_URL_parts
= parse_url(t3lib_div
::getIndpEnv('REQUEST_URI'));
224 $this->R_URL_getvars
= t3lib_div
::_GET();
225 $this->R_URL_getvars
['edit'] = $this->editconf
;
227 // MAKE url for storing
228 $this->compileStoreDat();
230 // Initialize more variables.
231 $this->dontStoreDocumentRef
=0;
232 $this->storeTitle
='';
234 // Get session data for the module:
235 $this->docDat
= $BE_USER->getModuleData('alt_doc.php','ses');
236 $this->docHandler
= $this->docDat
[0];
238 // If a request for closing the document has been sent, act accordingly:
239 if ($this->closeDoc
>0) {
240 $this->closeDocument($this->closeDoc
);
243 // If NO vars are sent to the script, try to read first document:
244 if (is_array($this->R_URL_getvars
) && count($this->R_URL_getvars
)<2 && !is_array($this->editconf
)) { // Added !is_array($this->editconf) because editConf must not be set either. Anyways I can't figure out when this situation here will apply...
245 $this->setDocument($this->docDat
[1]);
251 * Detects, if a save command has been triggered.
253 * @return boolean True, then save the document (data submitted)
255 function doProcessData() {
256 $out = $this->doSave ||
isset($_POST['_savedok_x']) ||
isset($_POST['_saveandclosedok_x']) ||
isset($_POST['_savedokview_x']) ||
isset($_POST['_savedoknew_x']) ||
isset($_POST['_translation_savedok_x']);
262 * Do processing of data, submitting it to TCEmain.
266 function processData() {
267 global $BE_USER,$TYPO3_CONF_VARS;
269 // GPvars specifically for processing:
270 $this->data
= t3lib_div
::_GP('data');
271 $this->cmd
= t3lib_div
::_GP('cmd');
272 $this->mirror
= t3lib_div
::_GP('mirror');
273 $this->cacheCmd
= t3lib_div
::_GP('cacheCmd');
274 $this->redirect
= t3lib_div
::_GP('redirect');
275 $this->returnNewPageId
= t3lib_div
::_GP('returnNewPageId');
276 $this->vC
= t3lib_div
::_GP('vC');
278 // See tce_db.php for relevate options here:
279 // Only options related to $this->data submission are included here.
280 $tce = t3lib_div
::makeInstance('t3lib_TCEmain');
281 $tce->stripslashes_values
=0;
282 if (isset($_POST['_translation_savedok_x'])) {
283 $tce->updateModeL10NdiffData
= 'FORCE_FFUPD';
286 // Setting default values specific for the user:
287 $TCAdefaultOverride = $BE_USER->getTSConfigProp('TCAdefaults');
288 if (is_array($TCAdefaultOverride)) {
289 $tce->setDefaultsFromUserTS($TCAdefaultOverride);
292 // Setting internal vars:
293 if ($BE_USER->uc
['neverHideAtCopy']) {
294 $tce->neverHideAtCopy
= 1;
297 $tce->disableRTE
= !$BE_USER->isRTE();
299 // Loading TCEmain with data:
300 $tce->start($this->data
,$this->cmd
);
301 if (is_array($this->mirror
)) {
302 $tce->setMirror($this->mirror
);
305 // If pages are being edited, we set an instruction about updating the page tree after this operation.
306 if (isset($this->data
['pages'])) {
307 t3lib_BEfunc
::setUpdateSignal('updatePageTree');
311 // Checking referer / executing
312 $refInfo=parse_url(t3lib_div
::getIndpEnv('HTTP_REFERER'));
313 $httpHost = t3lib_div
::getIndpEnv('TYPO3_HOST_ONLY');
314 if ($httpHost!=$refInfo['host'] && $this->vC
!=$BE_USER->veriCode() && !$TYPO3_CONF_VARS['SYS']['doNotCheckReferer']) {
315 $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));
316 debug('Error: Referer host did not match with server host.');
319 // Perform the saving operation with TCEmain:
320 $tce->process_uploads($_FILES);
321 $tce->process_datamap();
322 $tce->process_cmdmap();
324 // If there was saved any new items, load them:
325 if (count($tce->substNEWwithIDs_table
)) {
326 // save the expanded/collapsed states for new inline records, if any
327 t3lib_TCEforms_inline
::updateInlineView($this->uc
, $tce);
329 $newEditConf = array();
331 foreach($this->editconf
as $tableName => $tableCmds) {
332 $keys = array_keys($tce->substNEWwithIDs_table
, $tableName);
333 if(count($keys) > 0) {
334 foreach($keys as $key) {
335 $editId = $tce->substNEWwithIDs
[$key];
336 // check if the $editId isn't a child record of an IRRE action
337 if (!(is_array($tce->newRelatedIDs
[$tableName]) && in_array($editId, $tce->newRelatedIDs
[$tableName]))) {
338 // translate new id to the workspace version:
339 if ($versionRec = t3lib_BEfunc
::getWorkspaceVersionOfRecord($GLOBALS['BE_USER']->workspace
, $tableName, $editId,'uid')) {
340 $editId = $versionRec['uid'];
342 $newEditConf[$tableName][$editId] = 'edit';
345 // Traverse all new records and forge the content of ->editconf so we can continue to EDIT these records!
346 if ($tableName=='pages' && $this->retUrl
!='dummy.php' && $this->returnNewPageId
) {
347 $this->retUrl
.='&id='.$tce->substNEWwithIDs
[$key];
351 $newEditConf[$tableName] = $tableCmds;
355 // Resetting editconf if newEditConf has values:
356 if (count($newEditConf)) {
357 $this->editconf
= $newEditConf;
360 // Finally, set the editconf array in the "getvars" so they will be passed along in URLs as needed.
361 $this->R_URL_getvars
['edit']=$this->editconf
;
363 // Unsetting default values since we don't need them anymore.
364 unset($this->R_URL_getvars
['defVals']);
366 // Re-compile the store* values since editconf changed...
367 $this->compileStoreDat();
370 // See if any records was auto-created as new versions?
371 if (count($tce->autoVersionIdMap
)) {
372 $this->fixWSversioningInEditConf($tce->autoVersionIdMap
);
375 // If a document is saved and a new one is created right after.
376 if (isset($_POST['_savedoknew_x']) && is_array($this->editconf
)) {
378 // Finding the current table:
379 reset($this->editconf
);
380 $nTable=key($this->editconf
);
382 // Finding the first id, getting the records pid+uid
383 reset($this->editconf
[$nTable]);
384 $nUid=key($this->editconf
[$nTable]);
385 $nRec = t3lib_BEfunc
::getRecord($nTable,$nUid,'pid,uid');
387 // Setting a blank editconf array for a new record:
388 $this->editconf
=array();
389 if ($this->getNewIconMode($nTable)=='top') {
390 $this->editconf
[$nTable][$nRec['pid']]='new';
392 $this->editconf
[$nTable][-$nRec['uid']]='new';
395 // Finally, set the editconf array in the "getvars" so they will be passed along in URLs as needed.
396 $this->R_URL_getvars
['edit']=$this->editconf
;
398 // Re-compile the store* values since editconf changed...
399 $this->compileStoreDat();
402 $tce->printLogErrorMessages(
403 isset($_POST['_saveandclosedok_x']) ?
405 $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?
408 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!
409 $this->closeDocument(abs($this->closeDoc
));
414 * Initialize the normal module operation
419 global $BE_USER,$LANG,$BACK_PATH;
421 // Setting more GPvars:
422 $this->popViewId
= t3lib_div
::_GP('popViewId');
423 $this->popViewId_addParams
= t3lib_div
::_GP('popViewId_addParams');
424 $this->viewUrl
= t3lib_div
::_GP('viewUrl');
425 $this->editRegularContentFromId
= t3lib_div
::_GP('editRegularContentFromId');
426 $this->recTitle
= t3lib_div
::_GP('recTitle');
427 $this->disHelp
= t3lib_div
::_GP('disHelp');
428 $this->noView
= t3lib_div
::_GP('noView');
430 $this->perms_clause
= $BE_USER->getPagePermsClause(1);
432 // Set other internal variables:
433 $this->R_URL_getvars
['returnUrl']=$this->retUrl
;
434 $this->R_URI
= $this->R_URL_parts
['path'].'?'.t3lib_div
::implodeArrayForUrl('',$this->R_URL_getvars
);
437 // If array, then it's a selector box menu
438 // If empty string it's just a variable, that'll be saved.
439 // Values NOT in this array will not be saved in the settings-array for the module.
440 $this->MOD_MENU
= array(
444 // Setting virtual document name
445 $this->MCONF
['name']='xMOD_alt_doc.php';
448 $this->MOD_SETTINGS
= t3lib_BEfunc
::getModuleData($this->MOD_MENU
, t3lib_div
::_GP('SET'), $this->MCONF
['name']);
450 // Create an instance of the document template object
451 $this->doc
= t3lib_div
::makeInstance('template');
452 $this->doc
->backPath
= $BACK_PATH;
453 $this->doc
->setModuleTemplate('templates/alt_doc.html');
454 $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);">';
456 $this->doc
->loadJavascriptLib('contrib/prototype/prototype.js');
457 $this->doc
->JScode
= $this->doc
->wrapScriptTags('
458 function jumpToUrl(URL,formEl) { //
459 if (!TBE_EDITOR.isFormChanged()) {
460 window.location.href = URL;
461 } else if (formEl && formEl.type=="checkbox") {
462 formEl.checked = formEl.checked ? 0 : 1;
466 function typoSetup () { //
469 var TS = new typoSetup();
472 function launchView(table,uid,bP) { //
473 var backPath= bP ? bP : "";
474 var thePreviewWindow="";
475 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");
476 if (thePreviewWindow && thePreviewWindow.focus) {
477 thePreviewWindow.focus();
480 function deleteRecord(table,id,url) { //
482 '.($GLOBALS['BE_USER']->jsConfirmation(4)?
'confirm('.$LANG->JScharCode($LANG->getLL('deleteWarning')).')':'1==1').'
484 window.location.href = "tce_db.php?cmd["+table+"]["+id+"][delete]=1&redirect="+escape(url)+"&vC='.$BE_USER->veriCode().'&prErr=1&uPT=1";
488 '.(isset($_POST['_savedokview_x']) && $this->popViewId ?
489 'if (window.opener) { '.
490 t3lib_BEfunc
::viewOnClick($this->popViewId
,'',t3lib_BEfunc
::BEgetRootLine($this->popViewId
),'',$this->viewUrl
,$this->popViewId_addParams
,FALSE).
492 t3lib_BEfunc
::viewOnClick($this->popViewId
,'',t3lib_BEfunc
::BEgetRootLine($this->popViewId
),'',$this->viewUrl
,$this->popViewId_addParams
).
495 ).$this->doc
->getDynTabMenuJScode();
497 // Setting up the context sensitive menu:
498 $this->doc
->getContextMenuCode();
499 $this->doc
->bodyTagAdditions
= 'onload="window.scrollTo(0,'.t3lib_div
::intInRange(t3lib_div
::_GP('_scrollPosition'),0,10000).');"';
503 * Main module operation
508 global $BE_USER,$LANG;
511 if (is_array($this->editconf
)) {
513 // Initialize TCEforms (rendering the forms)
514 $this->tceforms
= t3lib_div
::makeInstance('t3lib_TCEforms');
515 $this->tceforms
->initDefaultBEMode();
516 $this->tceforms
->doSaveFieldName
= 'doSave';
517 $this->tceforms
->localizationMode
= t3lib_div
::inList('text,media',$this->localizationMode
) ?
$this->localizationMode
: ''; // text,media is keywords defined in TYPO3 Core API..., see "l10n_cat"
518 $this->tceforms
->returnUrl
= $this->R_URI
;
519 $this->tceforms
->palettesCollapsed
= !$this->MOD_SETTINGS
['showPalettes'];
520 $this->tceforms
->disableRTE
= !$BE_USER->isRTE();
521 $this->tceforms
->enableClickMenu
= TRUE;
522 $this->tceforms
->enableTabMenu
= TRUE;
524 // Clipboard is initialized:
525 $this->tceforms
->clipObj
= t3lib_div
::makeInstance('t3lib_clipboard'); // Start clipboard
526 $this->tceforms
->clipObj
->initializeClipboard(); // Initialize - reads the clipboard content from the user session
528 // Setting external variables:
529 $this->tceforms
->edit_showFieldHelp
= $BE_USER->uc
['edit_showFieldHelp'];
531 if ($this->editRegularContentFromId
) {
532 $this->editRegularContentFromId();
536 // Creating the editing form, wrap it with buttons, document selector etc.
537 $editForm = $this->makeEditForm();
540 $this->firstEl
= reset($this->elementsData
);
542 // Checking if the currently open document is stored in the list of "open documents" - if not, then add it:
543 if ((strcmp($this->docDat
[1], $this->storeUrlMd5
) ||
!isset($this->docHandler
[$this->storeUrlMd5
])) && !$this->dontStoreDocumentRef
) {
544 $this->docHandler
[$this->storeUrlMd5
] = array($this->storeTitle
, $this->storeArray
, $this->storeUrl
, $this->firstEl
);
545 $BE_USER->pushModuleData('alt_doc.php', array($this->docHandler
, $this->storeUrlMd5
));
546 t3lib_BEfunc
::setUpdateSignal('tx_opendocs::updateNumber', count($this->docHandler
));
550 // Module configuration
551 $this->modTSconfig
= ($this->viewId ? t3lib_BEfunc
::getModTSconfig($this->viewId
,'mod.xMOD_alt_doc') : array());
553 $body.= $this->tceforms
->printNeededJSFunctions_top();
554 $body.= $this->compileForm($editForm);
555 $body.= $this->tceforms
->printNeededJSFunctions();
556 $body.= $this->functionMenus();
557 $body.= $this->tceformMessages();
562 // The page will show only if there is a valid page and if this page may be viewed by the user
563 $this->pageinfo
= t3lib_BEfunc
::readPageAccess($this->viewId
, $this->perms_clause
);
565 // Setting up the buttons and markers for docheader
566 $docHeaderButtons = $this->getButtons();
568 'LANGSELECTOR' => $this->langSelector(),
569 'EXTRAHEADER' => $this->extraFormHeaders(),
570 'CSH' => $docHeaderButtons['csh'],
574 // Build the <body> for the module
575 $this->content
= $this->doc
->startPage('TYPO3 Edit Document');
576 $this->content
.= $this->doc
->moduleBody($this->pageinfo
, $docHeaderButtons, $markers);
577 $this->content
.= $this->doc
->endPage();
578 $this->content
= $this->doc
->insertStylesAndJS($this->content
);
583 * Outputting the accumulated content to screen
587 function printContent() {
610 /***************************
612 * Sub-content functions, rendering specific parts of the module content.
614 ***************************/
617 * Creates the editing form with TCEforms, based on the input from GPvars.
619 * @return string HTML form elements wrapped in tables
621 function makeEditForm() {
622 global $BE_USER,$LANG,$TCA;
624 // Initialize variables:
625 $this->elementsData
=array();
631 // Traverse the GPvar edit array
632 foreach($this->editconf
as $table => $conf) { // Tables:
633 if (is_array($conf) && $TCA[$table] && $BE_USER->check('tables_modify',$table)) {
635 // Traverse the keys/comments of each table (keys can be a commalist of uids)
636 foreach($conf as $cKey => $cmd) {
637 if ($cmd=='edit' ||
$cmd=='new') {
640 $ids = t3lib_div
::trimExplode(',',$cKey,1);
643 foreach($ids as $theUid) {
645 // 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...)
646 // First, resetting flags.
648 $deniedAccessReason = '';
652 // If the command is to create a NEW record...:
654 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.
656 // Find parent page on which the new record reside
657 if ($theUid<0) { // Less than zero - find parent page
658 $calcPRec=t3lib_BEfunc
::getRecord($table,abs($theUid));
659 $calcPRec=t3lib_BEfunc
::getRecord('pages',$calcPRec['pid']);
660 } else { // always a page
661 $calcPRec=t3lib_BEfunc
::getRecord('pages',abs($theUid));
664 // Now, calculate whether the user has access to creating new records on this position:
665 if (is_array($calcPRec)) {
666 $CALC_PERMS = $BE_USER->calcPerms($calcPRec); // Permissions for the parent page
667 if ($table=='pages') { // If pages:
668 $hasAccess = $CALC_PERMS&8 ?
1 : 0;
669 $this->viewId
= $calcPRec['pid'];
671 $hasAccess = $CALC_PERMS&16 ?
1 : 0;
672 $this->viewId
= $calcPRec['uid'];
676 $this->dontStoreDocumentRef
=1; // Don't save this document title in the document selector if the document is new.
678 $calcPRec = t3lib_BEfunc
::getRecord($table,$theUid);
679 t3lib_BEfunc
::fixVersioningPid($table,$calcPRec);
680 if (is_array($calcPRec)) {
681 if ($table=='pages') { // If pages:
682 $CALC_PERMS = $BE_USER->calcPerms($calcPRec);
683 $hasAccess = $CALC_PERMS&2 ?
1 : 0;
684 $deleteAccess = $CALC_PERMS&4 ?
1 : 0;
685 $this->viewId
= $calcPRec['uid'];
687 $CALC_PERMS = $BE_USER->calcPerms(t3lib_BEfunc
::getRecord('pages',$calcPRec['pid'])); // Fetching pid-record first.
688 $hasAccess = $CALC_PERMS&16 ?
1 : 0;
689 $deleteAccess = $CALC_PERMS&16 ?
1 : 0;
690 $this->viewId
= $calcPRec['pid'];
692 // Adding "&L=xx" if the record being edited has a languageField with a value larger than zero!
693 if ($TCA[$table]['ctrl']['languageField'] && $calcPRec[$TCA[$table]['ctrl']['languageField']]>0) {
694 $this->viewId_addParams
= '&L='.$calcPRec[$TCA[$table]['ctrl']['languageField']];
698 // Check internals regarding access:
700 $hasAccess = $BE_USER->recordEditAccessInternals($table, $calcPRec);
701 $deniedAccessReason = $BE_USER->errorMsg
;
703 } else $hasAccess = 0;
706 // 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:
709 $prevPageID = is_object($trData)?
$trData->prevPageID
:'';
710 $trData = t3lib_div
::makeInstance('t3lib_transferData');
711 $trData->addRawData
= TRUE;
712 $trData->defVals
= $this->defVals
;
713 $trData->lockRecords
=1;
714 $trData->disableRTE
= !$BE_USER->isRTE();
715 $trData->prevPageID
= $prevPageID;
716 $trData->fetchRecord($table,$theUid,$cmd=='new'?
'new':''); // 'new'
717 reset($trData->regTableItems_data
);
718 $rec = current($trData->regTableItems_data
);
719 $rec['uid'] = $cmd=='new' ?
uniqid('NEW') : $theUid;
721 $rec['pid'] = $theUid=='prev'?
$thePrevUid:$theUid;
723 $this->elementsData
[]=array(
725 'uid' => $rec['uid'],
726 'pid' => $rec['pid'],
728 'deleteAccess' => $deleteAccess
731 // Now, render the form:
732 if (is_array($rec)) {
734 // Setting visual path / title of form:
735 $this->generalPathOfForm
= $this->tceforms
->getRecordPath($table,$rec);
736 if (!$this->storeTitle
) {
737 $this->storeTitle
= $this->recTitle ?
htmlspecialchars($this->recTitle
) : t3lib_BEfunc
::getRecordTitle($table,$rec,TRUE);
740 // Setting variables in TCEforms object:
741 $this->tceforms
->hiddenFieldList
= '';
742 $this->tceforms
->globalShowHelp
= $this->disHelp ?
0 : 1;
743 if (is_array($this->overrideVals
[$table])) {
744 $this->tceforms
->hiddenFieldListArr
= array_keys($this->overrideVals
[$table]);
747 // Register default language labels, if any:
748 $this->tceforms
->registerDefaultLanguageData($table,$rec);
750 // Create form for the record (either specific list of fields or the whole record):
752 if ($this->columnsOnly
) {
753 if(is_array($this->columnsOnly
)){
754 $panel.= $this->tceforms
->getListedFields($table,$rec,$this->columnsOnly
[$table]);
756 $panel.= $this->tceforms
->getListedFields($table,$rec,$this->columnsOnly
);
759 $panel.= $this->tceforms
->getMainFields($table,$rec);
761 $panel = $this->tceforms
->wrapTotal($panel,$rec,$table);
763 // Setting the pid value for new records:
765 $panel.= '<input type="hidden" name="data['.$table.']['.$rec['uid'].'][pid]" value="'.$rec['pid'].'" />';
769 // Display "is-locked" message:
770 if ($lockInfo = t3lib_BEfunc
::isRecordLocked($table,$rec['uid'])) {
773 <!-- Warning box: -->
774 <table border="0" cellpadding="0" cellspacing="0" class="warningbox">
776 <td><img'.t3lib_iconWorks
::skinImg($this->doc
->backPath
,'gfx/recordlock_warning3.gif','width="17" height="12"').' alt="" /></td>
777 <td>'.htmlspecialchars($lockInfo['msg']).'</td>
781 } else $lockIcon = '';
784 $editForm.= $lockIcon.$panel;
787 $thePrevUid = $rec['uid'];
790 $editForm.=$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.noEditPermission',1).'<br /><br />'.
791 ($deniedAccessReason ?
'Reason: '.htmlspecialchars($deniedAccessReason).'<br/><br/>' : '');
803 * Create the panel of buttons for submitting the form or otherwise perform operations.
805 * @return array all available buttons as an assoc. array
807 protected function getButtons() {
818 'columns_only' => '',
822 // Render SAVE type buttons:
823 // The action of each button is decided by its name attribute. (See doProcessData())
824 if (!$this->errorC
&& !$TCA[$this->firstEl
['table']]['ctrl']['readOnly']) {
827 $buttons['save'] = '<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).'" />';
829 // SAVE / VIEW button:
830 if ($this->viewId
&& !$this->noView
&& t3lib_extMgm
::isLoaded('cms')) {
831 $buttons['save_view'] = '<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).'" />';
834 // SAVE / NEW button:
835 if (count($this->elementsData
)==1 && $this->getNewIconMode($this->firstEl
['table'])) {
836 $buttons['save_new'] = '<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).'" />';
840 $buttons['save_close'] = '<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).'" />';
842 // FINISH TRANSLATION / SAVE / CLOSE
843 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['explicitConfirmationOfTranslation']) {
844 $buttons['translation_save'] = '<input type="image" class="c-inputButton" name="_translation_savedok"'.t3lib_iconWorks
::skinImg($this->doc
->backPath
,'gfx/translationsavedok.gif','').' title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:rm.translationSaveDoc',1).'" />';
849 $buttons['close'] = '<a href="#" onclick="document.editform.closeDoc.value=1; document.editform.submit(); return false;">'.
850 '<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="" />'.
854 // DELETE + UNDO buttons:
855 if (!$this->errorC
&& !$TCA[$this->firstEl
['table']]['ctrl']['readOnly'] && count($this->elementsData
)==1) {
856 if ($this->firstEl
['cmd']!='new' && t3lib_div
::testInt($this->firstEl
['uid'])) {
859 if ($this->firstEl
['deleteAccess'] && !$TCA[$this->firstEl
['table']]['ctrl']['readOnly'] && !$this->getNewIconMode($this->firstEl
['table'],'disableDelete')) {
860 $aOnClick = 'return deleteRecord(\''.$this->firstEl
['table'].'\',\''.$this->firstEl
['uid'].'\',unescape(\''.rawurlencode($this->retUrl
).'\'));';
861 $buttons['delete'] = '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.
862 '<img'.t3lib_iconWorks
::skinImg($this->doc
->backPath
,'gfx/deletedok.gif','width="21" height="16"').' class="c-inputButton" title="'.$LANG->getLL('deleteItem',1).'" alt="" />'.
867 $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');
868 if ($undoButtonR = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($undoRes)) {
869 $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;';
870 $buttons['undo'] = '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.
871 '<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="" />'.
874 if ($this->getNewIconMode($this->firstEl
['table'],'showHistory')) {
875 $aOnClick = 'window.location.href=\'show_rechis.php?element='.rawurlencode($this->firstEl
['table'].':'.$this->firstEl
['uid']).'&returnUrl='.rawurlencode($this->R_URI
).'\'; return false;';
876 $buttons['history'] = '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.
877 '<img'.t3lib_iconWorks
::skinImg($this->doc
->backPath
,'gfx/history2.gif','width="13" height="12"').' class="c-inputButton" alt="" />'.
881 // If only SOME fields are shown in the form, this will link the user to the FULL form:
882 if ($this->columnsOnly
) {
883 $buttons['columns_only'] = '<a href="'.htmlspecialchars($this->R_URI
.'&columnsOnly=').'">'.
884 '<img'.t3lib_iconWorks
::skinImg($this->doc
->backPath
,'gfx/edit2.gif','width="11" height="12"').' class="c-inputButton" title="'.$LANG->getLL('editWholeRecord',1).'" alt="" />'.
891 $buttons['csh'] = t3lib_BEfunc
::cshItem('xMOD_csh_corebe', 'TCEforms', $GLOBALS['BACK_PATH'], '', TRUE);
892 $buttons['shortcut'] = $this->shortCutLink();
893 $buttons['open_in_new_window'] = $this->openInNewWindowLink();
898 * Returns the language switch/selector for editing,
899 * show only when a single record is edited
900 * - multiple records are too confusing
901 * @return string the HTML
903 function langSelector() {
905 if (count($this->elementsData
) == 1) {
906 $langSelector = $this->languageSwitch($this->firstEl
['table'], $this->firstEl
['uid'], $this->firstEl
['pid']);
908 return $langSelector;
913 * Compiles the extra form headers if the tceforms
915 * @return string the HTML
917 function extraFormHeaders() {
920 if (is_array($this->tceforms
->extraFormHeaders
)) {
921 $extraTemplate = t3lib_parsehtml
::getSubpart($this->doc
->moduleTemplate
, '###DOCHEADER_EXTRAHEADER###');
922 $extraTemplate = t3lib_parsehtml
::substituteMarker($extraTemplate, '###EXTRAHEADER###', implode(chr(10), $this->tceforms
->extraFormHeaders
));
924 return $extraTemplate;
929 * Put together the various elements (buttons, selectors, form) into a table
931 * @param string HTML form.
932 * @return string Composite HTML
934 function compileForm($editForm) {
938 <!-- EDITING FORM -->
941 <input type="hidden" name="returnUrl" value="'.htmlspecialchars($this->retUrl
).'" />
942 <input type="hidden" name="viewUrl" value="'.htmlspecialchars($this->viewUrl
).'" />';
944 if ($this->returnNewPageId
) {
945 $formContent .= '<input type="hidden" name="returnNewPageId" value="1" />';
947 $formContent .= '<input type="hidden" name="popViewId" value="'.htmlspecialchars($this->viewId
).'" />';
948 if ($this->viewId_addParams
) {
949 $formContent .= '<input type="hidden" name="popViewId_addParams" value="'.htmlspecialchars($this->viewId_addParams
).'" />';
952 <input type="hidden" name="closeDoc" value="0" />
953 <input type="hidden" name="doSave" value="0" />
954 <input type="hidden" name="_serialNumber" value="'.md5(microtime()).'" />
955 <input type="hidden" name="_scrollPosition" value="" />';
961 * Create the checkbox buttons in the bottom of the pages.
963 * @return string HTML for function menus.
965 function functionMenus() {
970 <!-- Function menus (checkboxes for selecting options): -->
971 <br />'.t3lib_BEfunc
::getFuncCheck('','SET[showPalettes]',$this->MOD_SETTINGS
['showPalettes'],'alt_doc.php',t3lib_div
::implodeArrayForUrl('',array_merge($this->R_URL_getvars
,array('SET'=>''))),'id="checkShowPalettes"').'<label for="checkShowPalettes">'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.showPalettes',1).'</label>';
976 * Create shortcut icon
980 function shortCutLink() {
981 global $BE_USER,$LANG;
983 if ($this->returnUrl
== 'close.html' ||
!$BE_USER->mayMakeShortcut()) {
986 return $this->doc
->makeShortcutIcon('returnUrl,edit,defVals,overrideVals,columnsOnly,returnNewPageId,editRegularContentFromId,disHelp,noView',implode(',',array_keys($this->MOD_MENU
)),$this->MCONF
['name'],1);
991 * Creates open-in-window link
995 function openInNewWindowLink() {
996 global $BE_USER, $LANG;
997 if ($this->returnUrl
== 'close.html') {
1000 $aOnClick = 'vHWin=window.open(\''.t3lib_div
::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;';
1001 return '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.
1002 '<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="" /></a>';
1007 * Reads comment messages from TCEforms and prints them in a HTML comment in the bottom of the page.
1011 function tceformMessages() {
1012 if (count($this->tceforms
->commentMessages
)) {
1013 $tceformMessages = '
1014 <!-- TCEFORM messages
1015 '.htmlspecialchars(implode(chr(10),$this->tceforms
->commentMessages
)).'
1019 return $tceformMessages;
1034 /***************************
1036 * Localization stuff
1038 ***************************/
1041 * Make selector box for creating new translation for a record or switching to edit the record in an existing language.
1042 * Displays only languages which are available for the current page.
1044 * @param string Table name
1045 * @param integer uid for which to create a new language
1046 * @param integer pid of the record
1047 * @return string <select> HTML element (if there were items for the box anyways...)
1049 function languageSwitch($table, $uid, $pid=NULL) {
1054 $languageField = $TCA[$table]['ctrl']['languageField'];
1055 $transOrigPointerField = $TCA[$table]['ctrl']['transOrigPointerField'];
1057 // table editable and activated for languages?
1058 if ($GLOBALS['BE_USER']->check('tables_modify',$table) && $languageField && $transOrigPointerField && !$TCA[$table]['ctrl']['transOrigPointerTable']) {
1061 $row = t3lib_befunc
::getRecord($table, $uid, 'pid');
1065 // get all avalibale languages for the page
1066 $langRows = $this->getLanguages($pid);
1068 // page available in other languages than default language?
1069 if (is_array($langRows) && count($langRows)>1) {
1071 $rowsByLang = array();
1072 $fetchFields = 'uid,'.$languageField.','.$transOrigPointerField;
1074 // get record in current language
1075 $rowCurrent = t3lib_befunc
::getRecord($table, $uid, $fetchFields);
1076 $currentLanguage = $rowCurrent[$languageField];
1078 if ($currentLanguage>-1) { // Disabled for records with [all] language!
1079 // get record in default language if needed
1080 if ($currentLanguage) {
1081 $rowsByLang[0] = t3lib_befunc
::getRecord($table, $rowCurrent[$transOrigPointerField], $fetchFields);
1083 $rowsByLang[0] = $rowCurrent;
1086 // get record in other languages to see what's already available
1087 $translations = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
1090 'pid='.intval($pid).
1091 ' AND '.$languageField.'>0'.
1092 ' AND '.$transOrigPointerField.'='.intval($rowsByLang[0]['uid']).
1093 t3lib_BEfunc
::deleteClause($table).
1094 t3lib_BEfunc
::versioningPlaceholderClause($table)
1096 foreach ($translations as $row) {
1097 $rowsByLang[$row[$languageField]] = $row;
1100 $langSelItems=array();
1101 foreach ($langRows as $lang) {
1102 if ($GLOBALS['BE_USER']->checkLanguageAccess($lang['uid'])) {
1104 $newTranslation = isset($rowsByLang[$lang['uid']]) ?
'' : ' ['.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:labels.new',1).']';
1106 // create url for creating a localized record
1107 if($newTranslation) {
1108 $href = $this->doc
->issueCommand(
1109 '&cmd['.$table.']['.$rowsByLang[0]['uid'].'][localize]='.$lang['uid'],
1110 $this->backPath
.'alt_doc.php?justLocalized='.rawurlencode($table.':'.$rowsByLang[0]['uid'].':'.$lang['uid']).'&returnUrl='.rawurlencode($this->retUrl
)
1115 $href = $this->backPath
.'alt_doc.php?';
1116 $href .= '&edit['.$table.']['.$rowsByLang[$lang['uid']]['uid'].']=edit';
1117 $href .= '&returnUrl='.rawurlencode($this->retUrl
);
1120 $langSelItems[$lang['uid']]='
1121 <option value="'.htmlspecialchars($href).'"'.($currentLanguage==$lang['uid']?
' selected="selected"':'').'>'.htmlspecialchars($lang['title'].$newTranslation).'</option>';
1125 // If any languages are left, make selector:
1126 if (count($langSelItems)>1) {
1127 $onChange = 'if(this.options[this.selectedIndex].value){window.location.href=(this.options[this.selectedIndex].value);}';
1128 $content = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_general.xml:LGL.language',1).' <select name="_langSelector" onchange="'.htmlspecialchars($onChange).'">
1129 '.implode('',$langSelItems).'
1140 * Redirects to alt_doc with new parameters to edit a just created localized record
1142 * @param string String passed by GET &justLocalized=
1145 function localizationRedirect($justLocalized) {
1148 list($table,$orig_uid,$language) = explode(':',$justLocalized);
1150 if ($TCA[$table] && $TCA[$table]['ctrl']['languageField'] && $TCA[$table]['ctrl']['transOrigPointerField']) {
1151 list($localizedRecord) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
1154 $TCA[$table]['ctrl']['languageField'].'='.intval($language).' AND '.
1155 $TCA[$table]['ctrl']['transOrigPointerField'].'='.intval($orig_uid).
1156 t3lib_BEfunc
::deleteClause($table).
1157 t3lib_BEfunc
::versioningPlaceholderClause($table)
1160 if (is_array($localizedRecord)) {
1161 // Create parameters and finally run the classic page module for creating a new page translation
1162 $params = '&edit['.$table.']['.$localizedRecord['uid'].']=edit';
1163 $returnUrl = '&returnUrl='.rawurlencode(t3lib_div
::_GP('returnUrl'));
1164 $location = $GLOBALS['BACK_PATH'].'alt_doc.php?'.$params.$returnUrl;
1166 header('Location: '.t3lib_div
::locationHeaderUrl($location));
1174 * Returns sys_language records.
1176 * @param integer Page id: If zero, the query will select all sys_language records from root level which are NOT hidden. If set to another value, the query will select all sys_language records that has a pages_language_overlay record on that page (and is not hidden, unless you are admin user)
1177 * @return array Language records including faked record for default language
1179 function getLanguages($id) {
1182 $modSharedTSconfig = t3lib_BEfunc
::getModTSconfig($id, 'mod.SHARED');
1189 'title' => strlen($modSharedTSconfig['properties']['defaultLanguageLabel']) ?
$modSharedTSconfig['properties']['defaultLanguageLabel'].' ('.$GLOBALS['LANG']->sl('LLL:EXT:lang/locallang_mod_web_list.xml:defaultLanguage').')' : $GLOBALS['LANG']->sl('LLL:EXT:lang/locallang_mod_web_list.xml:defaultLanguage'),
1190 'flag' => $modSharedTSconfig['properties']['defaultLanguageFlag'],
1194 $exQ = $GLOBALS['BE_USER']->isAdmin() ?
'' : ' AND sys_language.hidden=0';
1196 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
1198 'pages_language_overlay,sys_language',
1199 'pages_language_overlay.sys_language_uid=sys_language.uid AND pages_language_overlay.pid='.intval($id).$exQ,
1200 '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',
1201 'sys_language.title'
1204 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
1207 'sys_language.hidden=0',
1209 'sys_language.title'
1213 foreach ($rows as $row) {
1214 $languages[$row['uid']] = $row;
1229 /***************************
1233 ***************************/
1236 * Fix $this->editconf if versioning applies to any of the records
1238 * @param array Mapping between old and new ids if auto-versioning has been performed.
1241 function fixWSversioningInEditConf($mapArray=FALSE) {
1242 global $TCA,$BE_USER;
1244 // Traverse the editConf array
1245 if (is_array($this->editconf
)) {
1246 foreach($this->editconf
as $table => $conf) { // Tables:
1247 if (is_array($conf) && $TCA[$table]) {
1249 // Traverse the keys/comments of each table (keys can be a commalist of uids)
1251 foreach($conf as $cKey => $cmd) {
1253 // Traverse the ids:
1254 $ids = t3lib_div
::trimExplode(',', $cKey, 1);
1255 foreach($ids as $idKey => $theUid) {
1256 if (is_array($mapArray)) {
1257 if ($mapArray[$table][$theUid]) {
1258 $ids[$idKey] = $mapArray[$table][$theUid];
1260 } else { // Default, look for versions in workspace for record:
1261 $calcPRec = $this->getRecordForEdit($table,$theUid);
1262 if (is_array($calcPRec)) {
1263 // Setting UID again if it had changed, eg. due to workspace versioning.
1264 $ids[$idKey] = $calcPRec['uid'];
1267 #else unset($ids[$idKey]);
1270 // Add the possibly manipulated IDs to the new-build newConf array:
1271 $newConf[implode(',',$ids)] = $cmd;
1273 $newConf[$cKey] = $cmd;
1276 // Store the new conf array:
1277 $this->editconf
[$table] = $newConf;
1284 * Get record for editing.
1286 * @param string Table name
1287 * @param integer Record UID
1288 * @return array Returns record to edit, false if none
1290 function getRecordForEdit($table,$theUid) {
1293 // Fetch requested record:
1294 $reqRecord = t3lib_BEfunc
::getRecord($table,$theUid,'uid,pid');
1296 if (is_array($reqRecord)) {
1297 // If workspace is OFFLINE:
1298 if ($GLOBALS['BE_USER']->workspace
!=0) {
1300 // Check for versioning support of the table:
1301 if ($TCA[$table] && $TCA[$table]['ctrl']['versioningWS']) {
1303 // If the record is already a version of "something" pass it by.
1304 if ($reqRecord['pid']==-1) {
1306 // (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)
1308 } else { // The input record was online and an offline version must be found or made:
1310 // Look for version of this workspace:
1311 $versionRec = t3lib_BEfunc
::getWorkspaceVersionOfRecord($GLOBALS['BE_USER']->workspace
, $table, $reqRecord['uid'],'uid,pid,t3ver_oid');
1312 return is_array($versionRec) ?
$versionRec : $reqRecord;
1314 } 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.
1315 } else return $reqRecord; // In ONLINE workspace, just return the originally requested record:
1316 } else return FALSE; // Return false because the table/uid was not found anyway.
1320 * 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
1324 function editRegularContentFromId() {
1325 if (t3lib_extMgm
::isLoaded('cms')) {
1326 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1329 'pid='.intval($this->editRegularContentFromId
).
1330 t3lib_BEfunc
::deleteClause('tt_content').
1331 t3lib_BEfunc
::versioningPlaceholderClause('tt_content').
1332 ' AND colPos=0 AND sys_language_uid=0',
1336 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res)) {
1338 while($ecRec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
1339 $ecUids[]=$ecRec['uid'];
1341 $this->editconf
['tt_content'][implode(',',$ecUids)]='edit';
1347 * Populates the variables $this->storeArray, $this->storeUrl, $this->storeUrlMd5
1352 function compileStoreDat() {
1353 $this->storeArray
= t3lib_div
::compileSelectedGetVarsFromArray('edit,defVals,overrideVals,columnsOnly,disHelp,noView,editRegularContentFromId',$this->R_URL_getvars
);
1354 $this->storeUrl
= t3lib_div
::implodeArrayForUrl('',$this->storeArray
);
1355 $this->storeUrlMd5
= md5($this->storeUrl
);
1359 * Function used to look for configuration of buttons in the form: Fx. disabling buttons or showing them at various positions.
1361 * @param string The table for which the configuration may be specific
1362 * @param string The option for look for. Default is checking if the saveDocNew button should be displayed.
1363 * @return string Return value fetched from USER TSconfig
1365 function getNewIconMode($table,$key='saveDocNew') {
1367 $TSconfig = $BE_USER->getTSConfig('options.'.$key);
1368 $output = trim(isset($TSconfig['properties'][$table]) ?
$TSconfig['properties'][$table] : $TSconfig['value']);
1373 * Handling the closing of a document
1375 * @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
1378 function closeDocument($code=0) {
1381 // If current document is found in docHandler,
1382 // then unset it, possibly unset it ALL and finally, write it to the session data
1383 if (isset($this->docHandler
[$this->storeUrlMd5
])) {
1385 // add the closing document to the recent documents
1386 $recentDocs = $BE_USER->getModuleData('opendocs::recent');
1387 if (!is_array($recentDocs)) {
1388 $recentDocs = array();
1390 $closedDoc = $this->docHandler
[$this->storeUrlMd5
];
1391 $recentDocs = array_merge(array($this->storeUrlMd5
=> $closedDoc), $recentDocs);
1392 if (count($recentDocs) > 8) {
1393 $recentDocs = array_slice($recentDocs, 0, 8);
1396 // remove it from the list of the open documents
1397 unset($this->docHandler
[$this->storeUrlMd5
]);
1399 $recentDocs = array_merge($this->docHandler
, $recentDocs);
1400 $this->docHandler
= array();
1402 $BE_USER->pushModuleData('opendocs::recent', $recentDocs);
1403 $BE_USER->pushModuleData('alt_doc.php', array($this->docHandler
, $this->docDat
[1]));
1404 t3lib_BEfunc
::setUpdateSignal('tx_opendocs::updateNumber', count($this->docHandler
));
1408 // 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...)
1409 if ($this->returnEditConf
&& $this->retUrl
!='dummy.php') {
1410 $this->retUrl
.='&returnEditConf='.rawurlencode(serialize($this->editconf
));
1413 // If code is NOT set OR set to 1, then make a header location redirect to $this->retUrl
1414 if (!$code ||
$code==1) {
1415 Header('Location: '.t3lib_div
::locationHeaderUrl($this->retUrl
));
1418 $this->setDocument('',$this->retUrl
);
1423 * Redirects to the document pointed to by $currentDocFromHandlerMD5 OR $retUrl (depending on some internal calculations).
1424 * Most likely you will get a header-location redirect from this function.
1426 * @param string Pointer to the document in the docHandler array
1427 * @param string Alternative/Default retUrl
1430 function setDocument($currentDocFromHandlerMD5='',$retUrl='alt_doc_nodoc.php') {
1431 if (!t3lib_extMgm
::isLoaded('cms') && !strcmp($retUrl,'alt_doc_nodoc.php')) return;
1433 if (!$this->modTSconfig
['properties']['disableDocSelector'] && is_array($this->docHandler
) && count($this->docHandler
)) {
1434 if (isset($this->docHandler
[$currentDocFromHandlerMD5])) {
1435 $setupArr=$this->docHandler
[$currentDocFromHandlerMD5];
1437 reset($this->docHandler
);
1438 $setupArr=current($this->docHandler
);
1441 $sParts = parse_url(t3lib_div
::getIndpEnv('REQUEST_URI'));
1442 $retUrl = $sParts['path'].'?'.$setupArr[2].'&returnUrl='.rawurlencode($retUrl);
1445 Header('Location: '.t3lib_div
::locationHeaderUrl($retUrl));
1450 // Include extension?
1451 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE
]['XCLASS']['typo3/alt_doc.php']) {
1452 include_once($TYPO3_CONF_VARS[TYPO3_MODE
]['XCLASS']['typo3/alt_doc.php']);
1471 $SOBE = t3lib_div
::makeInstance('SC_alt_doc');
1473 // Preprocessing, storing data if submitted to
1475 if ($SOBE->doProcessData()) { // Checks, if a save button has been clicked (or the doSave variable is sent)
1476 $SOBE->processData();
1483 $SOBE->printContent();