PageRenderTime 14ms CodeModel.GetById 44ms app.highlight 32ms RepoModel.GetById 1ms app.codeStats 2ms

/t3lib/class.t3lib_tceforms.php

https://github.com/andreaswolf/typo3-tceforms
PHP | 6513 lines | 4223 code | 671 blank | 1619 comment | 831 complexity | 62ef0b9f429b94ccbed1910110392289 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1<?php
   2/***************************************************************
   3 *  Copyright notice
   4 *
   5 *  (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
   6 *  All rights reserved
   7 *
   8 *  This script is part of the TYPO3 project. The TYPO3 project is
   9 *  free software; you can redistribute it and/or modify
  10 *  it under the terms of the GNU General Public License as published by
  11 *  the Free Software Foundation; either version 2 of the License, or
  12 *  (at your option) any later version.
  13 *
  14 *  The GNU General Public License can be found at
  15 *  http://www.gnu.org/copyleft/gpl.html.
  16 *  A copy is found in the textfile GPL.txt and important notices to the license
  17 *  from the author is found in LICENSE.txt distributed with these scripts.
  18 *
  19 *
  20 *  This script is distributed in the hope that it will be useful,
  21 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23 *  GNU General Public License for more details.
  24 *
  25 *  This copyright notice MUST APPEAR in all copies of the script!
  26 ***************************************************************/
  27/**
  28 * Contains TYPO3 Core Form generator - AKA "TCEforms"
  29 *
  30 * $Id$
  31 * Revised for TYPO3 3.6 August/2003 by Kasper Skårhøj
  32 * XHTML compliant
  33 *
  34 * @author	Kasper Skårhøj <kasperYYYY@typo3.com>
  35 */
  36/**
  37 * [CLASS/FUNCTION INDEX of SCRIPT]
  38 *
  39 *
  40 *
  41 *  196: class t3lib_TCEforms
  42 *  302:	 function t3lib_TCEforms()
  43 *  338:	 function initDefaultBEmode()
  44 *
  45 *			  SECTION: Rendering the forms, fields etc
  46 *  385:	 function getSoloField($table,$row,$theFieldToReturn)
  47 *  424:	 function getMainFields($table,$row,$depth=0)
  48 *  618:	 function getListedFields($table,$row,$list)
  49 *  660:	 function getPaletteFields($table,$row,$palette,$header='',$itemList='',$collapsedHeader='')
  50 *  737:	 function getSingleField($table,$field,$row,$altName='',$palette=0,$extra='',$pal=0)
  51 *  900:	 function getSingleField_SW($table,$field,$row,&$PA)
  52 *
  53 *			  SECTION: Rendering of each TCEform field type
  54 *  976:	 function getSingleField_typeInput($table,$field,$row,&$PA)
  55 * 1057:	 function getSingleField_typeText($table,$field,$row,&$PA)
  56 * 1178:	 function getSingleField_typeCheck($table,$field,$row,&$PA)
  57 * 1244:	 function getSingleField_typeRadio($table,$field,$row,&$PA)
  58 * 1279:	 function getSingleField_typeSelect($table,$field,$row,&$PA)
  59 * 1359:	 function getSingleField_typeSelect_single($table,$field,$row,&$PA,$config,$selItems,$nMV_label)
  60 * 1490:	 function getSingleField_typeSelect_checkbox($table,$field,$row,&$PA,$config,$selItems,$nMV_label)
  61 * 1609:	 function getSingleField_typeSelect_singlebox($table,$field,$row,&$PA,$config,$selItems,$nMV_label)
  62 * 1719:	 function getSingleField_typeSelect_multiple($table,$field,$row,&$PA,$config,$selItems,$nMV_label)
  63 * 1823:	 function getSingleField_typeGroup($table,$field,$row,&$PA)
  64 * 1992:	 function getSingleField_typeNone($table,$field,$row,&$PA)
  65 * 2008:	 function getSingleField_typeNone_render($config,$itemValue)
  66 * 2070:	 function getSingleField_typeFlex($table,$field,$row,&$PA)
  67 * 2205:	 function getSingleField_typeFlex_langMenu($languages,$elName,$selectedLanguage,$multi=1)
  68 * 2224:	 function getSingleField_typeFlex_sheetMenu($sArr,$elName,$sheetKey)
  69 * 2259:	 function getSingleField_typeFlex_draw($dataStruct,$editData,$cmdData,$table,$field,$row,&$PA,$formPrefix='',$level=0,$tRows=array())
  70 * 2452:	 function getSingleField_typeUnknown($table,$field,$row,&$PA)
  71 * 2467:	 function getSingleField_typeUser($table,$field,$row,&$PA)
  72 *
  73 *			  SECTION: Field content processing
  74 * 2496:	 function formatValue ($config, $itemValue)
  75 *
  76 *			  SECTION: "Configuration" fetching/processing functions
  77 * 2588:	 function getRTypeNum($table,$row)
  78 * 2614:	 function rearrange($fields)
  79 * 2640:	 function getExcludeElements($table,$row,$typeNum)
  80 * 2688:	 function getFieldsToAdd($table,$row,$typeNum)
  81 * 2713:	 function mergeFieldsWithAddedFields($fields,$fieldsToAdd)
  82 * 2745:	 function setTSconfig($table,$row,$field='')
  83 * 2767:	 function getSpecConfForField($table,$row,$field)
  84 * 2788:	 function getSpecConfFromString($extraString, $defaultExtras)
  85 * 3007:	 function loadPaletteElements($table, $row, $palette, $itemList='')
  86 *
  87 *			  SECTION: Display of localized content etc.
  88 * 2816:	 function registerDefaultLanguageData($table,$rec)
  89 * 2848:	 function getLanguageOverlayRawValue($table, $row, $field, $fieldConf)
  90 * 2876:	 function renderDefaultLanguageContent($table,$field,$row,$item)
  91 * 2899:	 function renderDefaultLanguageDiff($table,$field,$row,$item)
  92 *
  93 *			  SECTION: Form element helper functions
  94 * 2955:	 function dbFileIcons($fName,$mode,$allowed,$itemArray,$selector='',$params=array(),$onFocus='')
  95 * 3108:	 function getClipboardElements($allowed,$mode)
  96 * 3157:	 function getClickMenu($str,$table,$uid='')
  97 * 3178:	 function renderWizards($itemKinds,$wizConf,$table,$row,$field,&$PA,$itemName,$specConf,$RTE=0)
  98 * 3382:	 function getIcon($icon)
  99 * 3409:	 function optionTagStyle($iconString)
 100 * 3425:	 function extractValuesOnlyFromValueLabelList($itemFormElValue)
 101 * 3447:	 function wrapOpenPalette($header,$table,$row,$palette,$retFunc=0)
 102 * 3471:	 function checkBoxParams($itemName,$thisValue,$c,$iCount,$addFunc='')
 103 * 3485:	 function elName($itemName)
 104 * 3496:	 function noTitle($str,$wrapParts=array())
 105 * 3505:	 function blur()
 106 * 3514:	 function thisReturnUrl()
 107 * 3527:	 function getSingleHiddenField($table,$field,$row)
 108 * 3549:	 function formWidth($size=48,$textarea=0)
 109 * 3576:	 function formWidthText($size=48,$wrap='')
 110 * 3592:	 function formElStyle($type)
 111 * 3603:	 function formElClass($type)
 112 * 3614:	 function formElStyleClassValue($type, $class=FALSE)
 113 * 3638:	 function insertDefStyle($type)
 114 * 3657:	 function getDynTabMenu($parts, $idString)
 115 *
 116 *			  SECTION: Item-array manipulation functions (check/select/radio)
 117 * 3696:	 function initItemArray($fieldValue)
 118 * 3714:	 function addItems($items,$iArray)
 119 * 3736:	 function procItems($items,$iArray,$config,$table,$row,$field)
 120 * 3760:	 function addSelectOptionsToItemArray($items,$fieldValue,$TSconfig,$field)
 121 * 3980:	 function addSelectOptionsToItemArray_makeModuleData($value)
 122 * 4002:	 function foreignTable($items,$fieldValue,$TSconfig,$field,$pFFlag=0)
 123 *
 124 *			  SECTION: Template functions
 125 * 4083:	 function setNewBEDesign()
 126 * 4138:	 function intoTemplate($inArr,$altTemplate='')
 127 * 4162:	 function addUserTemplateMarkers($marker,$table,$field,$row,&$PA)
 128 * 4173:	 function wrapLabels($str)
 129 * 4186:	 function wrapTotal($c,$rec,$table)
 130 * 4199:	 function replaceTableWrap($arr,$rec,$table)
 131 * 4236:	 function wrapBorder(&$out_array,&$out_pointer)
 132 * 4258:	 function rplColorScheme($inTemplate)
 133 * 4278:	 function getDivider()
 134 * 4288:	 function printPalette($palArr)
 135 * 4339:	 function helpTextIcon($table,$field,$force=0)
 136 * 4359:	 function helpText($table,$field)
 137 * 4380:	 function setColorScheme($scheme)
 138 * 4404:	 function resetSchemes()
 139 * 4415:	 function storeSchemes()
 140 * 4427:	 function restoreSchemes()
 141 *
 142 *			  SECTION: JavaScript related functions
 143 * 4457:	 function JStop()
 144 * 4508:	 function JSbottom($formname='forms[0]')
 145 * 4835:	 function dbFileCon($formObj='document.forms[0]')
 146 * 5053:	 function printNeededJSFunctions()
 147 * 5080:	 function printNeededJSFunctions_top()
 148 *
 149 *			  SECTION: Various helper functions
 150 * 5128:	 function getDefaultRecord($table,$pid=0)
 151 * 5167:	 function getRecordPath($table,$rec)
 152 * 5181:	 function readPerms()
 153 * 5195:	 function sL($str)
 154 * 5208:	 function getLL($str)
 155 * 5229:	 function isPalettesCollapsed($table,$palette)
 156 * 5245:	 function isDisplayCondition($displayCond,$row,$ffValueKey='')
 157 * 5349:	 function getTSCpid($table,$uid,$pid)
 158 * 5363:	 function doLoadTableDescr($table)
 159 * 5375:	 function getAvailableLanguages($onlyIsoCoded=1,$setDefault=1)
 160 *
 161 *
 162 * 5417: class t3lib_TCEforms_FE extends t3lib_TCEforms
 163 * 5425:	 function wrapLabels($str)
 164 * 5435:	 function printPalette($palArr)
 165 * 5460:	 function setFancyDesign()
 166 *
 167 * TOTAL FUNCTIONS: 100
 168 * (This index is automatically created/updated by the extension "extdeveval")
 169 *
 170 */
 171
 172
 173/**
 174 * 'TCEforms' - Class for creating the backend editing forms.
 175 *
 176 * @author	Kasper Skårhøj <kasperYYYY@typo3.com>
 177 * @coauthor	René Fritz <r.fritz@colorcube.de>
 178 * @package TYPO3
 179 * @subpackage t3lib
 180 */
 181class t3lib_TCEforms {
 182
 183		// variables not commented yet.... (do so...)
 184	var $palFieldArr = array();
 185	var $disableWizards = 0;
 186	var $isPalettedoc = 0;
 187	var $paletteMargin = 1;
 188	var $defStyle = ''; // 'font-family:Verdana;font-size:10px;';
 189	var $cachedTSconfig = array();
 190	var $cachedTSconfig_fieldLevel = array();
 191	var $cachedLanguageFlag = array();
 192	var $cachedAdditionalPreviewLanguages = NULL;
 193	var $transformedRow = array();
 194	var $extJSCODE = '';
 195	var $printNeededJS = array();
 196	var $hiddenFieldAccum = array();
 197	var $TBE_EDITOR_fieldChanged_func = '';
 198	var $loadMD5_JS = 1;
 199	var $prevBorderStyle = '[nothing here...]'; // Something unique...
 200	var $allowUpload = 0; // If set direct upload fields will be shown
 201	var $titleLen = 15; // @deprecated since TYPO3 4.1: $BE_USER->uc['titleLen'] but what is default??
 202	var $defaultLanguageData = array(); // Array where records in the default language is stored. (processed by transferdata)
 203	var $defaultLanguageData_diff = array(); // Array where records in the default language is stored (raw without any processing. used for making diff)
 204	var $additionalPreviewLanguageData = array();
 205
 206
 207		// EXTERNAL, static
 208	var $backPath = ''; // Set this to the 'backPath' pointing back to the typo3 admin directory from the script where this form is displayed.
 209	var $returnUrl = ''; // Alternative return URL path (default is t3lib_div::linkThisScript())
 210	var $doSaveFieldName = ''; // Can be set to point to a field name in the form which will be set to '1' when the form is submitted with a *save* button. This way the recipient script can determine that the form was submitted for save and not "close" for example.
 211	var $palettesCollapsed = 0; // Can be set true/false to whether palettes (secondary options) are in the topframe or in form. True means they are NOT IN-form. So a collapsed palette is one, which is shown in the top frame, not in the page.
 212	var $disableRTE = 0; // If set, the RTE is disabled (from form display, eg. by checkbox in the bottom of the page!)
 213	var $globalShowHelp = 1; // If false, then all CSH will be disabled, regardless of settings in $this->edit_showFieldHelp
 214	var $localizationMode = ''; // If true, the forms are rendering only localization relevant fields of the records.
 215	var $fieldOrder = ''; // Overrule the field order set in TCA[types][showitem], eg for tt_content this value, 'bodytext,image', would make first the 'bodytext' field, then the 'image' field (if set for display)... and then the rest in the old order.
 216	var $doPrintPalette = 1; // If set to false, palettes will NEVER be rendered.
 217
 218	/**
 219	 * Set to initialized clipboard object; Then the element browser will offer a link to paste in records from clipboard.
 220	 *
 221	 * @var t3lib_clipboard
 222	 */
 223	var $clipObj = FALSE;
 224	var $enableClickMenu = FALSE; // Enable click menu on reference icons.
 225	var $enableTabMenu = FALSE; // Enable Tab Menus.
 226	var $renderReadonly = FALSE; // When enabled all fields are rendered non-editable.
 227
 228	var $form_rowsToStylewidth = 9.58; // Form field width compensation: Factor from NN4 form field widths to style-aware browsers (like NN6+ and MSIE, with the $CLIENT[FORMSTYLE] value set)
 229	var $form_largeComp = 1.33; // Form field width compensation: Compensation for large documents, doc-tab (editing)
 230	var $charsPerRow = 40; // The number of chars expected per row when the height of a text area field is automatically calculated based on the number of characters found in the field content.
 231	var $maxTextareaWidth = 48; // The maximum abstract value for textareas
 232	var $maxInputWidth = 48; // The maximum abstract value for input fields
 233	var $defaultMultipleSelectorStyle = 'width:250px;'; // Default style for the selector boxes used for multiple items in "select" and "group" types.
 234
 235
 236		// INTERNAL, static
 237	var $prependFormFieldNames = 'data'; // The string to prepend formfield names with.
 238	var $prependCmdFieldNames = 'cmd'; // The string to prepend commands for tcemain::process_cmdmap with.
 239	var $prependFormFieldNames_file = 'data_files'; // The string to prepend FILE form field names with.
 240	var $formName = 'editform'; // The name attribute of the form.
 241	var $allowOverrideMatrix = array(); // Whitelist that allows TCA field configuration to be overridden by TSconfig, @see overrideFieldConf()
 242
 243
 244		// INTERNAL, dynamic
 245	var $perms_clause = ''; // Set by readPerms()  (caching)
 246	var $perms_clause_set = 0; // Set by readPerms()  (caching-flag)
 247	var $edit_showFieldHelp = ''; // Used to indicate the mode of CSH (Context Sensitive Help), whether it should be icons-only ('icon'), full description ('text') or not at all (blank).
 248	var $docLarge = 0; // If set, the forms will be rendered a little wider, more precisely with a factor of $this->form_largeComp.
 249	var $clientInfo = array(); // Loaded with info about the browser when class is instantiated.
 250	var $RTEenabled = 0; // True, if RTE is possible for the current user (based on result from BE_USER->isRTE())
 251	var $RTEenabled_notReasons = ''; // If $this->RTEenabled was false, you can find the reasons listed in this array which is filled with reasons why the RTE could not be loaded)
 252	var $RTEcounter = 0; // Counter that is incremented before an RTE is created. Can be used for unique ids etc.
 253
 254	var $colorScheme; // Contains current color scheme
 255	var $classScheme; // Contains current class scheme
 256	var $defColorScheme; // Contains the default color scheme
 257	var $defClassScheme; // Contains the default class scheme
 258	var $fieldStyle; // Contains field style values
 259	var $borderStyle; // Contains border style values.
 260
 261	var $commentMessages = array(); // An accumulation of messages from the class.
 262
 263		// INTERNAL, templates
 264	var $totalWrap = '<hr />|<hr />'; // Total wrapping for the table rows.
 265	var $fieldTemplate = '<strong>###FIELD_NAME###</strong><br />###FIELD_ITEM###<hr />'; // Field template
 266	var $sectionWrap = ''; // Wrapping template code for a section
 267	var $palFieldTemplateHeader = ''; // Template for palette headers
 268	var $palFieldTemplate = ''; // Template for palettes
 269
 270		// INTERNAL, working memory
 271	var $excludeElements = ''; // Set to the fields NOT to display, if any.
 272	var $palettesRendered = array(); // During rendering of forms this will keep track of which palettes has already been rendered (so they are not rendered twice by mistake)
 273	var $hiddenFieldListArr = array(); // This array of fields will be set as hidden-fields instead of rendered normally! For instance palette fields edited in the top frame are set as hidden fields since the main form has to submit the values. The top frame actually just sets the value in the main form!
 274	var $requiredFields = array(); // Used to register input-field names, which are required. (Done during rendering of the fields). This information is then used later when the JavaScript is made.
 275	var $requiredAdditional = array(); // Used to register input-field names, which are required an have additional requirements (e.g. like a date/time must be positive integer). The information of this array is merged with $this->requiredFields later.
 276	var $requiredElements = array(); // Used to register the min and max number of elements for selectorboxes where that apply (in the "group" type for instance)
 277	var $requiredNested = array(); // Used to determine where $requiredFields or $requiredElements are nested (in Tabs or IRRE)
 278	var $renderDepth = 0; // Keeps track of the rendering depth of nested records.
 279	var $savedSchemes = array(); // Color scheme buffer.
 280	var $dynNestedStack = array(); // holds the path an element is nested in (e.g. required for RTEhtmlarea)
 281
 282		// Internal, registers for user defined functions etc.
 283	var $additionalCode_pre = array(); // Additional HTML code, printed before the form.
 284	var $additionalJS_pre = array(); // Additional JavaScript, printed before the form
 285	var $additionalJS_post = array(); // Additional JavaScript printed after the form
 286	var $additionalJS_submit = array(); // Additional JavaScript executed on submit; If you set "OK" variable it will raise an error about RTEs not being loaded and offer to block further submission.
 287	var $additionalJS_delete = array(); // Additional JavaScript executed when section element is deleted. This is neceessary, for example, to correctly clean up HTMLArea RTE (bug #8232)
 288
 289	/**
 290	 * Instance of t3lib_tceforms_inline
 291	 *
 292	 * @var t3lib_TCEforms_inline
 293	 */
 294	var $inline;
 295	var $hookObjectsMainFields = array(); // Array containing hook class instances called once for a form
 296	var $hookObjectsSingleField = array(); // Array containing hook class instances called for each field
 297	var $extraFormHeaders = array(); // Rows gettings inserted into the alt_doc headers (when called from alt_doc.php)
 298
 299	public $templateFile = ''; // Form templates, relative to typo3 directory
 300
 301
 302	/**
 303	 * Constructor function, setting internal variables, loading the styles used.
 304	 *
 305	 * @return	void
 306	 */
 307	function t3lib_TCEforms() {
 308		global $CLIENT, $TYPO3_CONF_VARS;
 309
 310		$this->clientInfo = t3lib_div::clientInfo();
 311
 312		$this->RTEenabled = $GLOBALS['BE_USER']->isRTE();
 313		if (!$this->RTEenabled) {
 314			$this->RTEenabled_notReasons = implode(LF, $GLOBALS['BE_USER']->RTE_errors);
 315			$this->commentMessages[] = 'RTE NOT ENABLED IN SYSTEM due to:' . LF . $this->RTEenabled_notReasons;
 316		}
 317
 318			// Default color+class scheme
 319		$this->defColorScheme = array(
 320			$GLOBALS['SOBE']->doc->bgColor, // Background for the field AND palette
 321			t3lib_div::modifyHTMLColorAll($GLOBALS['SOBE']->doc->bgColor, -20), // Background for the field header
 322			t3lib_div::modifyHTMLColorAll($GLOBALS['SOBE']->doc->bgColor, -10), // Background for the palette field header
 323			'black', // Field header font color
 324			'#666666' // Palette field header font color
 325		);
 326		$this->defColorScheme = array();
 327
 328			// Override / Setting defaults from TBE_STYLES array
 329		$this->resetSchemes();
 330
 331			// Setting the current colorScheme to default.
 332		$this->defColorScheme = $this->colorScheme;
 333		$this->defClassScheme = $this->classScheme;
 334
 335			// Define whitelist that allows TCA field configuration to be overridden by TSconfig, @see overrideFieldConf():
 336		$this->allowOverrideMatrix = array(
 337			'input' => array('size', 'max'),
 338			'text' => array('cols', 'rows', 'wrap'),
 339			'check' => array('cols', 'showIfRTE'),
 340			'select' => array('size', 'autoSizeMax', 'maxitems', 'minitems'),
 341			'group' => array('size', 'autoSizeMax', 'max_size', 'show_thumbs', 'maxitems', 'minitems', 'disable_controls'),
 342			'inline' => array('appearance', 'behaviour', 'foreign_label', 'foreign_selector', 'foreign_unique', 'maxitems', 'minitems', 'size', 'autoSizeMax', 'symmetric_label'),
 343		);
 344
 345			// Create instance of t3lib_TCEforms_inline only if this a non-IRRE-AJAX call:
 346		if (!isset($GLOBALS['ajaxID']) || strpos($GLOBALS['ajaxID'], 't3lib_TCEforms_inline::') !== 0) {
 347			$this->inline = t3lib_div::makeInstance('t3lib_TCEforms_inline');
 348		}
 349			// Create instance of t3lib_TCEforms_suggest only if this a non-Suggest-AJAX call:
 350		if (!isset($GLOBALS['ajaxID']) || strpos($GLOBALS['ajaxID'], 't3lib_TCEforms_suggest::') !== 0) {
 351			$this->suggest = t3lib_div::makeInstance('t3lib_TCEforms_suggest');
 352		}
 353
 354			// Prepare user defined objects (if any) for hooks which extend this function:
 355		$this->hookObjectsMainFields = array();
 356		if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['getMainFieldsClass'])) {
 357			foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['getMainFieldsClass'] as $classRef) {
 358				$this->hookObjectsMainFields[] = t3lib_div::getUserObj($classRef);
 359			}
 360		}
 361		$this->hookObjectsSingleField = array();
 362		if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['getSingleFieldClass'])) {
 363			foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['getSingleFieldClass'] as $classRef) {
 364				$this->hookObjectsSingleField[] = t3lib_div::getUserObj($classRef);
 365			}
 366		}
 367
 368		$this->templateFile = 'templates/tceforms.html';
 369
 370	}
 371
 372	/**
 373	 * Initialize various internal variables.
 374	 *
 375	 * @return	void
 376	 */
 377	function initDefaultBEmode() {
 378		global $BE_USER;
 379		$this->prependFormFieldNames = 'data';
 380		$this->formName = 'editform';
 381		$this->setNewBEDesign();
 382		$this->docLarge = $BE_USER->uc['edit_wideDocument'] ? 1 : 0;
 383		$this->edit_showFieldHelp = $BE_USER->uc['edit_showFieldHelp'];
 384
 385		$this->edit_docModuleUpload = $BE_USER->uc['edit_docModuleUpload'];
 386		$this->titleLen = $BE_USER->uc['titleLen']; // @deprecated since TYPO3 4.1
 387
 388		$this->inline->init($this);
 389		$this->suggest->init($this);
 390	}
 391
 392
 393	/*******************************************************
 394	 *
 395	 * Rendering the forms, fields etc
 396	 *
 397	 *******************************************************/
 398
 399	/**
 400	 * Will return the TCEform element for just a single field from a record.
 401	 * The field must be listed in the currently displayed fields (as found in [types][showitem]) for the record.
 402	 * This also means that the $table/$row supplied must be complete so the list of fields to show can be found correctly
 403	 *
 404	 * @param	string		The table name
 405	 * @param	array		The record from the table for which to render a field.
 406	 * @param	string		The field name to return the TCEform element for.
 407	 * @return	string		HTML output
 408	 * @see getMainFields()
 409	 */
 410	function getSoloField($table, $row, $theFieldToReturn) {
 411		global $TCA;
 412
 413		if ($TCA[$table]) {
 414			t3lib_div::loadTCA($table);
 415			$typeNum = $this->getRTypeNum($table, $row);
 416			if ($TCA[$table]['types'][$typeNum]) {
 417				$itemList = $TCA[$table]['types'][$typeNum]['showitem'];
 418				if ($itemList) {
 419					$fields = t3lib_div::trimExplode(',', $itemList, 1);
 420					$excludeElements = $this->excludeElements = $this->getExcludeElements($table, $row, $typeNum);
 421
 422					foreach ($fields as $fieldInfo) {
 423						$parts = explode(';', $fieldInfo);
 424
 425						$theField = trim($parts[0]);
 426						if (!in_array($theField, $excludeElements) && !strcmp($theField, $theFieldToReturn)) {
 427							if ($TCA[$table]['columns'][$theField]) {
 428								$sField = $this->getSingleField($table, $theField, $row, $parts[1], 1, $parts[3], $parts[2]);
 429								return $sField['ITEM'];
 430							}
 431						}
 432					}
 433				}
 434			}
 435		}
 436	}
 437
 438	/**
 439	 * Based on the $table and $row of content, this displays the complete TCEform for the record.
 440	 * The input-$row is required to be preprocessed if necessary by eg. the t3lib_transferdata class. For instance the RTE content should be transformed through this class first.
 441	 *
 442	 * @param	string		The table name
 443	 * @param	array		The record from the table for which to render a field.
 444	 * @param	integer		Depth level
 445	 * @return	string		HTML output
 446	 * @see getSoloField()
 447	 */
 448	function getMainFields($table, $row, $depth = 0) {
 449		global $TCA, $TYPO3_CONF_VARS;
 450
 451		$this->renderDepth = $depth;
 452
 453			// Init vars:
 454		$out_array = array(array());
 455		$out_array_meta = array(array(
 456									'title' => $this->getLL('l_generalTab')
 457								));
 458
 459		$out_pointer = 0;
 460		$out_sheet = 0;
 461		$this->palettesRendered = array();
 462		$this->palettesRendered[$this->renderDepth][$table] = array();
 463
 464			// Hook: getMainFields_preProcess (requested by Thomas Hempel for use with the "dynaflex" extension)
 465		foreach ($this->hookObjectsMainFields as $hookObj) {
 466			if (method_exists($hookObj, 'getMainFields_preProcess')) {
 467				$hookObj->getMainFields_preProcess($table, $row, $this);
 468			}
 469		}
 470
 471		if ($TCA[$table]) {
 472
 473				// Load the full TCA for the table.
 474			t3lib_div::loadTCA($table);
 475
 476				// Get dividers2tabs setting from TCA of the current table:
 477			$dividers2tabs =& $TCA[$table]['ctrl']['dividers2tabs'];
 478
 479				// Load the description content for the table.
 480			if ($this->edit_showFieldHelp || $this->doLoadTableDescr($table)) {
 481				$GLOBALS['LANG']->loadSingleTableDescription($table);
 482			}
 483				// Get the current "type" value for the record.
 484			$typeNum = $this->getRTypeNum($table, $row);
 485
 486				// Find the list of fields to display:
 487			if ($TCA[$table]['types'][$typeNum]) {
 488				$itemList = $TCA[$table]['types'][$typeNum]['showitem'];
 489				if ($itemList) { // If such a list existed...
 490						// Explode the field list and possibly rearrange the order of the fields, if configured for
 491					$fields = t3lib_div::trimExplode(',', $itemList, 1);
 492					if ($this->fieldOrder) {
 493						$fields = $this->rearrange($fields);
 494					}
 495
 496						// Get excluded fields, added fiels and put it together:
 497					$excludeElements = $this->excludeElements = $this->getExcludeElements($table, $row, $typeNum);
 498					$fields = $this->mergeFieldsWithAddedFields($fields, $this->getFieldsToAdd($table, $row, $typeNum));
 499
 500						// If TCEforms will render a tab menu in the next step, push the name to the tab stack:
 501					$tabIdentString = '';
 502					$tabIdentStringMD5 = '';
 503					if (strstr($itemList, '--div--') !== false && $this->enableTabMenu && $dividers2tabs) {
 504						$tabIdentString = 'TCEforms:' . $table . ':' . $row['uid'];
 505						$tabIdentStringMD5 = $GLOBALS['TBE_TEMPLATE']->getDynTabMenuId($tabIdentString);
 506							// Remember that were currently working on the general tab:
 507						if (isset($fields[0]) && strpos($fields[0], '--div--') !== 0) {
 508							$this->pushToDynNestedStack('tab', $tabIdentStringMD5 . '-1');
 509						}
 510					}
 511
 512						// Traverse the fields to render:
 513					$cc = 0;
 514					foreach ($fields as $fieldInfo) {
 515							// Exploding subparts of the field configuration:
 516						$parts = explode(';', $fieldInfo);
 517
 518							// Getting the style information out:
 519						$color_style_parts = t3lib_div::trimExplode('-', $parts[4]);
 520						if (strcmp($color_style_parts[0], '')) {
 521							$this->setColorScheme($GLOBALS['TBE_STYLES']['colorschemes'][intval($color_style_parts[0])]);
 522						}
 523						if (strcmp($color_style_parts[1], '')) {
 524							$this->fieldStyle = $GLOBALS['TBE_STYLES']['styleschemes'][intval($color_style_parts[1])];
 525							if (!isset($this->fieldStyle)) {
 526								$this->fieldStyle = $GLOBALS['TBE_STYLES']['styleschemes'][0];
 527							}
 528						}
 529						if (strcmp($color_style_parts[2], '')) {
 530							$this->wrapBorder($out_array[$out_sheet], $out_pointer);
 531							$this->borderStyle = $GLOBALS['TBE_STYLES']['borderschemes'][intval($color_style_parts[2])];
 532							if (!isset($this->borderStyle)) {
 533								$this->borderStyle = $GLOBALS['TBE_STYLES']['borderschemes'][0];
 534							}
 535						}
 536
 537							// Render the field:
 538						$theField = $parts[0];
 539						if (!in_array($theField, $excludeElements)) {
 540							if ($TCA[$table]['columns'][$theField]) {
 541								$sFieldPal = '';
 542
 543								if ($parts[2] && !isset($this->palettesRendered[$this->renderDepth][$table][$parts[2]])) {
 544									$sFieldPal = $this->getPaletteFields($table, $row, $parts[2]);
 545									$this->palettesRendered[$this->renderDepth][$table][$parts[2]] = 1;
 546								}
 547								$sField = $this->getSingleField($table, $theField, $row, $parts[1], 0, $parts[3], $parts[2]);
 548								if ($sField) {
 549									$sField .= $sFieldPal;
 550								}
 551
 552								$out_array[$out_sheet][$out_pointer] .= $sField;
 553							} elseif ($theField == '--div--') {
 554								if ($cc > 0) {
 555									$out_array[$out_sheet][$out_pointer] .= $this->getDivider();
 556
 557									if ($this->enableTabMenu && $dividers2tabs) {
 558										$this->wrapBorder($out_array[$out_sheet], $out_pointer);
 559											// Remove last tab entry from the dynNestedStack:
 560										$out_sheet++;
 561											// Remove the previous sheet from stack (if any):
 562										$this->popFromDynNestedStack('tab', $tabIdentStringMD5 . '-' . ($out_sheet));
 563											// Remember on which sheet we're currently working:
 564										$this->pushToDynNestedStack('tab', $tabIdentStringMD5 . '-' . ($out_sheet + 1));
 565										$out_array[$out_sheet] = array();
 566										$out_array_meta[$out_sheet]['title'] = $this->sL($parts[1]);
 567											// Register newline for Tab
 568										$out_array_meta[$out_sheet]['newline'] = ($parts[2] == "newline");
 569									}
 570								} else { // Setting alternative title for "General" tab if "--div--" is the very first element.
 571									$out_array_meta[$out_sheet]['title'] = $this->sL($parts[1]);
 572										// Only add the first tab to the dynNestedStack if there are more tabs:
 573									if ($tabIdentString && strpos($itemList, '--div--', strlen($fieldInfo))) {
 574										$this->pushToDynNestedStack('tab', $tabIdentStringMD5 . '-1');
 575									}
 576								}
 577							} elseif ($theField == '--palette--') {
 578								if ($parts[2] && !isset($this->palettesRendered[$this->renderDepth][$table][$parts[2]])) {
 579										// render a 'header' if not collapsed
 580									if ($TCA[$table]['palettes'][$parts[2]]['canNotCollapse'] AND $parts[1]) {
 581										$out_array[$out_sheet][$out_pointer] .= $this->getPaletteFields($table, $row, $parts[2], $this->sL($parts[1]));
 582									} else {
 583										$out_array[$out_sheet][$out_pointer] .= $this->getPaletteFields($table, $row, $parts[2], '', '', $this->sL($parts[1]));
 584									}
 585									$this->palettesRendered[$this->renderDepth][$table][$parts[2]] = 1;
 586								}
 587							}
 588						}
 589
 590						$cc++;
 591					}
 592				}
 593			}
 594		}
 595
 596			// Hook: getMainFields_postProcess (requested by Thomas Hempel for use with the "dynaflex" extension)
 597		foreach ($this->hookObjectsMainFields as $hookObj) {
 598			if (method_exists($hookObj, 'getMainFields_postProcess')) {
 599				$hookObj->getMainFields_postProcess($table, $row, $this);
 600			}
 601		}
 602
 603			// Wrapping a border around it all:
 604		$this->wrapBorder($out_array[$out_sheet], $out_pointer);
 605
 606			// Resetting styles:
 607		$this->resetSchemes();
 608
 609			// Rendering Main palettes, if any
 610		$mParr = t3lib_div::trimExplode(',', $TCA[$table]['ctrl']['mainpalette']);
 611		$i = 0;
 612		if (count($mParr)) {
 613			foreach ($mParr as $mP) {
 614				if (!isset($this->palettesRendered[$this->renderDepth][$table][$mP])) {
 615					$temp_palettesCollapsed = $this->palettesCollapsed;
 616					$this->palettesCollapsed = 0;
 617					$label = ($i == 0 ? $this->getLL('l_generalOptions') : $this->getLL('l_generalOptions_more'));
 618					$out_array[$out_sheet][$out_pointer] .= $this->getPaletteFields($table, $row, $mP, $label);
 619					$this->palettesCollapsed = $temp_palettesCollapsed;
 620					$this->palettesRendered[$this->renderDepth][$table][$mP] = 1;
 621				}
 622				$this->wrapBorder($out_array[$out_sheet], $out_pointer);
 623				$i++;
 624				if ($this->renderDepth) {
 625					$this->renderDepth--;
 626				}
 627			}
 628		}
 629
 630			// Return the imploded $out_array:
 631		if ($out_sheet > 0) { // There were --div-- dividers around...
 632
 633				// Create parts array for the tab menu:
 634			$parts = array();
 635			foreach ($out_array as $idx => $sheetContent) {
 636				$content = implode('', $sheetContent);
 637				if ($content) {
 638						// Wrap content (row) with table-tag, otherwise tab/sheet will be disabled (see getdynTabMenu() )
 639					$content = '<table border="0" cellspacing="0" cellpadding="0" width="100%">' . $content . '</table>';
 640				}
 641				$parts[$idx] = array(
 642					'label' => $out_array_meta[$idx]['title'],
 643					'content' => $content,
 644					'newline' => $out_array_meta[$idx]['newline'], // Newline for this tab/sheet
 645				);
 646			}
 647
 648			if (count($parts) > 1) {
 649					// Unset the current level of tab menus:
 650				$this->popFromDynNestedStack('tab', $tabIdentStringMD5 . '-' . ($out_sheet + 1));
 651				$dividersToTabsBehaviour = (isset($TCA[$table]['ctrl']['dividers2tabs']) ? $TCA[$table]['ctrl']['dividers2tabs'] : 1);
 652				$output = $this->getDynTabMenu($parts, $tabIdentString, $dividersToTabsBehaviour);
 653
 654			} else {
 655					// If there is only one tab/part there is no need to wrap it into the dynTab code
 656				$output = isset($parts[0]) ? trim($parts[0]['content']) : '';
 657			}
 658
 659			$output = '
 660				<tr>
 661					<td colspan="2">
 662					' . $output . '
 663					</td>
 664				</tr>';
 665
 666		} else {
 667				// Only one, so just implode:
 668			$output = implode('', $out_array[$out_sheet]);
 669		}
 670
 671		return $output;
 672	}
 673
 674	/**
 675	 * Will return the TCEform elements for a pre-defined list of fields.
 676	 * Notice that this will STILL use the configuration found in the list [types][showitem] for those fields which are found there. So ideally the list of fields given as argument to this function should also be in the current [types][showitem] list of the record.
 677	 * Used for displaying forms for the frontend edit icons for instance.
 678	 *
 679	 * @param	string		The table name
 680	 * @param	array		The record array.
 681	 * @param	string		Commalist of fields from the table. These will be shown in the specified order in a form.
 682	 * @return	string		TCEform elements in a string.
 683	 */
 684	function getListedFields($table, $row, $list) {
 685		global $TCA;
 686
 687		t3lib_div::loadTCA($table);
 688		if ($this->edit_showFieldHelp || $this->doLoadTableDescr($table)) {
 689			$GLOBALS['LANG']->loadSingleTableDescription($table);
 690		}
 691
 692		$out = '';
 693		$types_fieldConfig = t3lib_BEfunc::getTCAtypes($table, $row, 1);
 694
 695		$editFieldList = array_unique(t3lib_div::trimExplode(',', $list, 1));
 696		foreach ($editFieldList as $theFieldC) {
 697			list($theField, $palFields) = preg_split('/\[|\]/', $theFieldC);
 698			$theField = trim($theField);
 699			$palFields = trim($palFields);
 700			if ($TCA[$table]['columns'][$theField]) {
 701				$parts = t3lib_div::trimExplode(';', $types_fieldConfig[$theField]['origString']);
 702				$sField = $this->getSingleField($table, $theField, $row, $parts[1], 0, $parts[3], 0); // Don't sent palette pointer - there are no options anyways for a field-list.
 703				$out .= $sField;
 704			} elseif ($theField == '--div--') {
 705				$out .= $this->getDivider();
 706			}
 707			if ($palFields) {
 708				$out .= $this->getPaletteFields($table, $row, '', '', implode(',', t3lib_div::trimExplode('|', $palFields, 1)));
 709			}
 710		}
 711
 712		return $out;
 713	}
 714
 715	/**
 716	 * Creates a palette (collection of secondary options).
 717	 *
 718	 * @param	string		The table name
 719	 * @param	array		The row array
 720	 * @param	string		The palette number/pointer
 721	 * @param	string		Header string for the palette (used when in-form). If not set, no header item is made.
 722	 * @param	string		Optional alternative list of fields for the palette
 723	 * @param	string		Optional Link text for activating a palette (when palettes does not have another form element to belong to).
 724	 * @return	string		HTML code.
 725	 */
 726	function getPaletteFields($table, $row, $palette, $header = '', $itemList = '', $collapsedHeader = NULL) {
 727		if (!$this->doPrintPalette) {
 728			return '';
 729		}
 730
 731		$out = '';
 732		$parts = $this->loadPaletteElements($table, $row, $palette, $itemList);
 733
 734			// Put palette together if there are fields in it:
 735		if (count($parts)) {
 736
 737			$realFields = 0;
 738
 739			foreach ($parts as $part) {
 740				if ($part['NAME'] !== '--linebreak--') {
 741					$realFields++;
 742				}
 743			}
 744
 745			if ($realFields > 0) {
 746
 747				if ($header) {
 748					$out .= $this->intoTemplate(
 749						array('HEADER' => htmlspecialchars($header)),
 750						$this->palFieldTemplateHeader
 751					);
 752				}
 753
 754				$collapsed = $this->isPalettesCollapsed($table, $palette);
 755
 756				$thePalIcon = '';
 757				if ($collapsed && $collapsedHeader !== NULL) {
 758					list($thePalIcon,) = $this->wrapOpenPalette(
 759						t3lib_iconWorks::getSpriteIcon(
 760							'actions-system-options-view',
 761							array('title' => htmlspecialchars($this->getLL('l_moreOptions')))
 762						), $table, $row, $palette, 1);
 763					$thePalIcon = '<span style="margin-left: 20px;">' . $thePalIcon . $collapsedHeader . '</span>';
 764				}
 765
 766				$paletteHtml = $this->wrapPaletteField($this->printPalette($parts), $table, $row, $palette, $collapsed);
 767
 768				$out .= $this->intoTemplate(
 769					array('PALETTE' => $thePalIcon . $paletteHtml),
 770					$this->palFieldTemplate
 771				);
 772			}
 773		}
 774		return $out;
 775	}
 776
 777	/**
 778	 * Returns the form HTML code for a database table field.
 779	 *
 780	 * @param	string		The table name
 781	 * @param	string		The field name
 782	 * @param	array		The record to edit from the database table.
 783	 * @param	string		Alternative field name label to show.
 784	 * @param	boolean		Set this if the field is on a palette (in top frame), otherwise not. (if set, field will render as a hidden field).
 785	 * @param	string		The "extra" options from "Part 4" of the field configurations found in the "types" "showitem" list. Typically parsed by $this->getSpecConfFromString() in order to get the options as an associative array.
 786	 * @param	integer		The palette pointer.
 787	 * @return	mixed		String (normal) or array (palettes)
 788	 */
 789	function getSingleField($table, $field, $row, $altName = '', $palette = 0, $extra = '', $pal = 0) {
 790		global $TCA, $BE_USER;
 791
 792			// Hook: getSingleField_preProcess
 793		foreach ($this->hookObjectsSingleField as $hookObj) {
 794			if (method_exists($hookObj, 'getSingleField_preProcess')) {
 795				$hookObj->getSingleField_preProcess($table, $field, $row, $altName, $palette, $extra, $pal, $this);
 796			}
 797		}
 798
 799		$out = '';
 800		$PA = array();
 801		$PA['altName'] = $altName;
 802		$PA['palette'] = $palette;
 803		$PA['extra'] = $extra;
 804		$PA['pal'] = $pal;
 805
 806			// Make sure to load full $TCA array for the table:
 807		t3lib_div::loadTCA($table);
 808
 809			// Get the TCA configuration for the current field:
 810		$PA['fieldConf'] = $TCA[$table]['columns'][$field];
 811		$PA['fieldConf']['config']['form_type'] = $PA['fieldConf']['config']['form_type'] ? $PA['fieldConf']['config']['form_type'] : $PA['fieldConf']['config']['type']; // Using "form_type" locally in this script
 812
 813		$skipThisField = $this->inline->skipField($table, $field, $row, $PA['fieldConf']['config']);
 814
 815			// Now, check if this field is configured and editable (according to excludefields + other configuration)
 816		if (is_array($PA['fieldConf']) &&
 817			!$skipThisField &&
 818			(!$PA['fieldConf']['exclude'] || $BE_USER->check('non_exclude_fields', $table . ':' . $field)) &&
 819			$PA['fieldConf']['config']['form_type'] != 'passthrough' &&
 820			($this->RTEenabled || !$PA['fieldConf']['config']['showIfRTE']) &&
 821			(!$PA['fieldConf']['displayCond'] || $this->isDisplayCondition($PA['fieldConf']['displayCond'], $row)) &&
 822			(!$TCA[$table]['ctrl']['languageField'] || $PA['fieldConf']['l10n_display'] || strcmp($PA['fieldConf']['l10n_mode'], 'exclude') || $row[$TCA[$table]['ctrl']['languageField']] <= 0) &&
 823			(!$TCA[$table]['ctrl']['languageField'] || !$this->localizationMode || $this->localizationMode === $PA['fieldConf']['l10n_cat'])
 824		) {
 825
 826
 827				// Fetching the TSconfig for the current table/field. This includes the $row which means that
 828			$PA['fieldTSConfig'] = $this->setTSconfig($table, $row, $field);
 829
 830				// If the field is NOT disabled from TSconfig (which it could have been) then render it
 831			if (!$PA['fieldTSConfig']['disabled']) {
 832					// Override fieldConf by fieldTSconfig:
 833				$PA['fieldConf']['config'] = $this->overrideFieldConf($PA['fieldConf']['config'], $PA['fieldTSConfig']);
 834
 835					// Init variables:
 836				$PA['itemFormElName'] = $this->prependFormFieldNames . '[' . $table . '][' . $row['uid'] . '][' . $field . ']'; // Form field name
 837				$PA['itemFormElName_file'] = $this->prependFormFieldNames_file . '[' . $table . '][' . $row['uid'] . '][' . $field . ']'; // Form field name, in case of file uploads
 838				$PA['itemFormElValue'] = $row[$field]; // The value to show in the form field.
 839				$PA['itemFormElID'] = $this->prependFormFieldNames . '_' . $table . '_' . $row['uid'] . '_' . $field;
 840
 841					// set field to read-only if configured for translated records to show default language content as readonly
 842				if ($PA['fieldConf']['l10n_display'] && t3lib_div::inList($PA['fieldConf']['l10n_display'], 'defaultAsReadonly') && $row[$TCA[$table]['ctrl']['languageField']] > 0) {
 843					$PA['fieldConf']['config']['readOnly'] = true;
 844					$PA['itemFormElValue'] = $this->defaultLanguageData[$table . ':' . $row['uid']][$field];
 845				}
 846
 847					// Create a JavaScript code line which will ask the user to save/update the form due to changing the element. This is used for eg. "type" fields and others configured with "requestUpdate"
 848				if (
 849					($TCA[$table]['ctrl']['type'] && !strcmp($field, $TCA[$table]['ctrl']['type'])) ||
 850					($TCA[$table]['ctrl']['requestUpdate'] && t3lib_div::inList($TCA[$table]['ctrl']['requestUpdate'], $field))) {
 851					if ($GLOBALS['BE_USER']->jsConfirmation(1)) {
 852						$alertMsgOnChange = 'if (confirm(TBE_EDITOR.labels.onChangeAlert) && TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };';
 853					} else {
 854						$alertMsgOnChange = 'if (TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };';
 855					}
 856				} else {
 857					$alertMsgOnChange = '';
 858				}
 859
 860					// Render as a hidden field?
 861				if (in_array($field, $this->hiddenFieldListArr)) {
 862					$this->hiddenFieldAccum[] = '<input type="hidden" name="' . $PA['itemFormElName'] . '" value="' . htmlspecialchars($PA['itemFormElValue']) . '" />';
 863				} else { // Render as a normal field:
 864
 865						// If the field is NOT a palette field, then we might create an icon which links to a palette for the field, if one exists.
 866					if (!$PA['palette']) {
 867						$paletteFields = $this->loadPaletteElements($table, $row, $PA['pal']);
 868						if ($PA['pal'] && $this->isPalettesCollapsed($table, $PA['pal']) && count($paletteFields)) {
 869							list($thePalIcon, $palJSfunc) = $this->wrapOpenPalette(t3lib_iconWorks::getSpriteIcon('actions-system-options-view', array('title' => htmlspecialchars($this->getLL('l_moreOptions')))), $table, $row, $PA['pal'], 1);
 870						} else {
 871							$thePalIcon = '';
 872							$palJSfunc = '';
 873						}
 874					}
 875						// onFocus attribute to add to the field:
 876					$PA['onFocus'] = ($palJSfunc && !$BE_USER->uc['dontShowPalettesOnFocusInAB']) ? ' onfocus="' . htmlspecialchars($palJSfunc) . '"' : '';
 877
 878						// Find item
 879					$item = '';
 880					$PA['label'] = ($PA['altName'] ? $PA['altName'] : $PA['fieldConf']['label']);
 881					$PA['label'] = ($PA['fieldTSConfig']['label'] ? $PA['fieldTSConfig']['label'] : $PA['label']);
 882					$PA['label'] = ($PA['fieldTSConfig']['label.'][$GLOBALS['LANG']->lang] ? $PA['fieldTSConfig']['label.'][$GLOBALS['LANG']->lang] : $PA['label']);
 883					$PA['label'] = $this->sL($PA['label']);
 884						// JavaScript code for event handlers:
 885					$PA['fieldChangeFunc'] = array();
 886					$PA['fieldChangeFunc']['TBE_EDITOR_fieldChanged'] = "TBE_EDITOR.fieldChanged('" . $table . "','" . $row['uid'] . "','" . $field . "','" . $PA['itemFormElName'] . "');";
 887					$PA['fieldChangeFunc']['alert'] = $alertMsgOnChange;
 888						// if this is the child of an inline type and it is the field creating the label
 889					if ($this->inline->isInlineChildAndLabelField($table, $field)) {
 890						$inlineObjectId = implode(
 891							t3lib_TCEforms_inline::Structure_Separator,
 892							array(
 893								 $this->inline->inlineNames['object'],
 894								 $table,
 895								 $row['uid']
 896							)
 897						);
 898						$PA['fieldChangeFunc']['inline'] = "inline.handleChangedField('" . $PA['itemFormElName'] . "','" . $inlineObjectId . "');";
 899					}
 900
 901						// Based on the type of the item, call a render function:
 902					$item = $this->getSingleField_SW($table, $field, $row, $PA);
 903
 904						// Add language + diff
 905					if ($PA['fieldConf']['l10n_display'] && (t3lib_div::inList($PA['fieldConf']['l10n_display'], 'hideDiff') || t3lib_div::inList($PA['fieldConf']['l10n_display'], 'defaultAsReadonly'))) {
 906						$renderLanguageDiff = false;
 907					} else {
 908						$renderLanguageDiff = true;
 909					}
 910
 911					if ($renderLanguageDiff) {
 912						$item = $this->renderDefaultLanguageContent($table, $field, $row, $item);
 913						$item = $this->renderDefaultLanguageDiff($table, $field, $row, $item);
 914					}
 915
 916						// If the record has been saved and the "linkTitleToSelf" is set, we make the field name into a link, which will load ONLY this field in alt_doc.php
 917					$label = t3lib_div::deHSCentities(htmlspecialchars($PA['label']));
 918					if (t3lib_div::testInt($row['uid']) && $PA['fieldTSConfig']['linkTitleToSelf'] && !t3lib_div::_GP('columnsOnly')) {
 919						$lTTS_url = $this->backPath . 'alt_doc.php?edit[' . $table . '][' . $row['uid'] . ']=edit&columnsOnly=' . $field . '&returnUrl=' . rawurlencode($this->thisReturnUrl());
 920						$label = '<a href="' . htmlspecialchars($lTTS_url) . '">' . $label . '</a>';
 921					}
 922
 923						// wrap the label with help text
 924					$PA['label'] = $label = t3lib_BEfunc::wrapInHelp($table, $field, $label);
 925
 926						// Create output value:
 927					if ($PA['fieldConf']['config']['form_type'] == 'user' && $PA['fieldConf']['config']['noTableWrapping']) {
 928						$out = $item;
 929					} elseif ($PA['palette']) {
 930							// Array:
 931						$out = array(
 932							'NAME' => $label,
 933							'ID' => $row['uid'],
 934							'FIELD' => $field,
 935							'TABLE' => $table,
 936							'ITEM' => $item
 937						);
 938						$out = $this->addUserTemplateMarkers($out, $table, $field, $row, $PA);
 939					} else {
 940							// String:
 941						$out = array(
 942							'NAME' => $label,
 943							'ITEM' => $item,
 944							'TABLE' => $table,
 945							'ID' => $row['uid'],
 946							'PAL_LINK_ICON' => $thePalIcon,
 947							'FIELD' => $field
 948						);
 949						$out = $this->addUserTemplateMarkers($out, $table, $field, $row, $PA);
 950							// String:
 951						$out = $this->intoTemplate($out);
 952					}
 953				}
 954			} else {
 955				$this->commentMessages[] = $this->prependFormFieldNames . '[' . $table . '][' . $row['uid'] . '][' . $field . ']: Disabled by TSconfig';
 956			}
 957		}
 958			// Hook: getSingleField_postProcess
 959		foreach ($this->hookObjectsSingleField as $hookObj) {
 960			if (method_exists($hookObj, 'getSingleField_postProcess')) {
 961				$hookObj->getSingleField_postProcess($table, $field, $row, $out, $PA, $this);
 962			}
 963		}
 964			// Return value (string or array)
 965		return $out;
 966	}
 967
 968	/**
 969	 * Rendering a single item for the form
 970	 *
 971	 * @param	string		Table name of record
 972	 * @param	string		Fieldname to render
 973	 * @param	array		The record
 974	 * @param	array		parameters array containing a lot of stuff. Value by Reference!
 975	 * @return	string		Returns the item as HTML code to insert
 976	 * @access private
 977	 * @see getSingleField(), getSingleField_typeFlex_draw()
 978	 */
 979	function getSingleField_SW($table, $field, $row, &$PA) {
 980		$PA['fieldConf']['config']['form_type'] = $PA['fieldConf']['config']['form_type'] ? $PA['fieldConf']['config']['form_type'] : $PA['fieldConf']['config']['type']; // Using "form_type" locally in this script
 981
 982			// Hook: getSingleField_beforeRender
 983		foreach ($this->hookObjectsSingleField as $hookObject) {
 984			if (method_exists($hookObject, 'getSingleField_beforeRender')) {
 985				$hookObject->getSingleField_beforeRender($table, $field, $row, $PA);
 986			}
 987		}
 988
 989		switch ($PA['fieldConf']['config']['form_type']) {
 990			case 'input':
 991				$item = $this->getSingleField_typeInput($table, $field, $row, $PA);
 992			break;
 993			case 'text':
 994				$item = $this->getSingleField_typeText($table, $field, $row, $PA);
 995			break;
 996			case 'check':
 997				$item = $this->getSingleField_typeCheck($table, $field, $row, $PA);
 998			break;
 999			case 'radio':
1000				$item = $this->getSingleField_typeRadio($table, $field, $row, $PA);
1001			break;
1002			case 'select':
1003				$item = $this->getSingleField_typeSelect($table, $field, $row, $PA);
1004			break;
1005			case 'group':
1006				$item = $this->getSingleField_typeGroup($table, $field, $row, $PA);
1007			break;
1008			case 'inline':
1009				$item = $this->inline->getSingleField_typeInline($table, $field, $row, $PA);
1010			break;
1011			case 'none':
1012				$item = $this->getSingleField_typeNone($table, $field, $row, $PA);
1013			break;
1014			case 'user':
1015				$item = $this->getSingleField_typeUser($table, $field, $row, $PA);
1016			break;
1017			case 'flex':
1018				$item = $this->getSingleField_typeFlex($table, $field, $row, $PA);
1019			break;
1020			default:
1021				$item = $this->getSingleField_typeUnknown($table, $field, $row, $PA);
1022			break;
1023		}
1024
1025		return $item;
1026	}
1027
1028
1029	/**********************************************************
1030	 *
1031	 * Rendering of each TCEform field type
1032	 *
1033	 ************************************************************/
1034
1035	/**
1036	 * Generation of TCEform elements of the type "input"
1037	 * This will render a single-line input form field, possibly with various control/validation features
1038	 *
1039	 * @param	string		The table name of the record
1040	 * @param	string		The field name which this element is supposed to edit
1041	 * @param	array		The record data array where the value(s) for the field can be found
1042	 * @param	array		An array with additional configuration options.
1043	 * @return	string		The HTML code for the TCEform field
1044	 */
1045	function getSingleField_typeInput($table, $field, $row, &$PA) {
1046		$config = $PA['fieldConf']['config'];
1047
1048		$specConf = $this->getSpecConfFromString($PA['extra'], $PA['fieldConf']['defaultExtras']);
1049		$size = t3lib_div::intInRange($config['size'] ? $config['size'] : 30, 5, $this->maxInputWidth);
1050		$evalList = t3lib_div::trimExplode(',', $config['eval'], 1);
1051		$classAndStyleAttributes = $this->formWidthAsArray($size);
1052
1053		$fieldAppendix = '';
1054		$cssClasses = array($classAndStyleAttributes['class']);
1055		$cssStyle = $classAndStyleAttributes['style'];
1056
1057		if (!isset($config['checkbox'])) {
1058			$config['checkbox'] = '0';
1059			$checkboxIsset = FALSE;
1060		} else {
1061			$checkboxIsset = TRUE;
1062		}
1063
1064		if (in_array('date', $evalList) || in_array('datetime', $evalList)) {
1065			if (in_array('datetime', $evalList)) {
1066				$class = 'datetime';
1067			} else {
1068				$class = 'date';
1069			}
1070			$dateRange = '';
1071			if (isset($config['range']['lower'])) {
1072				$dateRange .= ' lower-' . intval($config['range']['lower']);
1073			}
1074			if (isset($config['range']['upper'])) {
1075				$dateRange .= ' upper-' . intval($config['range']['upper']);
1076			}
1077			$inputId = uniqid('tceforms-' . $class . 'field-');
1078			$cssClasses[] = 'tceforms-textfield tceforms-' . $class . 'field' . $dateRange;
1079			$fieldAppendix = t3lib_iconWorks::getSpriteIcon(
1080				'actions-edit-pick-date',
1081				array(
1082					 'style' => 'cursor:pointer;',
1083					 'id' => 'picker-' . $inputId
1084				)
1085			);
1086		} elseif (in_array('timesec', $evalList)) {
1087			$inputId = uniqid('tceforms-timesecfield-');
1088			$cssClasses[] = 'tceforms-textfield tceforms-timesecfield';
1089		} elseif (in_array('year', $evalList)) {
1090			$inputId = uniqid('tceforms-yearfield-');
1091			$cssClasses[] = 'tceforms-textfield tceforms-yearfield';
1092		} elseif (in_array('time', $evalList)) {
1093			$inputId = uniqid('tceforms-timefield-');
1094			$cssClasses[] = 'tceforms-textfield tceforms-timefield';
1095		} elseif (in_array('int', $evalLis…

Large files files are truncated, but you can click here to view the full file