|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com) 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00027 /** 00028 * Main form rendering script 00029 * By sending certain parameters to this script you can bring up a form 00030 * which allows the user to edit the content of one or more database records. 00031 * 00032 * $Id: alt_doc.php 10306 2011-01-25 19:12:05Z baschny $ 00033 * Revised for TYPO3 3.6 November/2003 by Kasper Skårhøj 00034 * XHTML compliant 00035 * 00036 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00037 */ 00038 /** 00039 * [CLASS/FUNCTION INDEX of SCRIPT] 00040 * 00041 * 00042 * 00043 * 105: class SC_alt_doc 00044 * 179: function preInit() 00045 * 241: function doProcessData() 00046 * 251: function processData() 00047 * 379: function init() 00048 * 473: function main() 00049 * 551: function printContent() 00050 * 00051 * SECTION: Sub-content functions, rendering specific parts of the module content. 00052 * 587: function makeEditForm() 00053 * 771: function makeButtonPanel() 00054 * 850: function makeDocSel() 00055 * 892: function makeCmenu() 00056 * 914: function compileForm($panel,$docSel,$cMenu,$editForm, $langSelector='') 00057 * 982: function functionMenus() 00058 * 1013: function shortCutLink() 00059 * 1044: function tceformMessages() 00060 * 00061 * SECTION: Localization stuff 00062 * 1083: function languageSwitch($table, $uid, $pid=NULL) 00063 * 1179: function localizationRedirect($justLocalized) 00064 * 1213: function getLanguages($id) 00065 * 00066 * SECTION: Other functions 00067 * 1275: function fixWSversioningInEditConf($mapArray=FALSE) 00068 * 1324: function getRecordForEdit($table,$theUid) 00069 * 1358: function editRegularContentFromId() 00070 * 1386: function compileStoreDat() 00071 * 1399: function getNewIconMode($table,$key='saveDocNew') 00072 * 1412: function closeDocument($code=0) 00073 * 1444: function setDocument($currentDocFromHandlerMD5='',$retUrl='alt_doc_nodoc.php') 00074 * 00075 * TOTAL FUNCTIONS: 24 00076 * (This index is automatically created/updated by the extension "extdeveval") 00077 * 00078 */ 00079 00080 00081 require_once('init.php'); 00082 require_once('template.php'); 00083 $GLOBALS['LANG']->includeLLFile('EXT:lang/locallang_alt_doc.xml'); 00084 00085 t3lib_BEfunc::lockRecords(); 00086 00087 00088 00089 00090 /** 00091 * Script Class: Drawing the editing form for editing records in TYPO3. 00092 * Notice: It does NOT use tce_db.php to submit data to, rather it handles submissions itself 00093 * 00094 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00095 * @package TYPO3 00096 * @subpackage core 00097 */ 00098 class SC_alt_doc { 00099 00100 // Internal, static: GPvars: 00101 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). 00102 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 00103 var $defVals; // Default values for fields (array with tablenames, fields etc. as keys). Can be seen modified internally. 00104 var $overrideVals; // Array of values to force being set (as hidden fields). Will be set as $this->defVals IF defVals does not exist. 00105 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 00106 var $closeDoc; // Close-document command. Not really sure of all options... 00107 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). 00108 00109 var $data; // GPvar (for processing only) : The data array from which the data comes... 00110 var $mirror; // GPvar (for processing only) : ? 00111 var $cacheCmd; // GPvar (for processing only) : Clear-cache cmd. 00112 var $redirect; // GPvar (for processing only) : Redirect (not used???) 00113 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. 00114 var $vC; // GPvar (for processing only) : Verification code, internal stuff. 00115 var $uc; // GPvar : update BE_USER->uc 00116 00117 var $popViewId; // GPvar (module) : ID for displaying the page in the frontend (used for SAVE/VIEW operations) 00118 var $popViewId_addParams; // GPvar (module) : Additional GET vars for the link, eg. "&L=xxx" 00119 var $viewUrl; // GPvar (module) : Alternative URL for viewing the frontend pages. 00120 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! 00121 var $recTitle; // Alternative title for the document handler. 00122 var $disHelp; // Disable help... ? 00123 var $noView; // If set, then no SAVE/VIEW button is printed 00124 var $returnEditConf; // If set, the $this->editconf array is returned to the calling script (used by wizard_add.php for instance) 00125 var $localizationMode; // GP var, localization mode for TCEforms (eg. "text") 00126 00127 00128 // Internal, static: 00129 /** 00130 * document template object 00131 * 00132 * @var mediumDoc 00133 */ 00134 var $doc; 00135 var $template; // a static HTML template, usually in templates/alt_doc.html 00136 var $content; // Content accumulation 00137 00138 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. 00139 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... 00140 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.) 00141 var $R_URI; // Set to the URL of this script including variables which is needed to re-display the form. See main() 00142 00143 var $storeTitle; // Is loaded with the "title" of the currently "open document" - this is used in the Document Selector box. (see makeDocSel()) 00144 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()) 00145 var $storeUrl; // Contains storeArray, but imploded into a GET parameter string (see compileStoreDat()) 00146 var $storeUrlMd5; // Hashed value of storeURL (see compileStoreDat()) 00147 00148 var $docDat; // Module session data 00149 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". 00150 00151 00152 // Internal: Related to the form rendering: 00153 var $elementsData; // Array of the elements to create edit forms for. 00154 var $firstEl; // Pointer to the first element in $elementsData 00155 var $errorC; // Counter, used to count the number of errors (when users do not have edit permissions) 00156 var $newC; // Counter, used to count the number of new record forms displayed 00157 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 00158 var $viewId_addParams; // Is set to additional parameters (like "&L=xxx") if the record supports it. 00159 var $modTSconfig; // Module TSconfig, loaded from main() based on the page id value of viewId 00160 00161 /** 00162 * instance of TCEforms class 00163 * 00164 * @var t3lib_TCEforms 00165 */ 00166 var $tceforms; 00167 var $generalPathOfForm; // Contains the root-line path of the currently edited record(s) - for display. 00168 00169 00170 // Internal, dynamic: 00171 var $dontStoreDocumentRef; // Used internally to disable the storage of the document reference (eg. new records) 00172 00173 00174 00175 00176 00177 00178 00179 /** 00180 * First initialization. 00181 * 00182 * @return void 00183 */ 00184 function preInit() { 00185 global $BE_USER; 00186 00187 if (t3lib_div::_GP('justLocalized')) { 00188 $this->localizationRedirect(t3lib_div::_GP('justLocalized')); 00189 } 00190 00191 // Setting GPvars: 00192 $this->editconf = t3lib_div::_GP('edit'); 00193 $this->defVals = t3lib_div::_GP('defVals'); 00194 $this->overrideVals = t3lib_div::_GP('overrideVals'); 00195 $this->columnsOnly = t3lib_div::_GP('columnsOnly'); 00196 $this->returnUrl = t3lib_div::sanitizeLocalUrl(t3lib_div::_GP('returnUrl')); 00197 $this->closeDoc = t3lib_div::_GP('closeDoc'); 00198 $this->doSave = t3lib_div::_GP('doSave'); 00199 $this->returnEditConf = t3lib_div::_GP('returnEditConf'); 00200 $this->localizationMode = t3lib_div::_GP('localizationMode'); 00201 $this->uc = t3lib_div::_GP('uc'); 00202 00203 00204 // Setting override values as default if defVals does not exist. 00205 if (!is_array($this->defVals) && is_array($this->overrideVals)) { 00206 $this->defVals = $this->overrideVals; 00207 } 00208 00209 // Setting return URL 00210 $this->retUrl = $this->returnUrl ? $this->returnUrl : 'dummy.php'; 00211 00212 // Fix $this->editconf if versioning applies to any of the records 00213 $this->fixWSversioningInEditConf(); 00214 00215 // Make R_URL (request url) based on input GETvars: 00216 $this->R_URL_parts = parse_url(t3lib_div::getIndpEnv('REQUEST_URI')); 00217 $this->R_URL_getvars = t3lib_div::_GET(); 00218 $this->R_URL_getvars['edit'] = $this->editconf; 00219 00220 // MAKE url for storing 00221 $this->compileStoreDat(); 00222 00223 // Initialize more variables. 00224 $this->dontStoreDocumentRef=0; 00225 $this->storeTitle=''; 00226 00227 // Get session data for the module: 00228 $this->docDat = $BE_USER->getModuleData('alt_doc.php','ses'); 00229 $this->docHandler = $this->docDat[0]; 00230 00231 // If a request for closing the document has been sent, act accordingly: 00232 if ($this->closeDoc>0) { 00233 $this->closeDocument($this->closeDoc); 00234 } 00235 00236 // If NO vars are sent to the script, try to read first document: 00237 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... 00238 $this->setDocument($this->docDat[1]); 00239 } 00240 } 00241 00242 00243 /** 00244 * Detects, if a save command has been triggered. 00245 * 00246 * @return boolean True, then save the document (data submitted) 00247 */ 00248 function doProcessData() { 00249 $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']); 00250 return $out; 00251 } 00252 00253 00254 /** 00255 * Do processing of data, submitting it to TCEmain. 00256 * 00257 * @return void 00258 */ 00259 function processData() { 00260 global $BE_USER,$TYPO3_CONF_VARS; 00261 00262 // GPvars specifically for processing: 00263 $this->data = t3lib_div::_GP('data'); 00264 $this->cmd = t3lib_div::_GP('cmd'); 00265 $this->mirror = t3lib_div::_GP('mirror'); 00266 $this->cacheCmd = t3lib_div::_GP('cacheCmd'); 00267 $this->redirect = t3lib_div::_GP('redirect'); 00268 $this->returnNewPageId = t3lib_div::_GP('returnNewPageId'); 00269 $this->vC = t3lib_div::_GP('vC'); 00270 00271 // See tce_db.php for relevate options here: 00272 // Only options related to $this->data submission are included here. 00273 $tce = t3lib_div::makeInstance('t3lib_TCEmain'); 00274 $tce->stripslashes_values=0; 00275 00276 if (isset($_POST['_translation_savedok_x'])) { 00277 $tce->updateModeL10NdiffData = 'FORCE_FFUPD'; 00278 } 00279 if (isset($_POST['_translation_savedokclear_x'])) { 00280 $tce->updateModeL10NdiffData = 'FORCE_FFUPD'; 00281 $tce->updateModeL10NdiffDataClear = TRUE; 00282 } 00283 00284 // Setting default values specific for the user: 00285 $TCAdefaultOverride = $BE_USER->getTSConfigProp('TCAdefaults'); 00286 if (is_array($TCAdefaultOverride)) { 00287 $tce->setDefaultsFromUserTS($TCAdefaultOverride); 00288 } 00289 00290 // Setting internal vars: 00291 if ($BE_USER->uc['neverHideAtCopy']) { 00292 $tce->neverHideAtCopy = 1; 00293 } 00294 $tce->debug=0; 00295 $tce->disableRTE = !$BE_USER->isRTE(); 00296 00297 // Loading TCEmain with data: 00298 $tce->start($this->data,$this->cmd); 00299 if (is_array($this->mirror)) { 00300 $tce->setMirror($this->mirror); 00301 } 00302 00303 // If pages are being edited, we set an instruction about updating the page tree after this operation. 00304 if (isset($this->data['pages']) || $BE_USER->workspace != 0 && count($this->data)) { 00305 t3lib_BEfunc::setUpdateSignal('updatePageTree'); 00306 } 00307 00308 00309 // Checking referer / executing 00310 $refInfo=parse_url(t3lib_div::getIndpEnv('HTTP_REFERER')); 00311 $httpHost = t3lib_div::getIndpEnv('TYPO3_HOST_ONLY'); 00312 if ($httpHost!=$refInfo['host'] && $this->vC!=$BE_USER->veriCode() && !$TYPO3_CONF_VARS['SYS']['doNotCheckReferer']) { 00313 $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)); 00314 debug('Error: Referer host did not match with server host.'); 00315 } else { 00316 00317 // Perform the saving operation with TCEmain: 00318 $tce->process_uploads($_FILES); 00319 $tce->process_datamap(); 00320 $tce->process_cmdmap(); 00321 00322 // If there was saved any new items, load them: 00323 if (count($tce->substNEWwithIDs_table)) { 00324 // save the expanded/collapsed states for new inline records, if any 00325 t3lib_TCEforms_inline::updateInlineView($this->uc, $tce); 00326 00327 $newEditConf = array(); 00328 00329 foreach($this->editconf as $tableName => $tableCmds) { 00330 $keys = array_keys($tce->substNEWwithIDs_table, $tableName); 00331 if(count($keys) > 0) { 00332 foreach($keys as $key) { 00333 $editId = $tce->substNEWwithIDs[$key]; 00334 // check if the $editId isn't a child record of an IRRE action 00335 if (!(is_array($tce->newRelatedIDs[$tableName]) && in_array($editId, $tce->newRelatedIDs[$tableName]))) { 00336 // translate new id to the workspace version: 00337 if ($versionRec = t3lib_BEfunc::getWorkspaceVersionOfRecord($GLOBALS['BE_USER']->workspace, $tableName, $editId,'uid')) { 00338 $editId = $versionRec['uid']; 00339 } 00340 $newEditConf[$tableName][$editId] = 'edit'; 00341 } 00342 00343 // Traverse all new records and forge the content of ->editconf so we can continue to EDIT these records! 00344 if ($tableName=='pages' && $this->retUrl!='dummy.php' && $this->returnNewPageId) { 00345 $this->retUrl.='&id='.$tce->substNEWwithIDs[$key]; 00346 } 00347 } 00348 } else { 00349 $newEditConf[$tableName] = $tableCmds; 00350 } 00351 } 00352 00353 // Resetting editconf if newEditConf has values: 00354 if (count($newEditConf)) { 00355 $this->editconf = $newEditConf; 00356 } 00357 00358 // Finally, set the editconf array in the "getvars" so they will be passed along in URLs as needed. 00359 $this->R_URL_getvars['edit']=$this->editconf; 00360 00361 // Unsetting default values since we don't need them anymore. 00362 unset($this->R_URL_getvars['defVals']); 00363 00364 // Re-compile the store* values since editconf changed... 00365 $this->compileStoreDat(); 00366 } 00367 00368 // See if any records was auto-created as new versions? 00369 if (count($tce->autoVersionIdMap)) { 00370 $this->fixWSversioningInEditConf($tce->autoVersionIdMap); 00371 } 00372 00373 // If a document is saved and a new one is created right after. 00374 if (isset($_POST['_savedoknew_x']) && is_array($this->editconf)) { 00375 00376 // Finding the current table: 00377 reset($this->editconf); 00378 $nTable=key($this->editconf); 00379 00380 // Finding the first id, getting the records pid+uid 00381 reset($this->editconf[$nTable]); 00382 $nUid=key($this->editconf[$nTable]); 00383 $nRec = t3lib_BEfunc::getRecord($nTable,$nUid,'pid,uid'); 00384 00385 // Setting a blank editconf array for a new record: 00386 $this->editconf=array(); 00387 if ($this->getNewIconMode($nTable)=='top') { 00388 $this->editconf[$nTable][$nRec['pid']]='new'; 00389 } else { 00390 $this->editconf[$nTable][-$nRec['uid']]='new'; 00391 } 00392 00393 // Finally, set the editconf array in the "getvars" so they will be passed along in URLs as needed. 00394 $this->R_URL_getvars['edit']=$this->editconf; 00395 00396 // Re-compile the store* values since editconf changed... 00397 $this->compileStoreDat(); 00398 } 00399 00400 $tce->printLogErrorMessages( 00401 (isset($_POST['_saveandclosedok_x']) || isset($_POST['_translation_savedok_x'])) ? 00402 $this->retUrl : 00403 $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? 00404 ); 00405 } 00406 if ((isset($_POST['_saveandclosedok_x']) || isset($_POST['_translation_savedok_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! 00407 $this->closeDocument(abs($this->closeDoc)); 00408 } 00409 } 00410 00411 /** 00412 * Initialize the normal module operation 00413 * 00414 * @return void 00415 */ 00416 function init() { 00417 global $BE_USER,$LANG,$BACK_PATH; 00418 00419 // Setting more GPvars: 00420 $this->popViewId = t3lib_div::_GP('popViewId'); 00421 $this->popViewId_addParams = t3lib_div::_GP('popViewId_addParams'); 00422 $this->viewUrl = t3lib_div::_GP('viewUrl'); 00423 $this->editRegularContentFromId = t3lib_div::_GP('editRegularContentFromId'); 00424 $this->recTitle = t3lib_div::_GP('recTitle'); 00425 $this->disHelp = t3lib_div::_GP('disHelp'); 00426 $this->noView = t3lib_div::_GP('noView'); 00427 00428 $this->perms_clause = $BE_USER->getPagePermsClause(1); 00429 00430 // Set other internal variables: 00431 $this->R_URL_getvars['returnUrl']=$this->retUrl; 00432 $this->R_URI = $this->R_URL_parts['path'].'?'.t3lib_div::implodeArrayForUrl('',$this->R_URL_getvars); 00433 00434 // MENU-ITEMS: 00435 // If array, then it's a selector box menu 00436 // If empty string it's just a variable, that'll be saved. 00437 // Values NOT in this array will not be saved in the settings-array for the module. 00438 $this->MOD_MENU = array( 00439 'showPalettes' => '' 00440 ); 00441 00442 // Setting virtual document name 00443 $this->MCONF['name']='xMOD_alt_doc.php'; 00444 00445 // CLEANSE SETTINGS 00446 $this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), $this->MCONF['name']); 00447 00448 // Create an instance of the document template object 00449 $this->doc = $GLOBALS['TBE_TEMPLATE']; 00450 $this->doc->backPath = $BACK_PATH; 00451 $this->doc->setModuleTemplate('templates/alt_doc.html'); 00452 $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);">'; 00453 00454 $this->doc->getPageRenderer()->loadPrototype(); 00455 $this->doc->JScode = $this->doc->wrapScriptTags(' 00456 function jumpToUrl(URL,formEl) { // 00457 if (!TBE_EDITOR.isFormChanged()) { 00458 window.location.href = URL; 00459 } else if (formEl && formEl.type=="checkbox") { 00460 formEl.checked = formEl.checked ? 0 : 1; 00461 } 00462 } 00463 // Object: TS: 00464 // passwordDummy and decimalSign are used by tbe_editor.js and have to be declared here as 00465 // TS object overwrites the object declared in tbe_editor.js 00466 function typoSetup () { // 00467 this.uniqueID = ""; 00468 this.passwordDummy = "********"; 00469 this.decimalSign = "."; 00470 } 00471 var TS = new typoSetup(); 00472 00473 // Info view: 00474 function launchView(table,uid,bP) { // 00475 var backPath= bP ? bP : ""; 00476 var thePreviewWindow=""; 00477 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"); 00478 if (thePreviewWindow && thePreviewWindow.focus) { 00479 thePreviewWindow.focus(); 00480 } 00481 } 00482 function deleteRecord(table,id,url) { // 00483 if ( 00484 '.($GLOBALS['BE_USER']->jsConfirmation(4)?'confirm('.$LANG->JScharCode($LANG->getLL('deleteWarning')).')':'1==1').' 00485 ) { 00486 window.location.href = "tce_db.php?cmd["+table+"]["+id+"][delete]=1' . t3lib_BEfunc::getUrlToken('tceAction') . '&redirect="+escape(url)+"&vC=' . $BE_USER->veriCode() . '&prErr=1&uPT=1"; 00487 } 00488 return false; 00489 } 00490 '.(isset($_POST['_savedokview_x']) && $this->popViewId ? 00491 'if (window.opener) { '. 00492 t3lib_BEfunc::viewOnClick($this->popViewId,'',t3lib_BEfunc::BEgetRootLine($this->popViewId),'',$this->viewUrl,$this->popViewId_addParams,FALSE). 00493 ' } else { '. 00494 t3lib_BEfunc::viewOnClick($this->popViewId,'',t3lib_BEfunc::BEgetRootLine($this->popViewId),'',$this->viewUrl,$this->popViewId_addParams). 00495 ' } ' 00496 : '') 00497 ); 00498 00499 // Setting up the context sensitive menu: 00500 $this->doc->getContextMenuCode(); 00501 $this->doc->bodyTagAdditions = 'onload="window.scrollTo(0,'.t3lib_div::intInRange(t3lib_div::_GP('_scrollPosition'),0,10000).');"'; 00502 } 00503 00504 /** 00505 * Main module operation 00506 * 00507 * @return void 00508 */ 00509 function main() { 00510 global $BE_USER,$LANG; 00511 00512 // Begin edit: 00513 if (is_array($this->editconf)) { 00514 00515 // Initialize TCEforms (rendering the forms) 00516 $this->tceforms = t3lib_div::makeInstance('t3lib_TCEforms'); 00517 $this->tceforms->initDefaultBEMode(); 00518 $this->tceforms->doSaveFieldName = 'doSave'; 00519 $this->tceforms->localizationMode = t3lib_div::inList('text,media',$this->localizationMode) ? $this->localizationMode : ''; // text,media is keywords defined in TYPO3 Core API..., see "l10n_cat" 00520 $this->tceforms->returnUrl = $this->R_URI; 00521 $this->tceforms->palettesCollapsed = !$this->MOD_SETTINGS['showPalettes']; 00522 $this->tceforms->disableRTE = !$BE_USER->isRTE(); 00523 $this->tceforms->enableClickMenu = TRUE; 00524 $this->tceforms->enableTabMenu = TRUE; 00525 00526 // Clipboard is initialized: 00527 $this->tceforms->clipObj = t3lib_div::makeInstance('t3lib_clipboard'); // Start clipboard 00528 $this->tceforms->clipObj->initializeClipboard(); // Initialize - reads the clipboard content from the user session 00529 00530 // Setting external variables: 00531 $this->tceforms->edit_showFieldHelp = $BE_USER->uc['edit_showFieldHelp']; 00532 00533 if ($this->editRegularContentFromId) { 00534 $this->editRegularContentFromId(); 00535 } 00536 00537 00538 // Creating the editing form, wrap it with buttons, document selector etc. 00539 $editForm = $this->makeEditForm(); 00540 00541 if ($editForm) { 00542 $this->firstEl = reset($this->elementsData); 00543 00544 // Checking if the currently open document is stored in the list of "open documents" - if not, then add it: 00545 if ((strcmp($this->docDat[1], $this->storeUrlMd5) || !isset($this->docHandler[$this->storeUrlMd5])) && !$this->dontStoreDocumentRef) { 00546 $this->docHandler[$this->storeUrlMd5] = array($this->storeTitle, $this->storeArray, $this->storeUrl, $this->firstEl); 00547 $BE_USER->pushModuleData('alt_doc.php', array($this->docHandler, $this->storeUrlMd5)); 00548 t3lib_BEfunc::setUpdateSignal('tx_opendocs::updateNumber', count($this->docHandler)); 00549 } 00550 00551 00552 // Module configuration 00553 $this->modTSconfig = ($this->viewId ? t3lib_BEfunc::getModTSconfig($this->viewId,'mod.xMOD_alt_doc') : array()); 00554 00555 $body.= $this->tceforms->printNeededJSFunctions_top(); 00556 $body.= $this->compileForm($editForm); 00557 $body.= $this->tceforms->printNeededJSFunctions(); 00558 $body.= $this->functionMenus(); 00559 $body.= $this->tceformMessages(); 00560 } 00561 } 00562 00563 // Access check... 00564 // The page will show only if there is a valid page and if this page may be viewed by the user 00565 $this->pageinfo = t3lib_BEfunc::readPageAccess($this->viewId, $this->perms_clause); 00566 00567 // Setting up the buttons and markers for docheader 00568 $docHeaderButtons = $this->getButtons(); 00569 $markers = array( 00570 'LANGSELECTOR' => $this->langSelector(), 00571 'EXTRAHEADER' => $this->extraFormHeaders(), 00572 'CSH' => $docHeaderButtons['csh'], 00573 'CONTENT' => $body 00574 ); 00575 00576 // Build the <body> for the module 00577 $this->content = $this->doc->startPage('TYPO3 Edit Document'); 00578 $this->content.= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers); 00579 $this->content.= $this->doc->endPage(); 00580 $this->content = $this->doc->insertStylesAndJS($this->content); 00581 } 00582 00583 00584 /** 00585 * Outputting the accumulated content to screen 00586 * 00587 * @return void 00588 */ 00589 function printContent() { 00590 echo $this->content; 00591 } 00592 00593 00594 00595 00596 00597 00598 00599 00600 00601 00602 00603 00604 00605 00606 00607 00608 00609 00610 00611 00612 /*************************** 00613 * 00614 * Sub-content functions, rendering specific parts of the module content. 00615 * 00616 ***************************/ 00617 00618 /** 00619 * Creates the editing form with TCEforms, based on the input from GPvars. 00620 * 00621 * @return string HTML form elements wrapped in tables 00622 */ 00623 function makeEditForm() { 00624 global $BE_USER,$LANG,$TCA; 00625 00626 // Initialize variables: 00627 $this->elementsData=array(); 00628 $this->errorC=0; 00629 $this->newC=0; 00630 $thePrevUid=''; 00631 $editForm=''; 00632 $trData = NULL; 00633 00634 // Traverse the GPvar edit array 00635 foreach($this->editconf as $table => $conf) { // Tables: 00636 if (is_array($conf) && $TCA[$table] && $BE_USER->check('tables_modify',$table)) { 00637 00638 // Traverse the keys/comments of each table (keys can be a commalist of uids) 00639 foreach($conf as $cKey => $cmd) { 00640 if ($cmd=='edit' || $cmd=='new') { 00641 00642 // Get the ids: 00643 $ids = t3lib_div::trimExplode(',',$cKey,1); 00644 00645 // Traverse the ids: 00646 foreach($ids as $theUid) { 00647 00648 // 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...) 00649 // First, resetting flags. 00650 $hasAccess = 1; 00651 $deniedAccessReason = ''; 00652 $deleteAccess = 0; 00653 $this->viewId = 0; 00654 00655 // If the command is to create a NEW record...: 00656 if ($cmd=='new') { 00657 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. 00658 00659 // Find parent page on which the new record reside 00660 if ($theUid<0) { // Less than zero - find parent page 00661 $calcPRec=t3lib_BEfunc::getRecord($table,abs($theUid)); 00662 $calcPRec=t3lib_BEfunc::getRecord('pages',$calcPRec['pid']); 00663 } else { // always a page 00664 $calcPRec=t3lib_BEfunc::getRecord('pages',abs($theUid)); 00665 } 00666 00667 // Now, calculate whether the user has access to creating new records on this position: 00668 if (is_array($calcPRec)) { 00669 $CALC_PERMS = $BE_USER->calcPerms($calcPRec); // Permissions for the parent page 00670 if ($table=='pages') { // If pages: 00671 $hasAccess = $CALC_PERMS&8 ? 1 : 0; 00672 #$this->viewId = $calcPRec['pid']; 00673 $this->viewId = 0; 00674 } else { 00675 $hasAccess = $CALC_PERMS&16 ? 1 : 0; 00676 $this->viewId = $calcPRec['uid']; 00677 } 00678 } 00679 } 00680 $this->dontStoreDocumentRef=1; // Don't save this document title in the document selector if the document is new. 00681 } else { // Edit: 00682 $calcPRec = t3lib_BEfunc::getRecord($table,$theUid); 00683 t3lib_BEfunc::fixVersioningPid($table,$calcPRec); 00684 if (is_array($calcPRec)) { 00685 if ($table=='pages') { // If pages: 00686 $CALC_PERMS = $BE_USER->calcPerms($calcPRec); 00687 $hasAccess = $CALC_PERMS&2 ? 1 : 0; 00688 $deleteAccess = $CALC_PERMS&4 ? 1 : 0; 00689 $this->viewId = $calcPRec['uid']; 00690 } else { 00691 $CALC_PERMS = $BE_USER->calcPerms(t3lib_BEfunc::getRecord('pages',$calcPRec['pid'])); // Fetching pid-record first. 00692 $hasAccess = $CALC_PERMS&16 ? 1 : 0; 00693 $deleteAccess = $CALC_PERMS&16 ? 1 : 0; 00694 $this->viewId = $calcPRec['pid']; 00695 00696 // Adding "&L=xx" if the record being edited has a languageField with a value larger than zero! 00697 if ($TCA[$table]['ctrl']['languageField'] && $calcPRec[$TCA[$table]['ctrl']['languageField']]>0) { 00698 $this->viewId_addParams = '&L='.$calcPRec[$TCA[$table]['ctrl']['languageField']]; 00699 } 00700 } 00701 00702 // Check internals regarding access: 00703 if ($hasAccess) { 00704 $hasAccess = $BE_USER->recordEditAccessInternals($table, $calcPRec); 00705 $deniedAccessReason = $BE_USER->errorMsg; 00706 } 00707 } else $hasAccess = 0; 00708 } 00709 00710 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/alt_doc.php']['makeEditForm_accessCheck'])) { 00711 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/alt_doc.php']['makeEditForm_accessCheck'] as $_funcRef) { 00712 $_params = array( 00713 'table' => $table, 00714 'uid' => $theUid, 00715 'cmd' => $cmd, 00716 'hasAccess' => $hasAccess 00717 ); 00718 $hasAccess = t3lib_div::callUserFunction($_funcRef, $_params, $this); 00719 } 00720 } 00721 00722 // 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: 00723 00724 if ($hasAccess) { 00725 $prevPageID = is_object($trData)?$trData->prevPageID:''; 00726 $trData = t3lib_div::makeInstance('t3lib_transferData'); 00727 $trData->addRawData = TRUE; 00728 $trData->defVals = $this->defVals; 00729 $trData->lockRecords=1; 00730 $trData->disableRTE = !$BE_USER->isRTE(); 00731 $trData->prevPageID = $prevPageID; 00732 $trData->fetchRecord($table,$theUid,$cmd=='new'?'new':''); // 'new' 00733 reset($trData->regTableItems_data); 00734 $rec = current($trData->regTableItems_data); 00735 $rec['uid'] = $cmd=='new' ? uniqid('NEW') : $theUid; 00736 if ($cmd=='new') { 00737 $rec['pid'] = $theUid=='prev'?$thePrevUid:$theUid; 00738 } 00739 $this->elementsData[]=array( 00740 'table' => $table, 00741 'uid' => $rec['uid'], 00742 'pid' => $rec['pid'], 00743 'cmd' => $cmd, 00744 'deleteAccess' => $deleteAccess 00745 ); 00746 00747 // Now, render the form: 00748 if (is_array($rec)) { 00749 00750 // Setting visual path / title of form: 00751 $this->generalPathOfForm = $this->tceforms->getRecordPath($table,$rec); 00752 if (!$this->storeTitle) { 00753 $this->storeTitle = $this->recTitle ? htmlspecialchars($this->recTitle) : t3lib_BEfunc::getRecordTitle($table,$rec,TRUE); 00754 } 00755 00756 // Setting variables in TCEforms object: 00757 $this->tceforms->hiddenFieldList = ''; 00758 $this->tceforms->globalShowHelp = $this->disHelp ? 0 : 1; 00759 if (is_array($this->overrideVals[$table])) { 00760 $this->tceforms->hiddenFieldListArr = array_keys($this->overrideVals[$table]); 00761 } 00762 00763 // Register default language labels, if any: 00764 $this->tceforms->registerDefaultLanguageData($table,$rec); 00765 00766 // Create form for the record (either specific list of fields or the whole record): 00767 $panel = ''; 00768 if ($this->columnsOnly) { 00769 if(is_array($this->columnsOnly)){ 00770 $panel.= $this->tceforms->getListedFields($table,$rec,$this->columnsOnly[$table]); 00771 } else { 00772 $panel.= $this->tceforms->getListedFields($table,$rec,$this->columnsOnly); 00773 } 00774 } else { 00775 $panel.= $this->tceforms->getMainFields($table,$rec); 00776 } 00777 $panel = $this->tceforms->wrapTotal($panel,$rec,$table); 00778 00779 // Setting the pid value for new records: 00780 if ($cmd=='new') { 00781 $panel.= '<input type="hidden" name="data['.$table.']['.$rec['uid'].'][pid]" value="'.$rec['pid'].'" />'; 00782 $this->newC++; 00783 } 00784 00785 // Display "is-locked" message: 00786 if ($lockInfo = t3lib_BEfunc::isRecordLocked($table, $rec['uid'])) { 00787 $lockedMessage = t3lib_div::makeInstance( 00788 't3lib_FlashMessage', 00789 htmlspecialchars($lockInfo['msg']), 00790 '', 00791 t3lib_FlashMessage::WARNING 00792 ); 00793 t3lib_FlashMessageQueue::addMessage($lockedMessage); 00794 } 00795 00796 // Combine it all: 00797 $editForm .= $panel; 00798 } 00799 00800 $thePrevUid = $rec['uid']; 00801 } else { 00802 $this->errorC++; 00803 $editForm.=$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.noEditPermission',1).'<br /><br />'. 00804 ($deniedAccessReason ? 'Reason: ' . htmlspecialchars($deniedAccessReason) . '<br /><br />' : ''); 00805 } 00806 } 00807 } 00808 } 00809 } 00810 } 00811 00812 return $editForm; 00813 } 00814 00815 /** 00816 * Create the panel of buttons for submitting the form or otherwise perform operations. 00817 * 00818 * @return array all available buttons as an assoc. array 00819 */ 00820 protected function getButtons() { 00821 global $TCA,$LANG; 00822 $buttons = array( 00823 'save' => '', 00824 'save_view' => '', 00825 'save_new' => '', 00826 'save_close' => '', 00827 'close' => '', 00828 'delete' => '', 00829 'undo' => '', 00830 'history' => '', 00831 'columns_only' => '', 00832 'csh' => '', 00833 'translation_save' => '', 00834 'translation_saveclear' => '' 00835 ); 00836 00837 // Render SAVE type buttons: 00838 // The action of each button is decided by its name attribute. (See doProcessData()) 00839 if (!$this->errorC && !$TCA[$this->firstEl['table']]['ctrl']['readOnly']) { 00840 00841 // SAVE button: 00842 $buttons['save'] = t3lib_iconWorks::getSpriteIcon('actions-document-save', array( 'html' => '<input type="image" name="_savedok" class="c-inputButton" src="clear.gif" title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:rm.saveDoc', 1) . '" />' )); 00843 00844 // SAVE / VIEW button: 00845 if ($this->viewId && !$this->noView && t3lib_extMgm::isLoaded('cms') && $this->getNewIconMode($this->firstEl['table'], 'saveDocView')) { 00846 $buttons['save_view'] = t3lib_iconWorks::getSpriteIcon('actions-document-save-view',array('html'=>'<input type="image" class="c-inputButton" name="_savedokview" src="clear.gif" title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:rm.saveDocShow', 1) . '" />')); 00847 } 00848 00849 // SAVE / NEW button: 00850 if (count($this->elementsData)==1 && $this->getNewIconMode($this->firstEl['table'])) { 00851 $buttons['save_new'] = t3lib_iconWorks::getSpriteIcon('actions-document-save-new',array('html'=>'<input type="image" class="c-inputButton" name="_savedoknew" src="clear.gif" title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:rm.saveNewDoc', 1) . '" />')); 00852 } 00853 00854 // SAVE / CLOSE 00855 $buttons['save_close'] = t3lib_iconWorks::getSpriteIcon('actions-document-save-close',array('html'=>'<input type="image" class="c-inputButton" name="_saveandclosedok" src="clear.gif" title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:rm.saveCloseDoc', 1) . '" />')); 00856 00857 // FINISH TRANSLATION / SAVE / CLOSE 00858 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['explicitConfirmationOfTranslation']) { 00859 $buttons['translation_save'] = '<input type="image" class="c-inputButton" name="_translation_savedok" src="' . t3lib_iconWorks::skinImg($this->doc->backPath, 'gfx/translationsavedok.gif', '', 1) . '" title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:rm.translationSaveDoc', 1) . '" />'; 00860 $buttons['translation_saveclear'] = '<input type="image" class="c-inputButton" name="_translation_savedokclear" src="' . t3lib_iconWorks::skinImg($this->doc->backPath, 'gfx/translationsavedok_clear.gif', '', 1) . '" title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:rm.translationSaveDocClear', 1) . '" />'; 00861 } 00862 } 00863 00864 // CLOSE button: 00865 $buttons['close'] = '<a href="#" onclick="document.editform.closeDoc.value=1; document.editform.submit(); return false;" title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:rm.closeDoc', TRUE) . '">' . 00866 t3lib_iconWorks::getSpriteIcon('actions-document-close') . 00867 '</a>'; 00868 00869 00870 // DELETE + UNDO buttons: 00871 if (!$this->errorC && !$TCA[$this->firstEl['table']]['ctrl']['readOnly'] && count($this->elementsData)==1) { 00872 if ($this->firstEl['cmd']!='new' && t3lib_div::testInt($this->firstEl['uid'])) { 00873 00874 // Delete: 00875 if ($this->firstEl['deleteAccess'] && !$TCA[$this->firstEl['table']]['ctrl']['readOnly'] && !$this->getNewIconMode($this->firstEl['table'],'disableDelete')) { 00876 $aOnClick = 'return deleteRecord(\''.$this->firstEl['table'].'\',\''.$this->firstEl['uid'].'\',unescape(\''.rawurlencode($this->retUrl).'\'));'; 00877 $buttons['delete'] = '<a href="#" onclick="'.htmlspecialchars($aOnClick).'" title="' . $LANG->getLL('deleteItem', TRUE) . '">' . 00878 t3lib_iconWorks::getSpriteIcon('actions-edit-delete') . 00879 '</a>'; 00880 } 00881 00882 // Undo: 00883 $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'); 00884 if ($undoButtonR = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($undoRes)) { 00885 $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;'; 00886 $buttons['undo'] = '<a href="#" onclick="'.htmlspecialchars($aOnClick).'"'. 00887 ' title="' . htmlspecialchars(sprintf($LANG->getLL('undoLastChange'), t3lib_BEfunc::calcAge($GLOBALS['EXEC_TIME'] - $undoButtonR['tstamp'], $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears')))) . '">' . 00888 t3lib_iconWorks::getSpriteIcon('actions-edit-undo') . 00889 '</a>'; 00890 } 00891 if ($this->getNewIconMode($this->firstEl['table'],'showHistory')) { 00892 $aOnClick = 'window.location.href=\'show_rechis.php?element='.rawurlencode($this->firstEl['table'].':'.$this->firstEl['uid']).'&returnUrl='.rawurlencode($this->R_URI).'\'; return false;'; 00893 $buttons['history'] = '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'. 00894 t3lib_iconWorks::getSpriteIcon('actions-document-history-open') . 00895 '</a>'; 00896 } 00897 00898 // If only SOME fields are shown in the form, this will link the user to the FULL form: 00899 if ($this->columnsOnly) { 00900 $buttons['columns_only'] = '<a href="'.htmlspecialchars($this->R_URI.'&columnsOnly=').'" title="' . $LANG->getLL('editWholeRecord', TRUE) . '">' . 00901 t3lib_iconWorks::getSpriteIcon('actions-document-open') . 00902 '</a>'; 00903 } 00904 } 00905 } 00906 00907 // add the CSH icon 00908 $buttons['csh'] = t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'TCEforms', $GLOBALS['BACK_PATH'], '', TRUE); 00909 $buttons['shortcut'] = $this->shortCutLink(); 00910 $buttons['open_in_new_window'] = $this->openInNewWindowLink(); 00911 return $buttons; 00912 } 00913 00914 /** 00915 * Returns the language switch/selector for editing, 00916 * show only when a single record is edited 00917 * - multiple records are too confusing 00918 * @return string the HTML 00919 */ 00920 function langSelector() { 00921 $langSelector = ''; 00922 if (count($this->elementsData) == 1) { 00923 $langSelector = $this->languageSwitch($this->firstEl['table'], $this->firstEl['uid'], $this->firstEl['pid']); 00924 } 00925 return $langSelector; 00926 } 00927 00928 00929 /** 00930 * Compiles the extra form headers if the tceforms 00931 * 00932 * @return string the HTML 00933 */ 00934 function extraFormHeaders() { 00935 $extraTemplate = ''; 00936 00937 if (is_array($this->tceforms->extraFormHeaders)) { 00938 $extraTemplate = t3lib_parsehtml::getSubpart($this->doc->moduleTemplate, '###DOCHEADER_EXTRAHEADER###'); 00939 $extraTemplate = t3lib_parsehtml::substituteMarker($extraTemplate, '###EXTRAHEADER###', implode(LF, $this->tceforms->extraFormHeaders)); 00940 } 00941 return $extraTemplate; 00942 } 00943 00944 00945 /** 00946 * Put together the various elements (buttons, selectors, form) into a table 00947 * 00948 * @param string HTML form. 00949 * @return string Composite HTML 00950 */ 00951 function compileForm($editForm) { 00952 global $LANG; 00953 00954 $formContent = ' 00955 <!-- EDITING FORM --> 00956 '.$editForm.' 00957 00958 <input type="hidden" name="returnUrl" value="'.htmlspecialchars($this->retUrl).'" /> 00959 <input type="hidden" name="viewUrl" value="'.htmlspecialchars($this->viewUrl).'" />'; 00960 00961 if ($this->returnNewPageId) { 00962 $formContent .= '<input type="hidden" name="returnNewPageId" value="1" />'; 00963 } 00964 $formContent .= '<input type="hidden" name="popViewId" value="'.htmlspecialchars($this->viewId).'" />'; 00965 if ($this->viewId_addParams) { 00966 $formContent .= '<input type="hidden" name="popViewId_addParams" value="'.htmlspecialchars($this->viewId_addParams).'" />'; 00967 } 00968 $formContent .= ' 00969 <input type="hidden" name="closeDoc" value="0" /> 00970 <input type="hidden" name="doSave" value="0" /> 00971 <input type="hidden" name="_serialNumber" value="'.md5(microtime()).'" /> 00972 <input type="hidden" name="_scrollPosition" value="" />' . t3lib_TCEforms::getHiddenTokenField('editRecord'); 00973 00974 return $formContent; 00975 } 00976 00977 /** 00978 * Create the checkbox buttons in the bottom of the pages. 00979 * 00980 * @return string HTML for function menus. 00981 */ 00982 function functionMenus() { 00983 global $LANG; 00984 00985 if ($GLOBALS['BE_USER']->getTSConfigVal('options.enableShowPalettes')) { 00986 // Show palettes: 00987 return ' 00988 <!-- Function menu (checkbox for showing all palettes): --> 00989 <br />'.t3lib_BEfunc::getFuncCheck('','SET[showPalettes]',$this->MOD_SETTINGS['showPalettes'],'alt_doc.php',t3lib_div::implodeArrayForUrl('',array_merge($this->R_URL_getvars,array('SET'=>''))) . t3lib_BEfunc::getUrlToken('editRecord'),'id="checkShowPalettes"').'<label for="checkShowPalettes">'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.showPalettes',1).'</label>'; 00990 } 00991 else { 00992 return ''; 00993 } 00994 } 00995 00996 00997 /** 00998 * Create shortcut icon 00999 * 01000 * @return string 01001 */ 01002 function shortCutLink() { 01003 global $BE_USER,$LANG; 01004 01005 if ($this->returnUrl == 'close.html' || !$BE_USER->mayMakeShortcut()) { 01006 return ''; 01007 } 01008 return $this->doc->makeShortcutIcon('returnUrl,edit,defVals,overrideVals,columnsOnly,returnNewPageId,editRegularContentFromId,disHelp,noView',implode(',',array_keys($this->MOD_MENU)),$this->MCONF['name'],1); 01009 } 01010 01011 01012 /** 01013 * Creates open-in-window link 01014 * 01015 * @return string 01016 */ 01017 function openInNewWindowLink() { 01018 global $BE_USER, $LANG; 01019 if ($this->returnUrl == 'close.html') { 01020 return ''; 01021 } 01022 $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;'; 01023 return '<a href="#" onclick="'.htmlspecialchars($aOnClick).'" title="' . $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.openInNewWindow', TRUE) . '">' . 01024 t3lib_iconWorks::getSpriteIcon('actions-window-open') . 01025 '</a>'; 01026 } 01027 01028 01029 /** 01030 * Reads comment messages from TCEforms and prints them in a HTML comment in the bottom of the page. 01031 * 01032 * @return void 01033 */ 01034 function tceformMessages() { 01035 if (count($this->tceforms->commentMessages)) { 01036 $tceformMessages = ' 01037 <!-- TCEFORM messages 01038 '.htmlspecialchars(implode(LF,$this->tceforms->commentMessages)).' 01039 --> 01040 '; 01041 } 01042 return $tceformMessages; 01043 } 01044 01045 01046 01047 01048 01049 01050 01051 01052 01053 01054 01055 01056 01057 /*************************** 01058 * 01059 * Localization stuff 01060 * 01061 ***************************/ 01062 01063 /** 01064 * Make selector box for creating new translation for a record or switching to edit the record in an existing language. 01065 * Displays only languages which are available for the current page. 01066 * 01067 * @param string Table name 01068 * @param integer uid for which to create a new language 01069 * @param integer pid of the record 01070 * @return string <select> HTML element (if there were items for the box anyways...) 01071 */ 01072 function languageSwitch($table, $uid, $pid=NULL) { 01073 global $TCA; 01074 01075 $content = ''; 01076 01077 $languageField = $TCA[$table]['ctrl']['languageField']; 01078 $transOrigPointerField = $TCA[$table]['ctrl']['transOrigPointerField']; 01079 01080 // table editable and activated for languages? 01081 if ($GLOBALS['BE_USER']->check('tables_modify',$table) && $languageField && $transOrigPointerField && !$TCA[$table]['ctrl']['transOrigPointerTable']) { 01082 01083 if(is_null($pid)) { 01084 $row = t3lib_befunc::getRecord($table, $uid, 'pid'); 01085 $pid = $row['pid']; 01086 } 01087 01088 // get all avalibale languages for the page 01089 $langRows = $this->getLanguages($pid); 01090 01091 // page available in other languages than default language? 01092 if (is_array($langRows) && count($langRows)>1) { 01093 01094 $rowsByLang = array(); 01095 $fetchFields = 'uid,'.$languageField.','.$transOrigPointerField; 01096 01097 // get record in current language 01098 $rowCurrent = t3lib_befunc::getLiveVersionOfRecord($table, $uid, $fetchFields); 01099 if (!is_array($rowCurrent)) { 01100 $rowCurrent = t3lib_befunc::getRecord($table, $uid, $fetchFields); 01101 } 01102 01103 $currentLanguage = $rowCurrent[$languageField]; 01104 01105 if ($currentLanguage>-1) { // Disabled for records with [all] language! 01106 // get record in default language if needed 01107 if ($currentLanguage) { 01108 $rowsByLang[0] = t3lib_befunc::getLiveVersionOfRecord($table, $rowCurrent[$transOrigPointerField], $fetchFields); 01109 if (!is_array($rowsByLang[0])) { 01110 $rowsByLang[0] = t3lib_befunc::getRecord($table, $rowCurrent[$transOrigPointerField], $fetchFields); 01111 } 01112 } else { 01113 $rowsByLang[0] = $rowCurrent; 01114 } 01115 01116 // get record in other languages to see what's already available 01117 $translations = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 01118 $fetchFields, 01119 $table, 01120 'pid='.intval($pid). 01121 ' AND '.$languageField.'>0'. 01122 ' AND '.$transOrigPointerField.'='.intval($rowsByLang[0]['uid']). 01123 t3lib_BEfunc::deleteClause($table). 01124 t3lib_BEfunc::versioningPlaceholderClause($table) 01125 ); 01126 foreach ($translations as $row) { 01127 $rowsByLang[$row[$languageField]] = $row; 01128 } 01129 01130 $langSelItems=array(); 01131 foreach ($langRows as $lang) { 01132 if ($GLOBALS['BE_USER']->checkLanguageAccess($lang['uid'])) { 01133 01134 $newTranslation = isset($rowsByLang[$lang['uid']]) ? '' : ' ['.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:labels.new',1).']'; 01135 01136 // create url for creating a localized record 01137 if($newTranslation) { 01138 $href = $this->doc->issueCommand( 01139 '&cmd['.$table.']['.$rowsByLang[0]['uid'].'][localize]='.$lang['uid'], 01140 $this->backPath.'alt_doc.php?justLocalized='.rawurlencode($table.':'.$rowsByLang[0]['uid'].':'.$lang['uid']).'&returnUrl='.rawurlencode($this->retUrl) . t3lib_BEfunc::getUrlToken('editRecord') 01141 ); 01142 01143 // create edit url 01144 } else { 01145 $href = $this->backPath.'alt_doc.php?'; 01146 $href .= '&edit['.$table.']['.$rowsByLang[$lang['uid']]['uid'].']=edit'; 01147 $href .= '&returnUrl='.rawurlencode($this->retUrl) . t3lib_BEfunc::getUrlToken('editRecord'); 01148 } 01149 01150 $langSelItems[$lang['uid']]=' 01151 <option value="'.htmlspecialchars($href).'"'.($currentLanguage==$lang['uid']?' selected="selected"':'').'>'.htmlspecialchars($lang['title'].$newTranslation).'</option>'; 01152 } 01153 } 01154 01155 // If any languages are left, make selector: 01156 if (count($langSelItems)>1) { 01157 $onChange = 'if(this.options[this.selectedIndex].value){window.location.href=(this.options[this.selectedIndex].value);}'; 01158 $content = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_general.xml:LGL.language',1).' <select name="_langSelector" onchange="'.htmlspecialchars($onChange).'"> 01159 '.implode('',$langSelItems).' 01160 </select>'; 01161 } 01162 } 01163 } 01164 } 01165 return $content; 01166 } 01167 01168 01169 /** 01170 * Redirects to alt_doc with new parameters to edit a just created localized record 01171 * 01172 * @param string String passed by GET &justLocalized= 01173 * @return void 01174 */ 01175 function localizationRedirect($justLocalized) { 01176 global $TCA; 01177 01178 list($table,$orig_uid,$language) = explode(':',$justLocalized); 01179 01180 if ($TCA[$table] && $TCA[$table]['ctrl']['languageField'] && $TCA[$table]['ctrl']['transOrigPointerField']) { 01181 $localizedRecord = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow( 01182 'uid', 01183 $table, 01184 $TCA[$table]['ctrl']['languageField'].'='.intval($language).' AND '. 01185 $TCA[$table]['ctrl']['transOrigPointerField'].'='.intval($orig_uid). 01186 t3lib_BEfunc::deleteClause($table). 01187 t3lib_BEfunc::versioningPlaceholderClause($table) 01188 ); 01189 01190 if (is_array($localizedRecord)) { 01191 // Create parameters and finally run the classic page module for creating a new page translation 01192 $params = '&edit['.$table.']['.$localizedRecord['uid'].']=edit'; 01193 $returnUrl = '&returnUrl='.rawurlencode(t3lib_div::sanitizeLocalUrl(t3lib_div::_GP('returnUrl'))); 01194 $location = $GLOBALS['BACK_PATH'].'alt_doc.php?'.$params.$returnUrl . t3lib_BEfunc::getUrlToken('editRecord'); 01195 01196 t3lib_utility_Http::redirect($location); 01197 } 01198 } 01199 } 01200 01201 01202 /** 01203 * Returns sys_language records. 01204 * 01205 * @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) 01206 * @return array Language records including faked record for default language 01207 */ 01208 function getLanguages($id) { 01209 global $LANG; 01210 01211 $modSharedTSconfig = t3lib_BEfunc::getModTSconfig($id, 'mod.SHARED'); 01212 01213 // fallback non sprite-configuration 01214 if (preg_match('/\.gif$/', $modSharedTSconfig['properties']['defaultLanguageFlag'])) { 01215 $modSharedTSconfig['properties']['defaultLanguageFlag'] = str_replace('.gif', '', $modSharedTSconfig['properties']['defaultLanguageFlag']); 01216 } 01217 01218 $languages = array( 01219 0 => array( 01220 'uid' => 0, 01221 'pid' => 0, 01222 'hidden' => 0, 01223 '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'), 01224 'flag' => $modSharedTSconfig['properties']['defaultLanguageFlag'], 01225 ) 01226 ); 01227 01228 $exQ = $GLOBALS['BE_USER']->isAdmin() ? '' : ' AND sys_language.hidden=0'; 01229 if ($id) { 01230 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 01231 'sys_language.*', 01232 'pages_language_overlay,sys_language', 01233 'pages_language_overlay.sys_language_uid=sys_language.uid AND pages_language_overlay.pid='.intval($id).$exQ, 01234 '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', 01235 'sys_language.title' 01236 ); 01237 } else { 01238 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 01239 'sys_language.*', 01240 'sys_language', 01241 'sys_language.hidden=0', 01242 '', 01243 'sys_language.title' 01244 ); 01245 } 01246 if ($rows) { 01247 foreach ($rows as $row) { 01248 $languages[$row['uid']] = $row; 01249 } 01250 } 01251 return $languages; 01252 } 01253 01254 01255 01256 01257 01258 01259 01260 01261 01262 01263 /*************************** 01264 * 01265 * Other functions 01266 * 01267 ***************************/ 01268 01269 /** 01270 * Fix $this->editconf if versioning applies to any of the records 01271 * 01272 * @param array Mapping between old and new ids if auto-versioning has been performed. 01273 * @return void 01274 */ 01275 function fixWSversioningInEditConf($mapArray=FALSE) { 01276 global $TCA,$BE_USER; 01277 01278 // Traverse the editConf array 01279 if (is_array($this->editconf)) { 01280 foreach($this->editconf as $table => $conf) { // Tables: 01281 if (is_array($conf) && $TCA[$table]) { 01282 01283 // Traverse the keys/comments of each table (keys can be a commalist of uids) 01284 $newConf = array(); 01285 foreach($conf as $cKey => $cmd) { 01286 if ($cmd=='edit') { 01287 // Traverse the ids: 01288 $ids = t3lib_div::trimExplode(',', $cKey, 1); 01289 foreach($ids as $idKey => $theUid) { 01290 if (is_array($mapArray)) { 01291 if ($mapArray[$table][$theUid]) { 01292 $ids[$idKey] = $mapArray[$table][$theUid]; 01293 } 01294 } else { // Default, look for versions in workspace for record: 01295 $calcPRec = $this->getRecordForEdit($table,$theUid); 01296 if (is_array($calcPRec)) { 01297 // Setting UID again if it had changed, eg. due to workspace versioning. 01298 $ids[$idKey] = $calcPRec['uid']; 01299 } 01300 } 01301 #else unset($ids[$idKey]); 01302 } 01303 01304 // Add the possibly manipulated IDs to the new-build newConf array: 01305 $newConf[implode(',',$ids)] = $cmd; 01306 } else { 01307 $newConf[$cKey] = $cmd; 01308 } 01309 } 01310 // Store the new conf array: 01311 $this->editconf[$table] = $newConf; 01312 } 01313 } 01314 } 01315 } 01316 01317 /** 01318 * Get record for editing. 01319 * 01320 * @param string Table name 01321 * @param integer Record UID 01322 * @return array Returns record to edit, false if none 01323 */ 01324 function getRecordForEdit($table,$theUid) { 01325 global $TCA; 01326 01327 // Fetch requested record: 01328 $reqRecord = t3lib_BEfunc::getRecord($table,$theUid,'uid,pid'); 01329 01330 if (is_array($reqRecord)) { 01331 // If workspace is OFFLINE: 01332 if ($GLOBALS['BE_USER']->workspace!=0) { 01333 01334 // Check for versioning support of the table: 01335 if ($TCA[$table] && $TCA[$table]['ctrl']['versioningWS']) { 01336 01337 // If the record is already a version of "something" pass it by. 01338 if ($reqRecord['pid']==-1) { 01339 01340 // (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) 01341 return $reqRecord; 01342 } else { // The input record was online and an offline version must be found or made: 01343 01344 // Look for version of this workspace: 01345 $versionRec = t3lib_BEfunc::getWorkspaceVersionOfRecord($GLOBALS['BE_USER']->workspace, $table, $reqRecord['uid'],'uid,pid,t3ver_oid'); 01346 return is_array($versionRec) ? $versionRec : $reqRecord; 01347 } 01348 } 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. 01349 } else return $reqRecord; // In ONLINE workspace, just return the originally requested record: 01350 } else return FALSE; // Return false because the table/uid was not found anyway. 01351 } 01352 01353 /** 01354 * 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 01355 * 01356 * @return void 01357 */ 01358 function editRegularContentFromId() { 01359 if (t3lib_extMgm::isLoaded('cms')) { 01360 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 01361 'uid', 01362 'tt_content', 01363 'pid='.intval($this->editRegularContentFromId). 01364 t3lib_BEfunc::deleteClause('tt_content'). 01365 t3lib_BEfunc::versioningPlaceholderClause('tt_content'). 01366 ' AND colPos=0 AND sys_language_uid=0', 01367 '', 01368 'sorting' 01369 ); 01370 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res)) { 01371 $ecUids=array(); 01372 while($ecRec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 01373 $ecUids[]=$ecRec['uid']; 01374 } 01375 $this->editconf['tt_content'][implode(',',$ecUids)]='edit'; 01376 } 01377 } 01378 } 01379 01380 /** 01381 * Populates the variables $this->storeArray, $this->storeUrl, $this->storeUrlMd5 01382 * 01383 * @return void 01384 * @see makeDocSel() 01385 */ 01386 function compileStoreDat() { 01387 $this->storeArray = t3lib_div::compileSelectedGetVarsFromArray('edit,defVals,overrideVals,columnsOnly,disHelp,noView,editRegularContentFromId',$this->R_URL_getvars); 01388 $this->storeUrl = t3lib_div::implodeArrayForUrl('',$this->storeArray); 01389 $this->storeUrlMd5 = md5($this->storeUrl); 01390 } 01391 01392 /** 01393 * Function used to look for configuration of buttons in the form: Fx. disabling buttons or showing them at various positions. 01394 * 01395 * @param string The table for which the configuration may be specific 01396 * @param string The option for look for. Default is checking if the saveDocNew button should be displayed. 01397 * @return string Return value fetched from USER TSconfig 01398 */ 01399 function getNewIconMode($table, $key = 'saveDocNew') { 01400 $TSconfig = $GLOBALS['BE_USER']->getTSConfig('options.'.$key); 01401 $output = trim(isset($TSconfig['properties'][$table]) ? $TSconfig['properties'][$table] : $TSconfig['value']); 01402 return $output; 01403 } 01404 01405 /** 01406 * Handling the closing of a document 01407 * 01408 * @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 01409 * @return void 01410 */ 01411 function closeDocument($code=0) { 01412 global $BE_USER; 01413 01414 // If current document is found in docHandler, 01415 // then unset it, possibly unset it ALL and finally, write it to the session data 01416 if (isset($this->docHandler[$this->storeUrlMd5])) { 01417 01418 // add the closing document to the recent documents 01419 $recentDocs = $BE_USER->getModuleData('opendocs::recent'); 01420 if (!is_array($recentDocs)) { 01421 $recentDocs = array(); 01422 } 01423 $closedDoc = $this->docHandler[$this->storeUrlMd5]; 01424 $recentDocs = array_merge(array($this->storeUrlMd5 => $closedDoc), $recentDocs); 01425 if (count($recentDocs) > 8) { 01426 $recentDocs = array_slice($recentDocs, 0, 8); 01427 } 01428 01429 // remove it from the list of the open documents 01430 unset($this->docHandler[$this->storeUrlMd5]); 01431 if ($code == '3') { 01432 $recentDocs = array_merge($this->docHandler, $recentDocs); 01433 $this->docHandler = array(); 01434 } 01435 $BE_USER->pushModuleData('opendocs::recent', $recentDocs); 01436 $BE_USER->pushModuleData('alt_doc.php', array($this->docHandler, $this->docDat[1])); 01437 t3lib_BEfunc::setUpdateSignal('tx_opendocs::updateNumber', count($this->docHandler)); 01438 } 01439 01440 01441 // 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...) 01442 if ($this->returnEditConf && $this->retUrl!='dummy.php') { 01443 $this->retUrl.='&returnEditConf='.rawurlencode(serialize($this->editconf)); 01444 } 01445 01446 // If code is NOT set OR set to 1, then make a header location redirect to $this->retUrl 01447 if (!$code || $code==1) { 01448 t3lib_utility_Http::redirect($this->retUrl); 01449 } else { 01450 $this->setDocument('',$this->retUrl); 01451 } 01452 } 01453 01454 /** 01455 * Redirects to the document pointed to by $currentDocFromHandlerMD5 OR $retUrl (depending on some internal calculations). 01456 * Most likely you will get a header-location redirect from this function. 01457 * 01458 * @param string Pointer to the document in the docHandler array 01459 * @param string Alternative/Default retUrl 01460 * @return void 01461 */ 01462 function setDocument($currentDocFromHandlerMD5='',$retUrl='alt_doc_nodoc.php') { 01463 if (!t3lib_extMgm::isLoaded('cms') && !strcmp($retUrl,'alt_doc_nodoc.php')) return; 01464 01465 if (!$this->modTSconfig['properties']['disableDocSelector'] && is_array($this->docHandler) && count($this->docHandler)) { 01466 if (isset($this->docHandler[$currentDocFromHandlerMD5])) { 01467 $setupArr=$this->docHandler[$currentDocFromHandlerMD5]; 01468 } else { 01469 reset($this->docHandler); 01470 $setupArr=current($this->docHandler); 01471 } 01472 if ($setupArr[2]) { 01473 $sParts = parse_url(t3lib_div::getIndpEnv('REQUEST_URI')); 01474 $retUrl = $sParts['path'].'?'.$setupArr[2].'&returnUrl='.rawurlencode($retUrl); 01475 } 01476 } 01477 t3lib_utility_Http::redirect($retUrl); 01478 } 01479 } 01480 01481 01482 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/alt_doc.php'])) { 01483 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/alt_doc.php']); 01484 } 01485 01486 01487 01488 // Make instance: 01489 $SOBE = t3lib_div::makeInstance('SC_alt_doc'); 01490 01491 // Preprocessing, storing data if submitted to 01492 $SOBE->preInit(); 01493 01494 $formprotection = t3lib_formprotection_Factory::get(); 01495 01496 if ($SOBE->doProcessData()) { // Checks, if a save button has been clicked (or the doSave variable is sent) 01497 if ($formprotection->validateToken(t3lib_div::_GP('formToken'), 'editRecord')) { 01498 $SOBE->processData(); 01499 } 01500 } 01501 01502 // Main: 01503 $SOBE->init(); 01504 $SOBE->main(); 01505 $SOBE->printContent(); 01506 01507 ?>
1.8.0