Fixed feature request: TCEforms/IRRE - Allow TSconfig to override TCA field configuration
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_tceforms.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2006 Kasper Skaarhoj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Contains TYPO3 Core Form generator - AKA "TCEforms"
29 *
30 * $Id$
31 * Revised for TYPO3 3.6 August/2003 by Kasper Skaarhoj
32 * XHTML compliant
33 *
34 * @author Kasper Skaarhoj <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 *
86 * SECTION: Display of localized content etc.
87 * 2816: function registerDefaultLanguageData($table,$rec)
88 * 2848: function getLanguageOverlayRawValue($table, $row, $field, $fieldConf)
89 * 2876: function renderDefaultLanguageContent($table,$field,$row,$item)
90 * 2899: function renderDefaultLanguageDiff($table,$field,$row,$item)
91 *
92 * SECTION: Form element helper functions
93 * 2955: function dbFileIcons($fName,$mode,$allowed,$itemArray,$selector='',$params=array(),$onFocus='')
94 * 3108: function getClipboardElements($allowed,$mode)
95 * 3157: function getClickMenu($str,$table,$uid='')
96 * 3178: function renderWizards($itemKinds,$wizConf,$table,$row,$field,&$PA,$itemName,$specConf,$RTE=0)
97 * 3382: function getIcon($icon)
98 * 3409: function optionTagStyle($iconString)
99 * 3425: function extractValuesOnlyFromValueLabelList($itemFormElValue)
100 * 3447: function wrapOpenPalette($header,$table,$row,$palette,$retFunc=0)
101 * 3471: function checkBoxParams($itemName,$thisValue,$c,$iCount,$addFunc='')
102 * 3485: function elName($itemName)
103 * 3496: function noTitle($str,$wrapParts=array())
104 * 3505: function blur()
105 * 3514: function thisReturnUrl()
106 * 3527: function getSingleHiddenField($table,$field,$row)
107 * 3549: function formWidth($size=48,$textarea=0)
108 * 3576: function formWidthText($size=48,$wrap='')
109 * 3592: function formElStyle($type)
110 * 3603: function formElClass($type)
111 * 3614: function formElStyleClassValue($type, $class=FALSE)
112 * 3638: function insertDefStyle($type)
113 * 3657: function getDynTabMenu($parts, $idString)
114 *
115 * SECTION: Item-array manipulation functions (check/select/radio)
116 * 3696: function initItemArray($fieldValue)
117 * 3714: function addItems($items,$iArray)
118 * 3736: function procItems($items,$iArray,$config,$table,$row,$field)
119 * 3760: function addSelectOptionsToItemArray($items,$fieldValue,$TSconfig,$field)
120 * 3980: function addSelectOptionsToItemArray_makeModuleData($value)
121 * 4002: function foreignTable($items,$fieldValue,$TSconfig,$field,$pFFlag=0)
122 *
123 * SECTION: Template functions
124 * 4083: function setNewBEDesign()
125 * 4138: function intoTemplate($inArr,$altTemplate='')
126 * 4162: function addUserTemplateMarkers($marker,$table,$field,$row,&$PA)
127 * 4173: function wrapLabels($str)
128 * 4186: function wrapTotal($c,$rec,$table)
129 * 4199: function replaceTableWrap($arr,$rec,$table)
130 * 4236: function wrapBorder(&$out_array,&$out_pointer)
131 * 4258: function rplColorScheme($inTemplate)
132 * 4278: function getDivider()
133 * 4288: function printPalette($palArr)
134 * 4339: function helpTextIcon($table,$field,$force=0)
135 * 4359: function helpText($table,$field)
136 * 4380: function setColorScheme($scheme)
137 * 4404: function resetSchemes()
138 * 4415: function storeSchemes()
139 * 4427: function restoreSchemes()
140 *
141 * SECTION: JavaScript related functions
142 * 4457: function JStop()
143 * 4508: function JSbottom($formname='forms[0]')
144 * 4835: function dbFileCon($formObj='document.forms[0]')
145 * 5053: function printNeededJSFunctions()
146 * 5080: function printNeededJSFunctions_top()
147 *
148 * SECTION: Various helper functions
149 * 5128: function getDefaultRecord($table,$pid=0)
150 * 5167: function getRecordPath($table,$rec)
151 * 5181: function readPerms()
152 * 5195: function sL($str)
153 * 5208: function getLL($str)
154 * 5229: function isPalettesCollapsed($table,$palette)
155 * 5245: function isDisplayCondition($displayCond,$row,$ffValueKey='')
156 * 5349: function getTSCpid($table,$uid,$pid)
157 * 5363: function doLoadTableDescr($table)
158 * 5375: function getAvailableLanguages($onlyIsoCoded=1,$setDefault=1)
159 *
160 *
161 * 5417: class t3lib_TCEforms_FE extends t3lib_TCEforms
162 * 5425: function wrapLabels($str)
163 * 5435: function printPalette($palArr)
164 * 5460: function setFancyDesign()
165 *
166 * TOTAL FUNCTIONS: 100
167 * (This index is automatically created/updated by the extension "extdeveval")
168 *
169 */
170
171
172
173
174
175
176
177
178
179
180
181
182
183 require_once(PATH_t3lib.'class.t3lib_diff.php');
184 require_once(PATH_t3lib.'class.t3lib_tceforms_inline.php');
185
186
187
188 /**
189 * 'TCEforms' - Class for creating the backend editing forms.
190 *
191 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
192 * @coauthor Rene Fritz <r.fritz@colorcube.de>
193 * @package TYPO3
194 * @subpackage t3lib
195 */
196 class t3lib_TCEforms {
197
198 // variables not commented yet.... (do so...)
199 var $palFieldArr = array();
200 var $disableWizards = 0;
201 var $isPalettedoc = 0;
202 var $paletteMargin = 1;
203 var $defStyle = ''; // 'font-family:Verdana;font-size:10px;';
204 var $cachedTSconfig = array();
205 var $cachedTSconfig_fieldLevel = array();
206 var $cachedLanguageFlag = array();
207 var $cachedAdditionalPreviewLanguages = NULL;
208 var $transformedRow = array();
209 var $extJSCODE = '';
210 var $printNeededJS = array();
211 var $hiddenFieldAccum=array();
212 var $TBE_EDITOR_fieldChanged_func='';
213 var $loadMD5_JS=1;
214 var $prevBorderStyle='[nothing here...]'; // Something unique...
215 var $allowUpload=0; // If set direct upload fields will be shown
216 var $titleLen=15; // @deprecated: $BE_USER->uc['titleLen'] but what is default??
217 var $defaultLanguageData = array(); // Array where records in the default language is stored. (processed by transferdata)
218 var $defaultLanguageData_diff = array(); // Array where records in the default language is stored (raw without any processing. used for making diff)
219 var $additionalPreviewLanguageData = array();
220
221
222 // EXTERNAL, static
223 var $backPath=''; // Set this to the 'backPath' pointing back to the typo3 admin directory from the script where this form is displayed.
224 var $returnUrl=''; // Alternative return URL path (default is t3lib_div::linkThisScript())
225 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.
226 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.
227 var $disableRTE=0; // If set, the RTE is disabled (from form display, eg. by checkbox in the bottom of the page!)
228 var $globalShowHelp=1; // If false, then all CSH will be disabled, regardless of settings in $this->edit_showFieldHelp
229 var $localizationMode=''; // If true, the forms are rendering only localization relevant fields of the records.
230 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.
231 var $doPrintPalette=1; // If set to false, palettes will NEVER be rendered.
232 var $clipObj=FALSE; // Set to initialized clipboard object; Then the element browser will offer a link to paste in records from clipboard.
233 var $enableClickMenu=FALSE; // Enable click menu on reference icons.
234 var $enableTabMenu = FALSE; // Enable Tab Menus. If set to true, the JavaScript content from template::getDynTabMenuJScode() must be included in the document.
235 var $renderReadonly = FALSE; // When enabled all fields are rendered non-editable.
236
237 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)
238 var $form_largeComp = 1.33; // Form field width compensation: Compensation for large documents, doc-tab (editing)
239 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.
240 var $maxTextareaWidth=48; // The maximum abstract value for textareas
241 var $maxInputWidth=48; // The maximum abstract value for input fields
242 var $defaultMultipleSelectorStyle='width:250px;'; // Default style for the selector boxes used for multiple items in "select" and "group" types.
243
244
245 // INTERNAL, static
246 var $prependFormFieldNames = 'data'; // The string to prepend formfield names with.
247 var $prependCmdFieldNames = 'cmd'; // The string to prepend commands for tcemain::process_cmdmap with.
248 var $prependFormFieldNames_file = 'data_files'; // The string to prepend FILE form field names with.
249 var $formName = 'editform'; // The name attribute of the form.
250 var $allowOverrideMatrix = array(); // Whitelist that allows TCA field configuration to be overridden by TSconfig, @see overrideFieldConf()
251
252
253
254 // INTERNAL, dynamic
255 var $perms_clause=''; // Set by readPerms() (caching)
256 var $perms_clause_set=0; // Set by readPerms() (caching-flag)
257 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).
258 var $docLarge=0; // If set, the forms will be rendered a little wider, more precisely with a factor of $this->form_largeComp.
259 var $clientInfo=array(); // Loaded with info about the browser when class is instantiated.
260 var $RTEenabled=0; // True, if RTE is possible for the current user (based on result from BE_USER->isRTE())
261 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)
262 var $RTEcounter = 0; // Counter that is incremented before an RTE is created. Can be used for unique ids etc.
263
264 var $colorScheme; // Contains current color scheme
265 var $classScheme; // Contains current class scheme
266 var $defColorScheme; // Contains the default color scheme
267 var $defClassScheme; // Contains the default class scheme
268 var $fieldStyle; // Contains field style values
269 var $borderStyle; // Contains border style values.
270
271 var $commentMessages=array(); // An accumulation of messages from the class.
272
273 // INTERNAL, templates
274 var $totalWrap='<hr />|<hr />'; // Total wrapping for the table rows.
275 var $fieldTemplate='<b>###FIELD_NAME###</b><br />###FIELD_ITEM###<hr />'; // Field template
276 var $sectionWrap=''; // Wrapping template code for a section
277 var $palFieldTemplateHeader=''; // Template for palette headers
278 var $palFieldTemplate=''; // Template for palettes
279
280 // INTERNAL, working memory
281 var $excludeElements=''; // Set to the fields NOT to display, if any.
282 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)
283 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!
284 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.
285 var $requiredElements=array(); // Used to register the min and max number of elements for selectorboxes where that apply (in the "group" type for instance)
286 var $renderDepth=0; // Keeps track of the rendering depth of nested records.
287 var $savedSchemes=array(); // Color scheme buffer.
288 var $dynTabLevelStack = array(); // holds tab dividers which were cascaded, required for RTE&IRRE
289
290 // Internal, registers for user defined functions etc.
291 var $additionalCode_pre = array(); // Additional HTML code, printed before the form.
292 var $additionalJS_pre = array(); // Additional JavaScript, printed before the form
293 var $additionalJS_post = array(); // Additional JavaScript printed after the form
294 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.
295
296 var $inline; // Instance of t3lib_tceforms_inline
297
298
299
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;
309
310 $this->clientInfo = t3lib_div::clientInfo();
311
312 $this->RTEenabled = $GLOBALS['BE_USER']->isRTE();
313 if (!$this->RTEenabled) {
314 $this->RTEenabled_notReasons = implode(chr(10),$GLOBALS['BE_USER']->RTE_errors);
315 $this->commentMessages[] = 'RTE NOT ENABLED IN SYSTEM due to:'.chr(10).$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 'select' => array('minitems', 'maxitems', 'size'),
338 'group' => array('minitems', 'maxitems', 'size'),
339 'inline' => array('minitems', 'maxitems', 'size', 'foreign_selector', 'foreign_unique', 'appearance'),
340 );
341
342 $this->inline = t3lib_div::makeInstance('t3lib_TCEforms_inline');
343 }
344
345 /**
346 * Initialize various internal variables.
347 *
348 * @return void
349 */
350 function initDefaultBEmode() {
351 global $BE_USER;
352 $this->prependFormFieldNames = 'data';
353 $this->formName = 'editform';
354 $this->setNewBEDesign();
355 $this->docLarge = $BE_USER->uc['edit_wideDocument'] ? 1 : 0;
356 $this->edit_showFieldHelp = $BE_USER->uc['edit_showFieldHelp'];
357
358 $this->edit_docModuleUpload = $BE_USER->uc['edit_docModuleUpload'];
359 $this->titleLen = $BE_USER->uc['titleLen']; // @deprecated
360
361 $this->inline->init($this);
362 }
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380 /*******************************************************
381 *
382 * Rendering the forms, fields etc
383 *
384 *******************************************************/
385
386 /**
387 * Will return the TCEform element for just a single field from a record.
388 * The field must be listed in the currently displayed fields (as found in [types][showitem]) for the record.
389 * This also means that the $table/$row supplied must be complete so the list of fields to show can be found correctly
390 *
391 * @param string The table name
392 * @param array The record from the table for which to render a field.
393 * @param string The field name to return the TCEform element for.
394 * @return string HTML output
395 * @see getMainFields()
396 */
397 function getSoloField($table,$row,$theFieldToReturn) {
398 global $TCA;
399
400 if ($TCA[$table]) {
401 t3lib_div::loadTCA($table);
402 $typeNum = $this->getRTypeNum($table,$row);
403 if ($TCA[$table]['types'][$typeNum]) {
404 $itemList = $TCA[$table]['types'][$typeNum]['showitem'];
405 if ($itemList) {
406 $fields = t3lib_div::trimExplode(',',$itemList,1);
407 $excludeElements = $this->excludeElements = $this->getExcludeElements($table,$row,$typeNum);
408
409 reset($fields);
410 while(list(,$fieldInfo)=each($fields)) {
411 $parts = explode(';',$fieldInfo);
412
413 $theField = trim($parts[0]);
414 if (!in_array($theField,$excludeElements) && !strcmp($theField,$theFieldToReturn)) {
415 if ($TCA[$table]['columns'][$theField]) {
416 $sField = $this->getSingleField($table,$theField,$row,$parts[1],1,$parts[3],$parts[2]);
417 return $sField['ITEM'];
418 }
419 }
420 }
421 }
422 }
423 }
424 }
425
426 /**
427 * Based on the $table and $row of content, this displays the complete TCEform for the record.
428 * 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.
429 *
430 * @param string The table name
431 * @param array The record from the table for which to render a field.
432 * @param integer Depth level
433 * @return string HTML output
434 * @see getSoloField()
435 */
436 function getMainFields($table,$row,$depth=0) {
437 global $TCA, $TYPO3_CONF_VARS;
438
439 $this->renderDepth=$depth;
440
441 // Init vars:
442 $out_array = array(array());
443 $out_array_meta = array(array(
444 'title' => $this->getLL('l_generalTab')
445 ));
446
447 $out_pointer=0;
448 $out_sheet=0;
449 $this->palettesRendered=array();
450 $this->palettesRendered[$this->renderDepth][$table]=array();
451
452 // First prepare user defined objects (if any) for hooks which extend this function:
453 $hookObjectsArr = array();
454 if (is_array ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['getMainFieldsClass'])) {
455 foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['getMainFieldsClass'] as $classRef) {
456 $hookObjectsArr[] = &t3lib_div::getUserObj($classRef);
457 }
458 }
459
460 // Hook: getMainFields_preProcess (requested by Thomas Hempel for use with the "dynaflex" extension)
461 foreach ($hookObjectsArr as $hookObj) {
462 if (method_exists($hookObj,'getMainFields_preProcess')) {
463 $hookObj->getMainFields_preProcess($table,$row,$this);
464 }
465 }
466
467 if ($TCA[$table]) {
468
469 // Load the full TCA for the table.
470 t3lib_div::loadTCA($table);
471
472 // Load the description content for the table.
473 if ($this->edit_showFieldHelp || $this->doLoadTableDescr($table)) {
474 $GLOBALS['LANG']->loadSingleTableDescription($table);
475 }
476 // Get the current "type" value for the record.
477 $typeNum = $this->getRTypeNum($table,$row);
478
479 // Find the list of fields to display:
480 if ($TCA[$table]['types'][$typeNum]) {
481 $itemList = $TCA[$table]['types'][$typeNum]['showitem'];
482 if ($itemList) { // If such a list existed...
483 // if TCEforms will render a tab menu in the next step, push the name to the tab stack
484 if (strstr($itemList, '--div--') !== false && $this->enableTabMenu && $TCA[$table]['ctrl']['dividers2tabs']) {
485 $tabIdentString = 'TCEforms:'.$table.':'.$row['uid'];
486 $tabIdentStringMD5 = $GLOBALS['TBE_TEMPLATE']->getDynTabMenuId('TCEforms:'.$table.':'.$row['uid']);
487 $this->dynTabLevelStack[$tabIdentStringMD5] = 1;
488 }
489
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 // Traverse the fields to render:
501 $cc=0;
502 foreach($fields as $fieldInfo) {
503 // Exploding subparts of the field configuration:
504 $parts = explode(';',$fieldInfo);
505
506 // Getting the style information out:
507 $color_style_parts = t3lib_div::trimExplode('-',$parts[4]);
508 if (strcmp($color_style_parts[0],'')) {
509 $this->setColorScheme($GLOBALS['TBE_STYLES']['colorschemes'][intval($color_style_parts[0])]);
510 }
511 if (strcmp($color_style_parts[1],'')) {
512 $this->fieldStyle = $GLOBALS['TBE_STYLES']['styleschemes'][intval($color_style_parts[1])];
513 if (!isset($this->fieldStyle)) $this->fieldStyle = $GLOBALS['TBE_STYLES']['styleschemes'][0];
514 }
515 if (strcmp($color_style_parts[2],'')) {
516 $this->wrapBorder($out_array[$out_sheet],$out_pointer);
517 $this->borderStyle = $GLOBALS['TBE_STYLES']['borderschemes'][intval($color_style_parts[2])];
518 if (!isset($this->borderStyle)) $this->borderStyle = $GLOBALS['TBE_STYLES']['borderschemes'][0];
519 }
520
521 // Render the field:
522 $theField = $parts[0];
523 if (!in_array($theField,$excludeElements)) {
524 if ($TCA[$table]['columns'][$theField]) {
525 $sFieldPal='';
526
527 if ($parts[2] && !isset($this->palettesRendered[$this->renderDepth][$table][$parts[2]])) {
528 $sFieldPal=$this->getPaletteFields($table,$row,$parts[2]);
529 $this->palettesRendered[$this->renderDepth][$table][$parts[2]] = 1;
530 }
531 $sField = $this->getSingleField($table,$theField,$row,$parts[1],0,$parts[3],$parts[2]);
532 if ($sField) { $sField.= $sFieldPal; }
533
534 $out_array[$out_sheet][$out_pointer].= $sField;
535 } elseif ($theField=='--div--') {
536 if ($cc>0) {
537 $out_array[$out_sheet][$out_pointer].=$this->getDivider();
538
539 if ($this->enableTabMenu && $TCA[$table]['ctrl']['dividers2tabs']) {
540 $this->wrapBorder($out_array[$out_sheet],$out_pointer);
541 $out_sheet++;
542 // remember what sheet we're currently in
543 $this->dynTabLevelStack[$tabIdentStringMD5] = $out_sheet+1;
544 $out_array[$out_sheet] = array();
545 $out_array_meta[$out_sheet]['title'] = $this->sL($parts[1]);
546 }
547 } else { // Setting alternative title for "General" tab if "--div--" is the very first element.
548 $out_array_meta[$out_sheet]['title'] = $this->sL($parts[1]);
549 }
550 } elseif($theField=='--palette--') {
551 if ($parts[2] && !isset($this->palettesRendered[$this->renderDepth][$table][$parts[2]])) {
552 // render a 'header' if not collapsed
553 if ($TCA[$table]['palettes'][$parts[2]]['canNotCollapse'] AND $parts[1]) {
554 $out_array[$out_sheet][$out_pointer].=$this->getPaletteFields($table,$row,$parts[2],$this->sL($parts[1]));
555 } else {
556 $out_array[$out_sheet][$out_pointer].=$this->getPaletteFields($table,$row,$parts[2],'','',$this->sL($parts[1]));
557 }
558 $this->palettesRendered[$this->renderDepth][$table][$parts[2]] = 1;
559 }
560 }
561 }
562
563 $cc++;
564 }
565 }
566 }
567 }
568
569 // Hook: getMainFields_postProcess (requested by Thomas Hempel for use with the "dynaflex" extension)
570 foreach ($hookObjectsArr as $hookObj) {
571 if (method_exists($hookObj,'getMainFields_postProcess')) {
572 $hookObj->getMainFields_postProcess($table,$row,$this);
573 }
574 }
575
576 // Wrapping a border around it all:
577 $this->wrapBorder($out_array[$out_sheet],$out_pointer);
578
579 // Resetting styles:
580 $this->resetSchemes();
581
582 // Rendering Main palettes, if any
583 $mParr = t3lib_div::trimExplode(',',$TCA[$table]['ctrl']['mainpalette']);
584 $i = 0;
585 if (count($mParr)) {
586 foreach ($mParr as $mP) {
587 if (!isset($this->palettesRendered[$this->renderDepth][$table][$mP])) {
588 $temp_palettesCollapsed=$this->palettesCollapsed;
589 $this->palettesCollapsed=0;
590 $label = ($i==0?$this->getLL('l_generalOptions'):$this->getLL('l_generalOptions_more'));
591 $out_array[$out_sheet][$out_pointer].=$this->getPaletteFields($table,$row,$mP,$label);
592 $this->palettesCollapsed=$temp_palettesCollapsed;
593 $this->palettesRendered[$this->renderDepth][$table][$mP] = 1;
594 }
595 $this->wrapBorder($out_array[$out_sheet],$out_pointer);
596 $i++;
597 if ($this->renderDepth) {
598 $this->renderDepth--;
599 }
600 }
601 }
602
603 // Return the imploded $out_array:
604 if ($out_sheet>0) { // There were --div-- dividers around...
605
606 // Create parts array for the tab menu:
607 $parts = array();
608 foreach ($out_array as $idx => $sheetContent) {
609 $parts[] = array(
610 'label' => $out_array_meta[$idx]['title'],
611 'content' => '<table border="0" cellspacing="0" cellpadding="0" width="100%">'.
612 implode('',$sheetContent).
613 '</table>'
614 );
615 }
616
617 // unset the current level of tab menus
618 unset($this->dynTabLevelStack[$tabIdentStringMD5]);
619
620 return '
621 <tr>
622 <td colspan="2">
623 '.$this->getDynTabMenu($parts, $tabIdentString).'
624 </td>
625 </tr>';
626 } else { // Only one, so just implode:
627 return implode('',$out_array[$out_sheet]);
628 }
629 }
630
631 /**
632 * Will return the TCEform elements for a pre-defined list of fields.
633 * 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.
634 * Used for displaying forms for the frontend edit icons for instance.
635 *
636 * @param string The table name
637 * @param array The record array.
638 * @param string Commalist of fields from the table. These will be shown in the specified order in a form.
639 * @return string TCEform elements in a string.
640 */
641 function getListedFields($table,$row,$list) {
642 global $TCA;
643
644 t3lib_div::loadTCA($table);
645 if ($this->edit_showFieldHelp || $this->doLoadTableDescr($table)) {
646 $GLOBALS['LANG']->loadSingleTableDescription($table);
647 }
648
649 $out = '';
650 $types_fieldConfig = t3lib_BEfunc::getTCAtypes($table,$row,1);
651
652 $editFieldList=array_unique(t3lib_div::trimExplode(',',$list,1));
653 foreach($editFieldList as $theFieldC) {
654 list($theField,$palFields) = split('\[|\]',$theFieldC);
655 $theField = trim($theField);
656 $palFields = trim($palFields);
657 if ($TCA[$table]['columns'][$theField]) {
658 $parts = t3lib_div::trimExplode(';',$types_fieldConfig[$theField]['origString']);
659 $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.
660 $out.= $sField;
661 } elseif($theField=='--div--') {
662 $out.= $this->getDivider();
663 }
664 if ($palFields) {
665 $out.= $this->getPaletteFields($table,$row,'','',implode(',',t3lib_div::trimExplode('|',$palFields,1)));
666 }
667 }
668
669 return $out;
670 }
671
672 /**
673 * Creates a palette (collection of secondary options).
674 *
675 * @param string The table name
676 * @param array The row array
677 * @param string The palette number/pointer
678 * @param string Header string for the palette (used when in-form). If not set, no header item is made.
679 * @param string Optional alternative list of fields for the palette
680 * @param string Optional Link text for activating a palette (when palettes does not have another form element to belong to).
681 * @return string HTML code.
682 */
683 function getPaletteFields($table,$row,$palette,$header='',$itemList='',$collapsedHeader='') {
684 global $TCA;
685 if (!$this->doPrintPalette) return '';
686
687 $out='';
688 $palParts = array();
689 t3lib_div::loadTCA($table);
690
691 // Getting excludeElements, if any.
692 if (!is_array($this->excludeElements)) {
693 $this->excludeElements = $this->getExcludeElements($table,$row,$this->getRTypeNum($table,$row));
694 }
695
696 // Render the palette TCEform elements.
697 if ($TCA[$table] && (is_array($TCA[$table]['palettes'][$palette]) || $itemList)) {
698 $itemList = $itemList?$itemList:$TCA[$table]['palettes'][$palette]['showitem'];
699 if ($itemList) {
700 $fields = t3lib_div::trimExplode(',',$itemList,1);
701 reset($fields);
702 while(list(,$fieldInfo)=each($fields)) {
703 $parts = t3lib_div::trimExplode(';',$fieldInfo);
704 $theField = $parts[0];
705
706 if (!in_array($theField,$this->excludeElements) && $TCA[$table]['columns'][$theField]) {
707 $this->palFieldArr[$palette][] = $theField;
708 if ($this->isPalettesCollapsed($table,$palette)) {
709 $this->hiddenFieldListArr[] = $theField;
710 }
711
712 $part = $this->getSingleField($table,$theField,$row,$parts[1],1,'',$parts[2]);
713 if (is_array($part)) {
714 $palParts[] = $part;
715 }
716 }
717 }
718 }
719 }
720 // Put palette together if there are fields in it:
721 if (count($palParts)) {
722 if ($header) {
723 $out.= $this->intoTemplate(array(
724 'HEADER' => htmlspecialchars($header)
725 ),
726 $this->palFieldTemplateHeader
727 );
728 }
729 $out.= $this->intoTemplate(array(
730 'PALETTE' => $this->printPalette($palParts)
731 ),
732 $this->palFieldTemplate
733 );
734 }
735 // If a palette is collapsed (not shown in form, but in top frame instead) AND a collapse header string is given, then make that string a link to activate the palette.
736 if ($this->isPalettesCollapsed($table,$palette) && $collapsedHeader) {
737 $pC = $this->intoTemplate(array(
738 'PALETTE' => $this->wrapOpenPalette('<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/options.gif','width="18" height="16"').' border="0" title="'.htmlspecialchars($this->getLL('l_moreOptions')).'" align="top" alt="" /><strong>'.$collapsedHeader.'</strong>',$table,$row,$palette),
739 ),
740 $this->palFieldTemplate
741 );
742 $out.= $pC;
743 }
744
745 return $out;
746 }
747
748 /**
749 * Returns the form HTML code for a database table field.
750 *
751 * @param string The table name
752 * @param string The field name
753 * @param array The record to edit from the database table.
754 * @param string Alternative field name label to show.
755 * @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).
756 * @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.
757 * @param integer The palette pointer.
758 * @return mixed String (normal) or array (palettes)
759 */
760 function getSingleField($table,$field,$row,$altName='',$palette=0,$extra='',$pal=0) {
761 global $TCA,$BE_USER;
762
763 $out = '';
764 $PA = array();
765 $PA['altName'] = $altName;
766 $PA['palette'] = $palette;
767 $PA['extra'] = $extra;
768 $PA['pal'] = $pal;
769
770 // Make sure to load full $TCA array for the table:
771 t3lib_div::loadTCA($table);
772
773 // Get the TCA configuration for the current field:
774 $PA['fieldConf'] = $TCA[$table]['columns'][$field];
775 $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
776
777 $skipThisField = $this->inline->skipField($table, $field, $row, $PA['fieldConf']['config']);
778
779 // Now, check if this field is configured and editable (according to excludefields + other configuration)
780 if ( is_array($PA['fieldConf']) &&
781 !$skipThisField &&
782 (!$PA['fieldConf']['exclude'] || $BE_USER->check('non_exclude_fields',$table.':'.$field)) &&
783 $PA['fieldConf']['config']['form_type']!='passthrough' &&
784 ($this->RTEenabled || !$PA['fieldConf']['config']['showIfRTE']) &&
785 (!$PA['fieldConf']['displayCond'] || $this->isDisplayCondition($PA['fieldConf']['displayCond'],$row)) &&
786 (!$TCA[$table]['ctrl']['languageField'] || $PA['fieldConf']['l10n_display'] || strcmp($PA['fieldConf']['l10n_mode'],'exclude') || $row[$TCA[$table]['ctrl']['languageField']]<=0) &&
787 (!$TCA[$table]['ctrl']['languageField'] || !$this->localizationMode || $this->localizationMode===$PA['fieldConf']['l10n_cat'])
788 ) {
789
790
791
792 // Fetching the TSconfig for the current table/field. This includes the $row which means that
793 $PA['fieldTSConfig'] = $this->setTSconfig($table,$row,$field);
794
795 // If the field is NOT disabled from TSconfig (which it could have been) then render it
796 if (!$PA['fieldTSConfig']['disabled']) {
797 // Override fieldConf by fieldTSconfig:
798 $PA['fieldConf']['config'] = $this->overrideFieldConf($PA['fieldConf']['config'], $PA['fieldTSConfig']);
799
800 // Init variables:
801 $PA['itemFormElName']=$this->prependFormFieldNames.'['.$table.']['.$row['uid'].']['.$field.']'; // Form field name
802 $PA['itemFormElName_file']=$this->prependFormFieldNames_file.'['.$table.']['.$row['uid'].']['.$field.']'; // Form field name, in case of file uploads
803 $PA['itemFormElValue']=$row[$field]; // The value to show in the form field.
804 $PA['itemFormElID']=$this->prependFormFieldNames.'_'.$table.'_'.$row['uid'].'_'.$field;
805
806 // set field to read-only if configured for translated records to show default language content as readonly
807 if ($PA['fieldConf']['l10n_display'] AND t3lib_div::inList($PA['fieldConf']['l10n_display'], 'defaultAsReadonly') AND $row[$TCA[$table]['ctrl']['languageField']]) {
808 $PA['fieldConf']['config']['readOnly'] = true;
809 $PA['itemFormElValue'] = $this->defaultLanguageData[$table.':'.$row['uid']][$field];
810 }
811
812 // 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"
813 if (
814 ($TCA[$table]['ctrl']['type'] && !strcmp($field,$TCA[$table]['ctrl']['type'])) ||
815 ($TCA[$table]['ctrl']['requestUpdate'] && t3lib_div::inList($TCA[$table]['ctrl']['requestUpdate'],$field))) {
816 if($GLOBALS['BE_USER']->jsConfirmation(1)) {
817 $alertMsgOnChange = 'if (confirm(TBE_EDITOR.labels.onChangeAlert) && TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };';
818 } else {
819 $alertMsgOnChange = 'if (TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };';
820 }
821 } else {
822 $alertMsgOnChange = '';
823 }
824
825 // Render as a hidden field?
826 if (in_array($field,$this->hiddenFieldListArr)) {
827 $this->hiddenFieldAccum[]='<input type="hidden" name="'.$PA['itemFormElName'].'" value="'.htmlspecialchars($PA['itemFormElValue']).'" />';
828 } else { // Render as a normal field:
829
830 // 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.
831 if (!$PA['palette']) {
832 if ($PA['pal'] && $this->isPalettesCollapsed($table,$PA['pal'])) {
833 list($thePalIcon,$palJSfunc) = $this->wrapOpenPalette('<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/options.gif','width="18" height="16"').' border="0" title="'.htmlspecialchars($this->getLL('l_moreOptions')).'" alt="" />',$table,$row,$PA['pal'],1);
834 } else {
835 $thePalIcon = '';
836 $palJSfunc = '';
837 }
838 }
839 // onFocus attribute to add to the field:
840 $PA['onFocus'] = ($palJSfunc && !$BE_USER->uc['dontShowPalettesOnFocusInAB']) ? ' onfocus="'.htmlspecialchars($palJSfunc).'"' : '';
841
842 // Find item
843 $item='';
844 $PA['label'] = $PA['altName'] ? $PA['altName'] : $PA['fieldConf']['label'];
845 $PA['label'] = $this->sL($PA['label']);
846 // JavaScript code for event handlers:
847 $PA['fieldChangeFunc']=array();
848 $PA['fieldChangeFunc']['TBE_EDITOR_fieldChanged'] = "TBE_EDITOR.fieldChanged('".$table."','".$row['uid']."','".$field."','".$PA['itemFormElName']."');";
849 $PA['fieldChangeFunc']['alert']=$alertMsgOnChange;
850 // if this is the child of an inline type and it is the field creating the label
851 if ($this->inline->isInlineChildAndLabelField($table, $field)) {
852 $PA['fieldChangeFunc']['inline'] = "inline.handleChangedField('".$PA['itemFormElName']."','".$this->inline->inlineNames['object']."[$table][".$row['uid']."]');";
853 }
854
855 // Based on the type of the item, call a render function:
856 $item = $this->getSingleField_SW($table,$field,$row,$PA);
857
858 // Add language + diff
859 if ($PA['fieldConf']['l10n_display'] && (t3lib_div::inList($PA['fieldConf']['l10n_display'], 'hideDiff') || t3lib_div::inList($PA['fieldConf']['l10n_display'], 'defaultAsReadonly'))) {
860 $renderLanguageDiff = false;
861 } else {
862 $renderLanguageDiff = true;
863 }
864
865 if ($renderLanguageDiff) {
866 $item = $this->renderDefaultLanguageContent($table,$field,$row,$item);
867 $item = $this->renderDefaultLanguageDiff($table,$field,$row,$item);
868 }
869
870 // 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
871 $PA['label'] = t3lib_div::deHSCentities(htmlspecialchars($PA['label']));
872 if (t3lib_div::testInt($row['uid']) && $PA['fieldTSConfig']['linkTitleToSelf']) {
873 $lTTS_url = $this->backPath.'alt_doc.php?edit['.$table.']['.$row['uid'].']=edit&columnsOnly='.$field.
874 ($PA['fieldTSConfig']['linkTitleToSelf.']['returnUrl']?'&returnUrl='.rawurlencode($this->thisReturnUrl()):'');
875 $PA['label'] = '<a href="'.htmlspecialchars($lTTS_url).'">'.$PA['label'].'</a>';
876 }
877
878 // Create output value:
879 if ($PA['fieldConf']['config']['form_type']=='user' && $PA['fieldConf']['config']['noTableWrapping']) {
880 $out = $item;
881 } elseif ($PA['palette']) {
882 // Array:
883 $out=array(
884 'NAME'=>$PA['label'],
885 'ID'=>$row['uid'],
886 'FIELD'=>$field,
887 'TABLE'=>$table,
888 'ITEM'=>$item,
889 'HELP_ICON' => $this->helpTextIcon($table,$field,1)
890 );
891 $out = $this->addUserTemplateMarkers($out,$table,$field,$row,$PA);
892 } else {
893 // String:
894 $out=array(
895 'NAME'=>$PA['label'],
896 'ITEM'=>$item,
897 'TABLE'=>$table,
898 'ID'=>$row['uid'],
899 'HELP_ICON'=>$this->helpTextIcon($table,$field),
900 'HELP_TEXT'=>$this->helpText($table,$field),
901 'PAL_LINK_ICON'=>$thePalIcon,
902 'FIELD'=>$field
903 );
904 $out = $this->addUserTemplateMarkers($out,$table,$field,$row,$PA);
905 // String:
906 $out=$this->intoTemplate($out);
907 }
908 }
909 } else $this->commentMessages[]=$this->prependFormFieldNames.'['.$table.']['.$row['uid'].']['.$field.']: Disabled by TSconfig';
910 }
911 // Return value (string or array)
912 return $out;
913 }
914
915 /**
916 * Rendering a single item for the form
917 *
918 * @param string Table name of record
919 * @param string Fieldname to render
920 * @param array The record
921 * @param array parameters array containing a lot of stuff. Value by Reference!
922 * @return string Returns the item as HTML code to insert
923 * @access private
924 * @see getSingleField(), getSingleField_typeFlex_draw()
925 */
926 function getSingleField_SW($table,$field,$row,&$PA) {
927 $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
928
929 switch($PA['fieldConf']['config']['form_type']) {
930 case 'input':
931 $item = $this->getSingleField_typeInput($table,$field,$row,$PA);
932 break;
933 case 'text':
934 $item = $this->getSingleField_typeText($table,$field,$row,$PA);
935 break;
936 case 'check':
937 $item = $this->getSingleField_typeCheck($table,$field,$row,$PA);
938 break;
939 case 'radio':
940 $item = $this->getSingleField_typeRadio($table,$field,$row,$PA);
941 break;
942 case 'select':
943 $item = $this->getSingleField_typeSelect($table,$field,$row,$PA);
944 break;
945 case 'group':
946 $item = $this->getSingleField_typeGroup($table,$field,$row,$PA);
947 break;
948 case 'inline':
949 $item = $this->inline->getSingleField_typeInline($table,$field,$row,$PA);
950 break;
951 case 'none':
952 $item = $this->getSingleField_typeNone($table,$field,$row,$PA);
953 break;
954 case 'user':
955 $item = $this->getSingleField_typeUser($table,$field,$row,$PA);
956 break;
957 case 'flex':
958 $item = $this->getSingleField_typeFlex($table,$field,$row,$PA);
959 break;
960 default:
961 $item = $this->getSingleField_typeUnknown($table,$field,$row,$PA);
962 break;
963 }
964
965 return $item;
966 }
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986 /**********************************************************
987 *
988 * Rendering of each TCEform field type
989 *
990 ************************************************************/
991
992 /**
993 * Generation of TCEform elements of the type "input"
994 * This will render a single-line input form field, possibly with various control/validation features
995 *
996 * @param string The table name of the record
997 * @param string The field name which this element is supposed to edit
998 * @param array The record data array where the value(s) for the field can be found
999 * @param array An array with additional configuration options.
1000 * @return string The HTML code for the TCEform field
1001 */
1002 function getSingleField_typeInput($table,$field,$row,&$PA) {
1003 // typo3FormFieldSet(theField, evallist, is_in, checkbox, checkboxValue)
1004 // typo3FormFieldGet(theField, evallist, is_in, checkbox, checkboxValue, checkbox_off)
1005
1006 $config = $PA['fieldConf']['config'];
1007
1008 # $specConf = $this->getSpecConfForField($table,$row,$field);
1009 $specConf = $this->getSpecConfFromString($PA['extra'], $PA['fieldConf']['defaultExtras']);
1010 $size = t3lib_div::intInRange($config['size']?$config['size']:30,5,$this->maxInputWidth);
1011 $evalList = t3lib_div::trimExplode(',',$config['eval'],1);
1012
1013
1014 if($this->renderReadonly || $config['readOnly']) {
1015 $itemFormElValue = $PA['itemFormElValue'];
1016 if (in_array('date',$evalList)) {
1017 $config['format'] = 'date';
1018 } elseif (in_array('date',$evalList)) {
1019 $config['format'] = 'date';
1020 } elseif (in_array('datetime',$evalList)) {
1021 $config['format'] = 'datetime';
1022 } elseif (in_array('time',$evalList)) {
1023 $config['format'] = 'time';
1024 }
1025 if (in_array('password',$evalList)) {
1026 $itemFormElValue = $itemFormElValue ? '*********' : '';
1027 }
1028 return $this->getSingleField_typeNone_render($config, $itemFormElValue);
1029 }
1030
1031 if (in_array('required',$evalList)) {
1032 $this->requiredFields[$table.'_'.$row['uid'].'_'.$field]=$PA['itemFormElName'];
1033 }
1034
1035 $paramsList = "'".$PA['itemFormElName']."','".implode(',',$evalList)."','".trim($config['is_in'])."',".(isset($config['checkbox'])?1:0).",'".$config['checkbox']."'";
1036 if (isset($config['checkbox'])) {
1037 // Setting default "click-checkbox" values for eval types "date" and "datetime":
1038 $thisMidnight = mktime(0,0,0);
1039 $checkSetValue = in_array('date',$evalList) ? $thisMidnight : '';
1040 $checkSetValue = in_array('datetime',$evalList) ? time() : $checkSetValue;
1041
1042 $cOnClick = 'typo3form.fieldGet('.$paramsList.',1,\''.$checkSetValue.'\');'.implode('',$PA['fieldChangeFunc']);
1043 $item.='<input type="checkbox"'.$this->insertDefStyle('check').' name="'.$PA['itemFormElName'].'_cb" onclick="'.htmlspecialchars($cOnClick).'" />';
1044 }
1045
1046 $PA['fieldChangeFunc'] = array_merge(array('typo3form.fieldGet'=>'typo3form.fieldGet('.$paramsList.');'), $PA['fieldChangeFunc']);
1047 $mLgd = ($config['max']?$config['max']:256);
1048 $iOnChange = implode('',$PA['fieldChangeFunc']);
1049 $item.='<input type="text" name="'.$PA['itemFormElName'].'_hr" value=""'.$this->formWidth($size).' maxlength="'.$mLgd.'" onchange="'.htmlspecialchars($iOnChange).'"'.$PA['onFocus'].' />'; // This is the EDITABLE form field.
1050 $item.='<input type="hidden" name="'.$PA['itemFormElName'].'" value="'.htmlspecialchars($PA['itemFormElValue']).'" />'; // This is the ACTUAL form field - values from the EDITABLE field must be transferred to this field which is the one that is written to the database.
1051 $this->extJSCODE.='typo3form.fieldSet('.$paramsList.');';
1052
1053 // going through all custom evaluations configured for this field
1054 foreach ($evalList as $evalData) {
1055 if (substr($evalData, 0, 3) == 'tx_') {
1056 $evalObj = t3lib_div::getUserObj($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tce']['formevals'][$evalData].':&'.$evalData);
1057 if(is_object($evalObj) && method_exists($evalObj, 'returnFieldJS')) {
1058 $this->extJSCODE .= "\n\nfunction ".$evalData."(value) {\n".$evalObj->returnFieldJS()."\n}\n";
1059 }
1060 }
1061 }
1062
1063 // Creating an alternative item without the JavaScript handlers.
1064 $altItem = '<input type="hidden" name="'.$PA['itemFormElName'].'_hr" value="" />';
1065 $altItem.= '<input type="hidden" name="'.$PA['itemFormElName'].'" value="'.htmlspecialchars($PA['itemFormElValue']).'" />';
1066
1067 // Wrap a wizard around the item?
1068 $item= $this->renderWizards(array($item,$altItem),$config['wizards'],$table,$row,$field,$PA,$PA['itemFormElName'].'_hr',$specConf);
1069
1070 return $item;
1071 }
1072
1073 /**
1074 * Generation of TCEform elements of the type "text"
1075 * This will render a <textarea> OR RTE area form field, possibly with various control/validation features
1076 *
1077 * @param string The table name of the record
1078 * @param string The field name which this element is supposed to edit
1079 * @param array The record data array where the value(s) for the field can be found
1080 * @param array An array with additional configuration options.
1081 * @return string The HTML code for the TCEform field
1082 */
1083 function getSingleField_typeText($table,$field,$row,&$PA) {
1084
1085 // Init config:
1086 $config = $PA['fieldConf']['config'];
1087
1088 if($this->renderReadonly || $config['readOnly']) {
1089 return $this->getSingleField_typeNone_render($config, $PA['itemFormElValue']);
1090 }
1091
1092 // Setting columns number:
1093 $cols = t3lib_div::intInRange($config['cols'] ? $config['cols'] : 30, 5, $this->maxTextareaWidth);
1094
1095 // Setting number of rows:
1096 $origRows = $rows = t3lib_div::intInRange($config['rows'] ? $config['rows'] : 5, 1, 20);
1097 if (strlen($PA['itemFormElValue']) > $this->charsPerRow*2) {
1098 $cols = $this->maxTextareaWidth;
1099 $rows = t3lib_div::intInRange(round(strlen($PA['itemFormElValue'])/$this->charsPerRow), count(explode(chr(10),$PA['itemFormElValue'])), 20);
1100 if ($rows<$origRows) $rows = $origRows;
1101 }
1102
1103 // Init RTE vars:
1104 $RTEwasLoaded = 0; // Set true, if the RTE is loaded; If not a normal textarea is shown.
1105 $RTEwouldHaveBeenLoaded = 0; // Set true, if the RTE would have been loaded if it wasn't for the disable-RTE flag in the bottom of the page...
1106
1107 // "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist. Traditionally, this is where RTE configuration has been found.
1108 $specConf = $this->getSpecConfFromString($PA['extra'], $PA['fieldConf']['defaultExtras']);
1109
1110 // Setting up the altItem form field, which is a hidden field containing the value
1111 $altItem = '<input type="hidden" name="'.htmlspecialchars($PA['itemFormElName']).'" value="'.htmlspecialchars($PA['itemFormElValue']).'" />';
1112
1113 // If RTE is generally enabled (TYPO3_CONF_VARS and user settings)
1114 if ($this->RTEenabled) {
1115 $p = t3lib_BEfunc::getSpecConfParametersFromArray($specConf['rte_transform']['parameters']);
1116 if (isset($specConf['richtext']) && (!$p['flag'] || !$row[$p['flag']])) { // If the field is configured for RTE and if any flag-field is not set to disable it.
1117 t3lib_BEfunc::fixVersioningPid($table,$row);
1118 list($tscPID,$thePidValue) = $this->getTSCpid($table,$row['uid'],$row['pid']);
1119
1120 // If the pid-value is not negative (that is, a pid could NOT be fetched)
1121 if ($thePidValue >= 0) {
1122 $RTEsetup = $GLOBALS['BE_USER']->getTSConfig('RTE',t3lib_BEfunc::getPagesTSconfig($tscPID));
1123 $RTEtypeVal = t3lib_BEfunc::getTCAtypeValue($table,$row);
1124 $thisConfig = t3lib_BEfunc::RTEsetup($RTEsetup['properties'],$table,$field,$RTEtypeVal);
1125
1126 if (!$thisConfig['disabled']) {
1127 if (!$this->disableRTE) {
1128 $this->RTEcounter++;
1129
1130 // Find alternative relative path for RTE images/links:
1131 $eFile = t3lib_parsehtml_proc::evalWriteFile($specConf['static_write'], $row);
1132 $RTErelPath = is_array($eFile) ? dirname($eFile['relEditFile']) : '';
1133
1134 // Get RTE object, draw form and set flag:
1135 $RTEobj = &t3lib_BEfunc::RTEgetObj();
1136 $item = $RTEobj->drawRTE($this,$table,$field,$row,$PA,$specConf,$thisConfig,$RTEtypeVal,$RTErelPath,$thePidValue);
1137
1138 // Wizard:
1139 $item = $this->renderWizards(array($item,$altItem),$config['wizards'],$table,$row,$field,$PA,$PA['itemFormElName'],$specConf,1);
1140
1141 $RTEwasLoaded = 1;
1142 } else {
1143 $RTEwouldHaveBeenLoaded = 1;
1144 $this->commentMessages[] = $PA['itemFormElName'].': RTE is disabled by the on-page RTE-flag (probably you can enable it by the check-box in the bottom of this page!)';
1145 }
1146 } else $this->commentMessages[] = $PA['itemFormElName'].': RTE is disabled by the Page TSconfig, "RTE"-key (eg. by RTE.default.disabled=0 or such)';
1147 } else $this->commentMessages[] = $PA['itemFormElName'].': PID value could NOT be fetched. Rare error, normally with new records.';
1148 } else {
1149 if (!isset($specConf['richtext'])) $this->commentMessages[] = $PA['itemFormElName'].': RTE was not configured for this field in TCA-types';
1150 if (!(!$p['flag'] || !$row[$p['flag']])) $this->commentMessages[] = $PA['itemFormElName'].': Field-flag ('.$PA['flag'].') has been set to disable RTE!';
1151 }
1152 }
1153
1154 // Display ordinary field if RTE was not loaded.
1155 if (!$RTEwasLoaded) {
1156 if ($specConf['rte_only']) { // Show message, if no RTE (field can only be edited with RTE!)
1157 $item = '<p><em>'.htmlspecialchars($this->getLL('l_noRTEfound')).'</em></p>';
1158 } else {
1159 if ($specConf['nowrap']) {
1160 $wrap = 'off';
1161 } else {
1162 $wrap = ($config['wrap'] ? $config['wrap'] : 'virtual');
1163 }
1164
1165 $classes = array();
1166 if ($specConf['fixed-font']) { $classes[] = 'fixed-font'; }
1167 if ($specConf['enable-tab']) { $classes[] = 'enable-tab'; }
1168
1169 $formWidthText = $this->formWidthText($cols,$wrap);
1170
1171 // Extract class attributes from $formWidthText (otherwise it would be added twice to the output)
1172 if (preg_match('/ class="(.+?)"/',$formWidthText,$res)) {
1173 $formWidthText = str_replace(' class="'.$res[1].'"','',$formWidthText);
1174 $classes = array_merge($classes, explode(' ',$res[1]));
1175 }
1176
1177 if (count($classes)) {
1178 $class = ' class="'.implode(' ',$classes).'"';
1179 } else $class='';
1180
1181 $iOnChange = implode('',$PA['fieldChangeFunc']);
1182 $item.= '
1183 <textarea name="'.$PA['itemFormElName'].'"'.$formWidthText.$class.' rows="'.$rows.'" wrap="'.$wrap.'" onchange="'.htmlspecialchars($iOnChange).'"'.$PA['onFocus'].'>'.
1184 t3lib_div::formatForTextarea($PA['itemFormElValue']).
1185 '</textarea>';
1186 $item = $this->renderWizards(array($item,$altItem),$config['wizards'],$table,$row,$field,$PA,$PA['itemFormElName'],$specConf,$RTEwouldHaveBeenLoaded);
1187 }
1188 }
1189
1190 // Return field HTML:
1191 return $item;
1192 }
1193
1194 /**
1195 * Generation of TCEform elements of the type "check"
1196 * This will render a check-box OR an array of checkboxes
1197 *
1198 * @param string The table name of the record
1199 * @param string The field name which this element is supposed to edit
1200 * @param array The record data array where the value(s) for the field can be found
1201 * @param array An array with additional configuration options.
1202 * @return string The HTML code for the TCEform field
1203 */
1204 function getSingleField_typeCheck($table,$field,$row,&$PA) {
1205 $config = $PA['fieldConf']['config'];
1206
1207 $disabled = '';
1208 if($this->renderReadonly || $config['readOnly']) {
1209 $disabled = ' disabled="disabled"';
1210 }
1211
1212 // Traversing the array of items:
1213 $selItems = $this->initItemArray($PA['fieldConf']);
1214 if ($config['itemsProcFunc']) $selItems = $this->procItems($selItems,$PA['fieldTSConfig']['itemsProcFunc.'],$config,$table,$row,$field);
1215
1216 if (!count($selItems)) {
1217 $selItems[]=array('','');
1218 }
1219 $thisValue = intval($PA['itemFormElValue']);
1220
1221 $cols = intval($config['cols']);
1222 if ($cols > 1) {
1223 $item.= '<table border="0" cellspacing="0" cellpadding="0" class="typo3-TCEforms-checkboxArray">';
1224 for ($c=0;$c<count($selItems);$c++) {
1225 $p = $selItems[$c];
1226 if(!($c%$cols)) { $item.='<tr>'; }
1227 $cBP = $this->checkBoxParams($PA['itemFormElName'],$thisValue,$c,count($selItems),implode('',$PA['fieldChangeFunc']));
1228 $cBName = $PA['itemFormElName'].'_'.$c;
1229 $cBID = $PA['itemFormElID'].'_'.$c;
1230 $item.= '<td nowrap="nowrap">'.
1231 '<input type="checkbox"'.$this->insertDefStyle('check').' value="1" name="'.$cBName.'"'.$cBP.$disabled.' id="'.$cBID.'" />'.
1232 $this->wrapLabels('<label for="'.$cBID.'">'.htmlspecialchars($p[0]).'</label>&nbsp;').
1233 '</td>';
1234 if(($c%$cols)+1==$cols) {$item.='</tr>';}
1235 }
1236 if ($c%$cols) {
1237 $rest=$cols-($c%$cols);
1238 for ($c=0;$c<$rest;$c++) {
1239 $item.= '<td></td>';
1240 }
1241 if ($c>0) { $item.= '</tr>'; }
1242 }
1243 $item.= '</table>';
1244 } else {
1245 for ($c=0;$c<count($selItems);$c++) {
1246 $p = $selItems[$c];
1247 $cBP = $this->checkBoxParams($PA['itemFormElName'],$thisValue,$c,count($selItems),implode('',$PA['fieldChangeFunc']));
1248 $cBName = $PA['itemFormElName'].'_'.$c;
1249 $cBID = $PA['itemFormElID'].'_'.$c;
1250 $item.= ($c>0?'<br />':'').
1251 '<input type="checkbox"'.$this->insertDefStyle('check').' value="1" name="'.$cBName.'"'.$cBP.$PA['onFocus'].$disabled.' id="'.$cBID.'" />'.
1252 htmlspecialchars($p[0]);
1253 }
1254 }
1255 if (!$disabled) {
1256 $item.= '<input type="hidden" name="'.$PA['itemFormElName'].'" value="'.htmlspecialchars($thisValue).'" />';
1257 }
1258
1259 return $item;
1260 }
1261
1262 /**
1263 * Generation of TCEform elements of the type "radio"
1264 * This will render a series of radio buttons.
1265 *
1266 * @param string The table name of the record
1267 * @param string The field name which this element is supposed to edit
1268 * @param array The record data array where the value(s) for the field can be found
1269 * @param array An array with additional configuration options.
1270 * @return string The HTML code for the TCEform field
1271 */
1272 function getSingleField_typeRadio($table,$field,$row,&$PA) {
1273 $config = $PA['fieldConf']['config'];
1274
1275 $disabled = '';
1276 if($this->renderReadonly || $config['readOnly']) {
1277 $disabled = ' disabled="disabled"';
1278 }
1279
1280 // Get items for the array:
1281 $selItems = $this->initItemArray($PA['fieldConf']);
1282 if ($config['itemsProcFunc']) $selItems = $this->procItems($selItems,$PA['fieldTSConfig']['itemsProcFunc.'],$config,$table,$row,$field);
1283
1284 // Traverse the items, making the form elements:
1285 for ($c=0;$c<count($selItems);$c++) {
1286 $p = $selItems[$c];
1287 $rID = $PA['itemFormElID'].'_'.$c;
1288 $rOnClick = implode('',$PA['fieldChangeFunc']);
1289 $rChecked = (!strcmp($p[1],$PA['itemFormElValue'])?' checked="checked"':'');
1290 $item.= '<input type="radio"'.$this->insertDefStyle('radio').' name="'.$PA['itemFormElName'].'" value="'.htmlspecialchars($p[1]).'" onclick="'.htmlspecialchars($rOnClick).'"'.$rChecked.$PA['onFocus'].$disabled.' id="'.$rID.'" />
1291 <label for="'.$rID.'">'.htmlspecialchars($p[0]).'</label>
1292 <br />';
1293 }
1294
1295 return $item;
1296 }
1297
1298 /**
1299 * Generation of TCEform elements of the type "select"
1300 * This will render a selector box element, or possibly a special construction with two selector boxes. That depends on configuration.
1301 *
1302 * @param string The table name of the record
1303 * @param string The field name which this element is supposed to edit
1304 * @param array The record data array where the value(s) for the field can be found
1305 * @param array An array with additional configuration options.
1306 * @return string The HTML code for the TCEform field
1307 */
1308 function getSingleField_typeSelect($table,$field,$row,&$PA) {
1309 global $TCA;
1310
1311 // Field configuration from TCA:
1312 $config = $PA['fieldConf']['config'];
1313
1314 $disabled = '';
1315 if($this->renderReadonly || $config['readOnly']) {
1316 $disabled = ' disabled="disabled"';
1317 }
1318
1319 // "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist. See http://typo3.org/documentation/document-library/doc_core_api/Wizards_Configuratio/.
1320 $specConf = $this->getSpecConfFromString($PA['extra'], $PA['fieldConf']['defaultExtras']);
1321
1322 // Getting the selector box items from the system
1323 $selItems = $this->addSelectOptionsToItemArray($this->initItemArray($PA['fieldConf']),$PA['fieldConf'],$this->setTSconfig($table,$row),$field);
1324 $selItems = $this->addItems($selItems,$PA['fieldTSConfig']['addItems.']);
1325 if ($config['itemsProcFunc']) $selItems = $this->procItems($selItems,$PA['fieldTSConfig']['itemsProcFunc.'],$config,$table,$row,$field);
1326
1327 // Possibly remove some items:
1328 $removeItems = t3lib_div::trimExplode(',',$PA['fieldTSConfig']['removeItems'],1);
1329 foreach($selItems as $tk => $p) {
1330
1331 // Checking languages and authMode:
1332 $languageDeny = $TCA[$table]['ctrl']['languageField'] && !strcmp($TCA[$table]['ctrl']['languageField'], $field) && !$GLOBALS['BE_USER']->checkLanguageAccess($p[1]);
1333 $authModeDeny = $config['form_type']=='select' && $config['authMode'] && !$GLOBALS['BE_USER']->checkAuthMode($table,$field,$p[1],$config['authMode']);
1334 if (in_array($p[1],$removeItems) || $languageDeny || $authModeDeny) {
1335 unset($selItems[$tk]);
1336 } elseif (isset($PA['fieldTSConfig']['altLabels.'][$p[1]])) {
1337 $selItems[$tk][0]=$this->sL($PA['fieldTSConfig']['altLabels.'][$p[1]]);
1338 }
1339
1340 // Removing doktypes with no access:
1341 if ($table.'.'.$field == 'pages.doktype') {
1342 if (!($GLOBALS['BE_USER']->isAdmin() || t3lib_div::inList($GLOBALS['BE_USER']->groupData['pagetypes_select'],$p[1]))) {
1343 unset($selItems[$tk]);
1344 }
1345 }
1346 }
1347
1348 // Creating the label for the "No Matching Value" entry.
1349 $nMV_label = isset($PA['fieldTSConfig']['noMatchingValue_label']) ? $this->sL($PA['fieldTSConfig']['noMatchingValue_label']) : '[ '.$this->getLL('l_noMatchingValue').' ]';
1350
1351 // Prepare some values:
1352 $maxitems = intval($config['maxitems']);
1353
1354 // If a SINGLE selector box...
1355 if ($maxitems<=1) {
1356 $item = $this->getSingleField_typeSelect_single($table,$field,$row,$PA,$config,$selItems,$nMV_label);
1357 } elseif (!strcmp($config['renderMode'],'checkbox')) { // Checkbox renderMode
1358 $item = $this->getSingleField_typeSelect_checkbox($table,$field,$row,$PA,$config,$selItems,$nMV_label);
1359 } elseif (!strcmp($config['renderMode'],'singlebox')) { // Single selector box renderMode
1360 $item = $this->getSingleField_typeSelect_singlebox($table,$field,$row,$PA,$config,$selItems,$nMV_label);
1361 } else { // Traditional multiple selector box:
1362 $item = $this->getSingleField_typeSelect_multiple($table,$field,$row,$PA,$config,$selItems,$nMV_label);
1363 }
1364
1365 // Wizards:
1366 if (!$disabled) {
1367 $altItem = '<input type="hidden" name="'.$PA['itemFormElName'].'" value="'.htmlspecialchars($PA['itemFormElValue']).'" />';
1368 $item = $this->renderWizards(array($item,$altItem),$config['wizards'],$table,$row,$field,$PA,$PA['itemFormElName'],$specConf);
1369 }
1370
1371 return $item;
1372 }
1373
1374 /**
1375 * Creates a single-selector box
1376 * (Render function for getSingleField_typeSelect())
1377 *
1378 * @param string See getSingleField_typeSelect()
1379 * @param string See getSingleField_typeSelect()
1380 * @param array See getSingleField_typeSelect()
1381 * @param array See getSingleField_typeSelect()
1382 * @param array (Redundant) content of $PA['fieldConf']['config'] (for convenience)
1383 * @param array Items available for selection
1384 * @param string Label for no-matching-value
1385 * @return string The HTML code for the item
1386 * @see getSingleField_typeSelect()
1387 */
1388 function getSingleField_typeSelect_single($table,$field,$row,&$PA,$config,$selItems,$nMV_label) {
1389 // check against inline uniqueness
1390 $inlineParent = $this->inline->getStructureLevel(-1);
1391 if(is_array($inlineParent) && $inlineParent['uid']) {
1392 if ($inlineParent['config']['foreign_table'] == $table && $inlineParent['config']['foreign_unique'] == $field) {
1393 $uniqueIds = $this->inline->inlineData['unique'][$this->inline->inlineNames['object'].'['.$table.']']['used'];
1394 $PA['fieldChangeFunc']['inlineUnique'] = "inline.updateUnique(this,'".$this->inline->inlineNames['object'].'['.$table."]','".$this->inline->inlineNames['form']."','".$row['uid']."');";
1395 }
1396 // hide uid of parent record for symmetric relations
1397 if ($inlineParent['config']['foreign_table'] == $table && ($inlineParent['config']['foreign_field'] == $field || $inlineParent['config']['symmetric_field'] == $field)) {
1398 $uniqueIds[] = $inlineParent['uid'];
1399 }
1400 }
1401
1402 // Initialization:
1403 $c = 0;
1404 $sI = 0;
1405 $noMatchingValue = 1;
1406 $opt = array();
1407 $selicons = array();
1408 $onlySelectedIconShown = 0;
1409 $size = intval($config['size']);
1410
1411 $disabled = '';
1412 if($this->renderReadonly || $config['readOnly']) {
1413 $disabled = ' disabled="disabled"';
1414 $onlySelectedIconShown = 1;
1415 }
1416
1417 // Icon configuration:
1418 if ($config['suppress_icons']=='IF_VALUE_FALSE') {
1419 $suppressIcons = !$PA['itemFormElValue'] ? 1 : 0;
1420 } elseif ($config['suppress_icons']=='ONLY_SELECTED') {
1421 $suppressIcons=0;
1422 $onlySelectedIconShown=1;
1423 } elseif ($config['suppress_icons']) {
1424 $suppressIcons = 1;
1425 } else $suppressIcons = 0;
1426
1427 // Traverse the Array of selector box items:
1428 foreach($selItems as $p) {
1429 $sM = (!strcmp($PA['itemFormElValue'],$p[1])?' selected="selected"':'');
1430 if ($sM) {
1431 $sI = $c;
1432 $noMatchingValue = 0;
1433 }
1434
1435 // Getting style attribute value (for icons):
1436 if ($config['iconsInOptionTags']) {
1437 $styleAttrValue = $this->optionTagStyle($p[2]);
1438 }
1439
1440 // Compiling the <option> tag:
1441 if (!($p[1] != $PA['itemFormElValue'] && is_array($uniqueIds) && in_array($p[1], $uniqueIds))) {
1442 $opt[]= '<option value="'.htmlspecialchars($p[1]).'"'.
1443 $sM.
1444 ($styleAttrValue ? ' style="'.htmlspecialchars($styleAttrValue).'"' : '').
1445 (!strcmp($p[1],'--div--') ? ' class="c-divider"' : '').
1446 '>'.t3lib_div::deHSCentities(htmlspecialchars($p[0])).'</option>';
1447 }
1448
1449 // If there is an icon for the selector box (rendered in table under)...:
1450 if ($p[2] && !$suppressIcons && (!$onlySelectedIconShown || $sM)) {
1451 list($selIconFile,$selIconInfo)=$this->getIcon($p[2]);
1452 $iOnClick = $this->elName($PA['itemFormElName']).'.selectedIndex='.$c.'; '.implode('',$PA['fieldChangeFunc']).$this->blur().'return false;';
1453 $selicons[]=array(
1454 (!$onlySelectedIconShown ? '<a href="#" onclick="'.htmlspecialchars($iOnClick).'">' : '').
1455 '<img src="'.$selIconFile.'" '.$selIconInfo[3].' vspace="2" border="0" title="'.htmlspecialchars($p[0]).'" alt="'.htmlspecialchars($p[0]).'" />'.
1456 (!$onlySelectedIconShown ? '</a>' : ''),
1457 $c,$sM);
1458 }
1459 $c++;
1460 }
1461
1462 // No-matching-value:
1463 if ($PA['itemFormElValue'] && $noMatchingValue && !$PA['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) {
1464 $nMV_label = @sprintf($nMV_label, $PA['itemFormElValue']);
1465 $opt[]= '<option value="'.htmlspecialchars($PA['itemFormElValue']).'" selected="selected">'.htmlspecialchars($nMV_label).'</option>';
1466 }
1467
1468 // Create item form fields:
1469 $sOnChange = 'if (this.options[this.selectedIndex].value==\'--div--\') {this.selectedIndex='.$sI.';} '.implode('',$PA['fieldChangeFunc']);
1470 if(!$disabled) {
1471 $item.= '<input type="hidden" name="'.$PA['itemFormElName'].'_selIconVal" value="'.htmlspecialchars($sI).'" />'; // MUST be inserted before the selector - else is the value of the hiddenfield here mysteriously submitted...
1472 }
1473 $item.= '<select name="'.$PA['itemFormElName'].'"'.
1474 $this->insertDefStyle('select').
1475 ($size?' size="'.$size.'"':'').
1476 ' onchange="'.htmlspecialchars($sOnChange).'"'.
1477 $PA['onFocus'].$disabled.'>';
1478 $item.= implode('',$opt);
1479 $item.= '</select>';
1480
1481 // Create icon table:
1482 if (count($selicons)) {
1483 $item.='<table border="0" cellpadding="0" cellspacing="0" class="typo3-TCEforms-selectIcons">';
1484 $selicon_cols = intval($config['selicon_cols']);
1485 if (!$selicon_cols) $selicon_cols=count($selicons);
1486 $sR = ceil(count($selicons)/$selicon_cols);
1487 $selicons = array_pad($selicons,$sR*$selicon_cols,'');
1488 for($sa=0;$sa<$sR;$sa++) {
1489 $item.='<tr>';
1490 for($sb=0;$sb<$selicon_cols;$sb++) {
1491 $sk=($sa*$selicon_cols+$sb);
1492 $imgN = 'selIcon_'.$table.'_'.$row['uid'].'_'.$field.'_'.$selicons[$sk][1];
1493 $imgS = ($selicons[$sk][2]?$this->backPath.'gfx/content_selected.gif':'clear.gif');
1494 $item.='<td><img name="'.htmlspecialchars($imgN).'" src="'.$imgS.'" width="7" height="10" alt="" /></td>';
1495 $item.='<td>'.$selicons[$sk][0].'</td>';
1496 }
1497 $item.='</tr>';
1498 }
1499 $item.='</table>';
1500 }
1501
1502 return $item;
1503 }
1504
1505 /**
1506 * Creates a checkbox list (renderMode = "checkbox")
1507 * (Render function for getSingleField_typeSelect())
1508 *
1509 * @param string See getSingleField_typeSelect()
1510 * @param string See getSingleField_typeSelect()
1511 * @param array See getSingleField_typeSelect()
1512 * @param array See getSingleField_typeSelect()
1513 * @param array (Redundant) content of $PA['fieldConf']['config'] (for convenience)
1514 * @param array Items available for selection
1515 * @param string Label for no-matching-value
1516 * @return string The HTML code for the item
1517 * @see getSingleField_typeSelect()
1518 */
1519 function getSingleField_typeSelect_checkbox($table,$field,$row,&$PA,$config,$selItems,$nMV_label) {
1520
1521 // Get values in an array (and make unique, which is fine because there can be no duplicates anyway):
1522 $itemArray = array_flip($this->extractValuesOnlyFromValueLabelList($PA['itemFormElValue']));
1523
1524 $disabled = '';
1525 if($this->renderReadonly || $config['readOnly']) {
1526 $disabled = ' disabled="disabled"';
1527 }
1528
1529 // Traverse the Array of selector box items:
1530 $tRows = array();
1531 $c=0;
1532 if (!$disabled) {
1533 $sOnChange = implode('',$PA['fieldChangeFunc']);
1534 $setAll = array(); // Used to accumulate the JS needed to restore the original selection.
1535 foreach($selItems as $p) {
1536 // Non-selectable element:
1537 if (!strcmp($p[1],'--div--')) {
1538 if (count($setAll)) {
1539 $tRows[] = '
1540 <tr>
1541 <td colspan="2">'.
1542 '<a href="#" onclick="'.htmlspecialchars(implode('',$setAll).' return false;').'">'.
1543 htmlspecialchars($this->getLL('l_setAllCheckboxes')).
1544 '</a></td>
1545 </tr>';
1546 $setAll = array();
1547 }
1548
1549 $tRows[] = '
1550 <tr class="c-header">
1551 <td colspan="2">'.htmlspecialchars($p[0]).'</td>
1552 </tr>';
1553 } else {
1554 // Selected or not by default:
1555 $sM = '';
1556 if (isset($itemArray[$p[1]])) {
1557 $sM = ' checked="checked"';
1558 unset($itemArray[$p[1]]);
1559 }
1560
1561 // Icon:
1562 $selIconFile = '';
1563 if ($p[2]) {
1564 list($selIconFile,$selIconInfo) = $this->getIcon($p[2]);
1565 }
1566
1567 // Compile row:
1568 $onClickCell = $this->elName($PA['itemFormElName'].'['.$c.']').'.checked=!'.$this->elName($PA['itemFormElName'].'['.$c.']').'.checked;';
1569 $onClick = 'this.attributes.getNamedItem("class").nodeValue = '.$this->elName($PA['itemFormElName'].'['.$c.']').'.checked ? "c-selectedItem" : "";';
1570 $setAll[] = $this->elName($PA['itemFormElName'].'['.$c.']').'.checked=1;';
1571 $tRows[] = '
1572 <tr class="'.($sM ? 'c-selectedItem' : '').'" onclick="'.htmlspecialchars($onClick).'" style="cursor: pointer;">
1573 <td><input type="checkbox"'.$this->insertDefStyle('check').' name="'.htmlspecialchars($PA['itemFormElName'].'['.$c.']').'" value="'.htmlspecialchars($p[1]).'"'.$sM.' onclick="'.htmlspecialchars($sOnChange).'"'.$PA['onFocus'].' /></td>
1574 <td class="c-labelCell" onclick="'.htmlspecialchars($onClickCell).'">'.
1575 ($selIconFile ? '<img src="'.$selIconFile.'" '.$selIconInfo[3].' vspace="2" border="0" class="absmiddle" style="margin-right: 4px;" alt="" />' : '').
1576 t3lib_div::deHSCentities(htmlspecialchars($p[0])).
1577 (strcmp($p[3],'') ? '<br/><p class="c-descr">'.nl2br(trim(htmlspecialchars($p[3]))).'</p>' : '').
1578 '</td>
1579 </tr>';
1580 $c++;
1581 }
1582 }
1583
1584 // Remaining checkboxes will get their set-all link:
1585 if (count($setAll)) {
1586 $tRows[] = '
1587 <tr>
1588 <td colspan="2">'.
1589 '<a href="#" onclick="'.htmlspecialchars(implode('',$setAll).' return false;').'">'.
1590 htmlspecialchars($this->getLL('l_setAllCheckboxes')).
1591 '</a></td>
1592 </tr>';
1593 }
1594 }
1595
1596 // Remaining values (invalid):
1597 if (count($itemArray) && !$PA['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) {
1598 foreach($itemArray as $theNoMatchValue => $temp) {
1599 // Compile <checkboxes> tag:
1600 array_unshift($tRows,'
1601 <tr class="c-invalidItem">
1602 <td><input type="checkbox"'.$this->insertDefStyle('check').' name="'.htmlspecialchars($PA['itemFormElName'].'['.$c.']').'" value="'.htmlspecialchars($theNoMatchValue).'" checked="checked" onclick="'.htmlspecialchars($sOnChange).'"'.$PA['onFocus'].$disabled.' /></td>
1603 <td class="c-labelCell">'.
1604 t3lib_div::deHSCentities(htmlspecialchars(@sprintf($nMV_label, $theNoMatchValue))).
1605 '</td>
1606 </tr>');
1607 $c++;
1608 }
1609 }
1610
1611 // Add an empty hidden field which will send a blank value if all items are unselected.
1612 $item.='<input type="hidden" name="'.htmlspecialchars($PA['itemFormElName']).'" value="" />';
1613
1614 // Implode rows in table:
1615 $item.= '
1616 <table border="0" cellpadding="0" cellspacing="0" class="typo3-TCEforms-select-checkbox">'.
1617 implode('',$tRows).'
1618 </table>
1619 ';
1620
1621 return $item;
1622 }
1623
1624 /**
1625 * Creates a selectorbox list (renderMode = "singlebox")
1626 * (Render function for getSingleField_typeSelect())
1627 *
1628 * @param string See getSingleField_typeSelect()
1629 * @param string See getSingleField_typeSelect()
1630 * @param array See getSingleField_typeSelect()
1631 * @param array See getSingleField_typeSelect()
1632 * @param array (Redundant) content of $PA['fieldConf']['config'] (for convenience)
1633 * @param array Items available for selection
1634 * @param string Label for no-matching-value
1635 * @return string The HTML code for the item
1636 * @see getSingleField_typeSelect()
1637 */
1638 function getSingleField_typeSelect_singlebox($table,$field,$row,&$PA,$config,$selItems,$nMV_label) {
1639
1640 // Get values in an array (and make unique, which is fine because there can be no duplicates anyway):
1641 $itemArray = array_flip($this->extractValuesOnlyFromValueLabelList($PA['itemFormElValue']));
1642
1643 $disabled = '';
1644 if($this->renderReadonly || $config['readOnly']) {
1645 $disabled = ' disabled="disabled"';
1646 }
1647
1648 // Traverse the Array of selector box items:
1649 $opt = array();
1650 $restoreCmd = array(); // Used to accumulate the JS needed to restore the original selection.
1651 $c = 0;
1652 foreach($selItems as $p) {
1653 // Selected or not by default:
1654 $sM = '';
1655 if (isset($itemArray[$p[1]])) {
1656 $sM = ' selected="selected"';
1657 $restoreCmd[] = $this->elName($PA['itemFormElName'].'[]').'.options['.$c.'].selected=1;';
1658 unset($itemArray[$p[1]]);
1659 }
1660
1661 // Non-selectable element:
1662 $nonSel = '';
1663 if (!strcmp($p[1],'--div--')) {
1664 $nonSel = ' onclick="this.selected=0;" class="c-divider"';
1665 }
1666
1667 // Icon style for option tag:
1668 if ($config['iconsInOptionTags']) {
1669 $styleAttrValue = $this->optionTagStyle($p[2]);
1670 }
1671
1672 // Compile <option> tag:
1673 $opt[] = '<option value="'.htmlspecialchars($p[1]).'"'.
1674 $sM.
1675 $nonSel.
1676 ($styleAttrValue ? ' style="'.htmlspecialchars($styleAttrValue).'"' : '').
1677 '>'.t3lib_div::deHSCentities(htmlspecialchars($p[0])).'</option>';
1678 $c++;
1679 }
1680
1681 // Remaining values:
1682 if (count($itemArray) && !$PA['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) {
1683 foreach($itemArray as $theNoMatchValue => $temp) {
1684 // Compile <option> tag:
1685 array_unshift($opt,'<option value="'.htmlspecialchars($theNoMatchValue).'" selected="selected">'.t3lib_div::deHSCentities(htmlspecialchars(@sprintf($nMV_label, $theNoMatchValue))).'</option>');
1686 }
1687 }
1688
1689 // Compile selector box:
1690 $sOnChange = implode('',$PA['fieldChangeFunc']);
1691 $selector_itemListStyle = isset($config['itemListStyle']) ? ' style="'.htmlspecialchars($config['itemListStyle']).'"' : ' style="'.$this->defaultMultipleSelectorStyle.'"';
1692 $size = intval($config['size']);
1693 $size = $config['autoSizeMax'] ? t3lib_div::intInRange(count($selItems)+1,t3lib_div::intInRange($size,1),$config['autoSizeMax']) : $size;
1694 $selectBox = '<select name="'.$PA['itemFormElName'].'[]"'.
1695 $this->insertDefStyle('select').
1696 ($size ? ' size="'.$size.'"' : '').
1697 ' multiple="multiple" onchange="'.htmlspecialchars($sOnChange).'"'.
1698 $PA['onFocus'].
1699 $selector_itemListStyle.
1700 $disabled.'>
1701 '.
1702 implode('
1703 ',$opt).'
1704 </select>';
1705
1706 // Add an empty hidden field which will send a blank value if all items are unselected.
1707 if (!$disabled) {
1708 $item.='<input type="hidden" name="'.htmlspecialchars($PA['itemFormElName']).'" value="" />';
1709 }
1710
1711 // Put it all into a table:
1712 $item.= '
1713 <table border="0" cellspacing="0" cellpadding="0" width="1" class="typo3-TCEforms-select-singlebox">
1714 <tr>
1715 <td>
1716 '.$selectBox.'
1717 <br/>
1718 <em>'.
1719 htmlspecialchars($this->getLL('l_holdDownCTRL')).
1720 '</em>
1721 </td>
1722 <td valign="top">
1723 <a href="#" onclick="'.htmlspecialchars($this->elName($PA['itemFormElName'].'[]').'.selectedIndex=-1;'.implode('',$restoreCmd).' return false;').'">'.
1724 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/history.gif','width="13" height="12"').' title="'.htmlspecialchars($this->getLL('l_revertSelection')).'" alt="" />'.
1725 '</a>
1726 </td>
1727 </tr>
1728 </table>
1729 ';
1730
1731 return $item;
1732 }
1733
1734 /**
1735 * Creates a multiple-selector box (two boxes, side-by-side)
1736 * (Render function for getSingleField_typeSelect())
1737 *
1738 * @param string See getSingleField_typeSelect()
1739 * @param string See getSingleField_typeSelect()
1740 * @param array See getSingleField_typeSelect()
1741 * @param array See getSingleField_typeSelect()
1742 * @param array (Redundant) content of $PA['fieldConf']['config'] (for convenience)
1743 * @param array Items available for selection
1744 * @param string Label for no-matching-value
1745 * @return string The HTML code for the item
1746 * @see getSingleField_typeSelect()
1747 */
1748 function getSingleField_typeSelect_multiple($table,$field,$row,&$PA,$config,$selItems,$nMV_label) {
1749
1750 $disabled = '';
1751 if($this->renderReadonly || $config['readOnly']) {
1752 $disabled = ' disabled="disabled"';
1753 }
1754
1755 // Setting this hidden field (as a flag that JavaScript can read out)
1756 if (!$disabled) {
1757 $item.= '<input type="hidden" name="'.$PA['itemFormElName'].'_mul" value="'.($config['multiple']?1:0).'" />';
1758 }
1759
1760 // Set max and min items:
1761 $maxitems = t3lib_div::intInRange($config['maxitems'],0);
1762 if (!$maxitems) $maxitems=100000;
1763 $minitems = t3lib_div::intInRange($config['minitems'],0);
1764
1765 // Register the required number of elements:
1766 $this->requiredElements[$PA['itemFormElName']] = array($minitems,$maxitems,'imgName'=>$table.'_'.$row['uid'].'_'.$field);
1767
1768 // Get "removeItems":
1769 $removeItems = t3lib_div::trimExplode(',',$PA['fieldTSConfig']['removeItems'],1);
1770
1771 // Perform modification of the selected items array:
1772 $itemArray = t3lib_div::trimExplode(',',$PA['itemFormElValue'],1);
1773 foreach($itemArray as $tk => $tv) {
1774 $tvP = explode('|',$tv,2);
1775 $evalValue = rawurldecode($tvP[0]);
1776 $isRemoved = in_array($evalValue,$removeItems) || ($config['form_type']=='select' && $config['authMode'] && !$GLOBALS['BE_USER']->checkAuthMode($table,$field,$evalValue,$config['authMode']));
1777 if ($isRemoved && !$PA['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) {
1778 $tvP[1] = rawurlencode(@sprintf($nMV_label, $evalValue));
1779 } elseif (isset($PA['fieldTSConfig']['altLabels.'][$evalValue])) {
1780 $tvP[1] = rawurlencode($this->sL($PA['fieldTSConfig']['altLabels.'][$evalValue]));
1781 }
1782 $itemArray[$tk] = implode('|',$tvP);
1783 }
1784 $itemsToSelect = '';
1785
1786 if(!$disabled) {
1787 // Create option tags:
1788 $opt = array();
1789 $styleAttrValue = '';
1790 foreach($selItems as $p) {
1791 if ($config['iconsInOptionTags']) {
1792 $styleAttrValue = $this->optionTagStyle($p[2]);
1793 }
1794 $opt[]= '<option value="'.htmlspecialchars($p[1]).'"'.
1795 ($styleAttrValue ? ' style="'.htmlspecialchars($styleAttrValue).'"' : '').
1796 '>'.htmlspecialchars($p[0]).'</option>';
1797 }
1798
1799 // Put together the selector box:
1800 $selector_itemListStyle = isset($config['itemListStyle']) ? ' style="'.htmlspecialchars($config['itemListStyle']).'"' : ' style="'.$this->defaultMultipleSelectorStyle.'"';
1801 $size = intval($config['size']);
1802 $size = $config['autoSizeMax'] ? t3lib_div::intInRange(count($itemArray)+1,t3lib_div::intInRange($size,1),$config['autoSizeMax']) : $size;
1803 if ($config['exclusiveKeys']) {
1804 $sOnChange = 'setFormValueFromBrowseWin(\''.$PA['itemFormElName'].'\',this.options[this.selectedIndex].value,this.options[this.selectedIndex].text,\''.$config['exclusiveKeys'].'\'); ';
1805 } else {
1806 $sOnChange = 'setFormValueFromBrowseWin(\''.$PA['itemFormElName'].'\',this.options[this.selectedIndex].value,this.options[this.selectedIndex].text); ';
1807 }
1808 $sOnChange .= implode('',$PA['fieldChangeFunc']);
1809 $itemsToSelect = '
1810 <select name="'.$PA['itemFormElName'].'_sel"'.
1811 $this->insertDefStyle('select').
1812 ($size ? ' size="'.$size.'"' : '').
1813 ' onchange="'.htmlspecialchars($sOnChange).'"'.
1814 $PA['onFocus'].
1815 $selector_itemListStyle.'>
1816 '.implode('
1817 ',$opt).'
1818 </select>';
1819 }
1820
1821 // Pass to "dbFileIcons" function:
1822 $params = array(
1823 'size' => $size,
1824 'autoSizeMax' => t3lib_div::intInRange($config['autoSizeMax'],0),
1825 'style' => isset($config['selectedListStyle']) ? ' style="'.htmlspecialchars($config['selectedListStyle']).'"' : ' style="'.$this->defaultMultipleSelectorStyle.'"',
1826 'dontShowMoveIcons' => ($maxitems<=1),
1827 'maxitems' => $maxitems,
1828 'info' => '',
1829 'headers' => array(
1830 'selector' => $this->getLL('l_selected').':<br />',
1831 'items' => $this->getLL('l_items').':<br />'
1832 ),
1833 'noBrowser' => 1,
1834 'thumbnails' => $itemsToSelect,
1835 'readOnly' => $disabled
1836 );
1837 $item.= $this->dbFileIcons($PA['itemFormElName'],'','',$itemArray,'',$params,$PA['onFocus']);
1838
1839 return $item;
1840 }
1841
1842 /**
1843 * Generation of TCEform elements of the type "group"
1844 * This will render a selectorbox into which elements from either the file system or database can be inserted. Relations.
1845 *
1846 * @param string The table name of the record
1847 * @param string The field name which this element is supposed to edit
1848 * @param array The record data array where the value(s) for the field can be found
1849 * @param array An array with additional configuration options.
1850 * @return string The HTML code for the TCEform field
1851 */
1852 function getSingleField_typeGroup($table,$field,$row,&$PA) {
1853 // Init:
1854 $config = $PA['fieldConf']['config'];
1855 $internal_type = $config['internal_type'];
1856 $show_thumbs = $config['show_thumbs'];
1857 $size = intval($config['size']);
1858 $maxitems = t3lib_div::intInRange($config['maxitems'],0);
1859 if (!$maxitems) $maxitems=100000;
1860 $minitems = t3lib_div::intInRange($config['minitems'],0);
1861 $allowed = $config['allowed'];
1862 $disallowed = $config['disallowed'];
1863
1864 $disabled = '';
1865 if($this->renderReadonly || $config['readOnly']) {
1866 $disabled = ' disabled="disabled"';
1867 }
1868
1869 $item.= '<input type="hidden" name="'.$PA['itemFormElName'].'_mul" value="'.($config['multiple']?1:0).'"'.$disabled.' />';
1870 $this->requiredElements[$PA['itemFormElName']] = array($minitems,$maxitems,'imgName'=>$table.'_'.$row['uid'].'_'.$field);
1871 $info='';
1872
1873 // "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist. See http://typo3.org/documentation/document-library/doc_core_api/Wizards_Configuratio/.
1874 $specConf = $this->getSpecConfFromString($PA['extra'], $PA['fieldConf']['defaultExtras']);
1875
1876 // Acting according to either "file" or "db" type:
1877 switch((string)$config['internal_type']) {
1878 case 'file': // If the element is of the internal type "file":
1879
1880 // Creating string showing allowed types:
1881 $tempFT = t3lib_div::trimExplode(',',$allowed,1);
1882 if (!count($tempFT)) {$info.='*';}
1883 foreach($tempFT as $ext) {
1884 if ($ext) {
1885 $info.=strtoupper($ext).' ';
1886 }
1887 }
1888 // Creating string, showing disallowed types:
1889 $tempFT_dis = t3lib_div::trimExplode(',',$disallowed,1);
1890 if (count($tempFT_dis)) {$info.='<br />';}
1891 foreach($tempFT_dis as $ext) {
1892 if ($ext) {
1893 $info.='-'.strtoupper($ext).' ';
1894 }
1895 }
1896
1897 // Making the array of file items:
1898 $itemArray = t3lib_div::trimExplode(',',$PA['itemFormElValue'],1);
1899
1900 // Showing thumbnails:
1901 $thumbsnail = '';
1902 if ($show_thumbs) {
1903 $imgs = array();
1904 foreach($itemArray as $imgRead) {
1905 $imgP = explode('|',$imgRead);
1906 $imgPath = rawurldecode($imgP[0]);
1907
1908 $rowCopy = array();
1909 $rowCopy[$field] = $imgPath;
1910
1911 // Icon + clickmenu:
1912 $absFilePath = t3lib_div::getFileAbsFileName($config['uploadfolder'].'/'.$imgPath);
1913
1914 $fI = pathinfo($imgPath);
1915 $fileIcon = t3lib_BEfunc::getFileIcon(strtolower($fI['extension']));
1916 $fileIcon = '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/fileicons/'.$fileIcon,'width="18" height="16"').' class="absmiddle" title="'.htmlspecialchars($fI['basename'].($absFilePath && @is_file($absFilePath) ? ' ('.t3lib_div::formatSize(filesize($absFilePath)).'bytes)' : ' - FILE NOT FOUND!')).'" alt="" />';
1917
1918 $imgs[] = '<span class="nobr">'.t3lib_BEfunc::thumbCode($rowCopy,$table,$field,$this->backPath,'thumbs.php',$config['uploadfolder'],0,' align="middle"').
1919 ($absFilePath ? $this->getClickMenu($fileIcon, $absFilePath) : $fileIcon).
1920 $imgPath.
1921 '</span>';
1922 }
1923 $thumbsnail = implode('<br />',$imgs);
1924 }
1925
1926 // Creating the element:
1927 $params = array(
1928 'size' => $size,
1929 'dontShowMoveIcons' => ($maxitems<=1),
1930 'autoSizeMax' => t3lib_div::intInRange($config['autoSizeMax'],0),
1931 'maxitems' => $maxitems,
1932 'style' => isset($config['selectedListStyle']) ? ' style="'.htmlspecialchars($config['selectedListStyle']).'"' : ' style="'.$this->defaultMultipleSelectorStyle.'"',
1933 'info' => $info,
1934 'thumbnails' => $thumbsnail,
1935 'readOnly' => $disabled
1936 );
1937 $item.= $this->dbFileIcons($PA['itemFormElName'],'file',implode(',',$tempFT),$itemArray,'',$params,$PA['onFocus']);
1938
1939 if(!$disabled) {
1940 // Adding the upload field:
1941 if ($this->edit_docModuleUpload) $item.='<input type="file" name="'.$PA['itemFormElName_file'].'"'.$this->formWidth().' size="60" />';
1942 }
1943 break;
1944 case 'db': // If the element is of the internal type "db":
1945
1946 // Creating string showing allowed types:
1947 $tempFT = t3lib_div::trimExplode(',',$allowed,1);
1948 if (!strcmp(trim($tempFT[0]),'*')) {
1949 $info.='<span class="nobr">&nbsp;&nbsp;&nbsp;&nbsp;'.
1950 htmlspecialchars($this->getLL('l_allTables')).
1951 '</span><br />';
1952 } else {
1953 while(list(,$theT)=each($tempFT)) {
1954 if ($theT) {
1955 $info.='<span class="nobr">&nbsp;&nbsp;&nbsp;&nbsp;'.
1956 t3lib_iconWorks::getIconImage($theT,array(),$this->backPath,'align="top"').
1957 htmlspecialchars($this->sL($GLOBALS['TCA'][$theT]['ctrl']['title'])).
1958 '</span><br />';
1959 }
1960 }
1961 }
1962
1963 $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);
1964 $itemArray = array();
1965 $imgs = array();
1966
1967 // Thumbnails:
1968 $temp_itemArray = t3lib_div::trimExplode(',',$PA['itemFormElValue'],1);
1969 foreach($temp_itemArray as $dbRead) {
1970 $recordParts = explode('|',$dbRead);
1971 list($this_table,$this_uid) = t3lib_BEfunc::splitTable_Uid($recordParts[0]);
1972 $itemArray[] = array('table'=>$this_table, 'id'=>$this_uid);
1973 if (!$disabled && $show_thumbs) {
1974 $rr = t3lib_BEfunc::getRecordWSOL($this_table,$this_uid);
1975 $imgs[] = '<span class="nobr">'.
1976 $this->getClickMenu(t3lib_iconWorks::getIconImage($this_table,$rr,$this->backPath,'align="top" title="'.htmlspecialchars(t3lib_BEfunc::getRecordPath($rr['pid'],$perms_clause,15)).' [UID: '.$rr['uid'].']"'),$this_table, $this_uid).
1977 '&nbsp;'.
1978 t3lib_BEfunc::getRecordTitle($this_table,$rr,TRUE).' <span class="typo3-dimmed"><em>['.$rr['uid'].']</em></span>'.
1979 '</span>';
1980 }
1981 }
1982 $thumbsnail='';
1983 if (!$disabled && $show_thumbs) {
1984 $thumbsnail = implode('<br />',$imgs);
1985 }
1986
1987 // Creating the element:
1988 $params = array(
1989 'size' => $size,
1990 'dontShowMoveIcons' => ($maxitems<=1),
1991 'autoSizeMax' => t3lib_div::intInRange($config['autoSizeMax'],0),
1992 'maxitems' => $maxitems,
1993 'style' => isset($config['selectedListStyle']) ? ' style="'.htmlspecialchars($config['selectedListStyle']).'"' : ' style="'.$this->defaultMultipleSelectorStyle.'"',
1994 'info' => $info,
1995 'thumbnails' => $thumbsnail,
1996 'readOnly' => $disabled
1997 );
1998 $item.= $this->dbFileIcons($PA['itemFormElName'],'db',implode(',',$tempFT),$itemArray,'',$params,$PA['onFocus']);
1999
2000 break;
2001 }
2002
2003 // Wizards:
2004 $altItem = '<input type="hidden" name="'.$PA['itemFormElName'].'" value="'.htmlspecialchars($PA['itemFormElValue']).'" />';
2005 if (!$disabled) {
2006 $item = $this->renderWizards(array($item,$altItem),$config['wizards'],$table,$row,$field,$PA,$PA['itemFormElName'],$specConf);
2007 }
2008
2009 return $item;
2010 }
2011
2012 /**
2013 * Generation of TCEform elements of the type "none"
2014 * This will render a non-editable display of the content of the field.
2015 *
2016 * @param string The table name of the record
2017 * @param string The field name which this element is supposed to edit
2018 * @param array The record data array where the value(s) for the field can be found
2019 * @param array An array with additional configuration options.
2020 * @return string The HTML code for the TCEform field
2021 */
2022 function getSingleField_typeNone($table,$field,$row,&$PA) {
2023 // Init:
2024 $config = $PA['fieldConf']['config'];
2025 $itemValue = $PA['itemFormElValue'];
2026
2027 return $this->getSingleField_typeNone_render($config,$itemValue);
2028 }
2029
2030 /**
2031 * HTML rendering of a value which is not editable.
2032 *
2033 * @param array Configuration for the display
2034 * @param string The value to display
2035 * @return string The HTML code for the display
2036 * @see getSingleField_typeNone();
2037 */
2038 function getSingleField_typeNone_render($config,$itemValue) {
2039
2040 // is colorScheme[0] the right value?
2041 $divStyle = 'border:solid 1px '.t3lib_div::modifyHTMLColorAll($this->colorScheme[0],-30).';'.$this->defStyle.$this->formElStyle('none').' background-color: '.$this->colorScheme[0].'; padding-left:1px;color:#555;';
2042
2043 if ($config['format']) {
2044 $itemValue = $this->formatValue($config, $itemValue);
2045 }
2046
2047 $rows = intval($config['rows']);
2048 if ($rows > 1) {
2049 if(!$config['pass_content']) {
2050 $itemValue = nl2br(htmlspecialchars($itemValue));
2051 }
2052 // like textarea
2053 $cols = t3lib_div::intInRange($config['cols'] ? $config['cols'] : 30, 5, $this->maxTextareaWidth);
2054 if (!$config['fixedRows']) {
2055 $origRows = $rows = t3lib_div::intInRange($rows, 1, 20);
2056 if (strlen($itemValue)>$this->charsPerRow*2) {
2057 $cols = $this->maxTextareaWidth;
2058 $rows = t3lib_div::intInRange(round(strlen($itemValue)/$this->charsPerRow),count(explode(chr(10),$itemValue)),20);
2059 if ($rows<$origRows) $rows=$origRows;
2060 }
2061 }
2062
2063 if ($this->docLarge) $cols = round($cols*$this->form_largeComp);
2064 $width = ceil($cols*$this->form_rowsToStylewidth);
2065 // hardcoded: 12 is the height of the font
2066 $height=$rows*12;
2067
2068 $item='
2069 <div style="'.htmlspecialchars($divStyle.' overflow:auto; height:'.$height.'px; width:'.$width.'px;').'" class="'.htmlspecialchars($this->formElClass('none')).'">'.
2070 $itemValue.
2071 '</div>';
2072 } else {
2073 if(!$config['pass_content']) {
2074 $itemValue = htmlspecialchars($itemValue);
2075 }
2076
2077 $cols = $config['cols']?$config['cols']:($config['size']?$config['size']:$this->maxInputWidth);
2078 if ($this->docLarge) $cols = round($cols*$this->form_largeComp);
2079 $width = ceil($cols*$this->form_rowsToStylewidth);
2080
2081 // overflow:auto crashes mozilla here. Title tag is usefull when text is longer than the div box (overflow:hidden).
2082 $item = '
2083 <div style="'.htmlspecialchars($divStyle.' overflow:hidden; width:'.$width.'px;').'" class="'.htmlspecialchars($this->formElClass('none')).'" title="'.$itemValue.'">'.
2084 '<span class="nobr">'.(strcmp($itemValue,'')?$itemValue:'&nbsp;').'</span>'.
2085 '</div>';
2086 }
2087
2088 return $item;
2089 }
2090
2091 /**
2092 * Handler for Flex Forms
2093 *
2094 * @param string The table name of the record
2095 * @param string The field name which this element is supposed to edit
2096 * @param array The record data array where the value(s) for the field can be found
2097 * @param array An array with additional configuration options.
2098 * @return string The HTML code for the TCEform field
2099 */
2100 function getSingleField_typeFlex($table,$field,$row,&$PA) {
2101
2102 // Data Structure:
2103 $dataStructArray = t3lib_BEfunc::getFlexFormDS($PA['fieldConf']['config'],$row,$table);
2104
2105 // Get data structure:
2106 if (is_array($dataStructArray)) {
2107
2108 // Get data:
2109 $xmlData = $PA['itemFormElValue'];
2110 $xmlHeaderAttributes = t3lib_div::xmlGetHeaderAttribs($xmlData);
2111 $storeInCharset = strtolower($xmlHeaderAttributes['encoding']);
2112 if ($storeInCharset) {
2113 $currentCharset=$GLOBALS['LANG']->charSet;
2114 $xmlData = $GLOBALS['LANG']->csConvObj->conv($xmlData,$storeInCharset,$currentCharset,1);
2115 }
2116 $editData=t3lib_div::xml2array($xmlData);
2117 if (!is_array($editData)) { // Must be XML parsing error...
2118 $editData=array();
2119 } elseif (!isset($editData['meta']) || !is_array($editData['meta'])) {
2120 $editData['meta'] = array();
2121 }
2122
2123 // Find the data structure if sheets are found:
2124 $sheet = $editData['meta']['currentSheetId'] ? $editData['meta']['currentSheetId'] : 'sDEF'; // Sheet to display
2125
2126 // Create sheet menu:
2127 // if (is_array($dataStructArray['sheets'])) {
2128 // #$item.=$this->getSingleField_typeFlex_sheetMenu($dataStructArray['sheets'], $PA['itemFormElName'].'[meta][currentSheetId]', $sheet).'<br />';
2129 // }
2130
2131 // Create language menu:
2132 $langChildren = $dataStructArray['meta']['langChildren'] ? 1 : 0;
2133 $langDisabled = $dataStructArray['meta']['langDisable'] ? 1 : 0;
2134
2135 $editData['meta']['currentLangId']=array();
2136 $languages = $this->getAvailableLanguages();
2137
2138 foreach($languages as $lInfo) {
2139 if ($GLOBALS['BE_USER']->checkLanguageAccess($lInfo['uid'])) {
2140 $editData['meta']['currentLangId'][] = $lInfo['ISOcode'];
2141 }
2142 }
2143 if (!is_array($editData['meta']['currentLangId']) || !count($editData['meta']['currentLangId'])) {
2144 $editData['meta']['currentLangId']=array('DEF');
2145 }
2146
2147 $editData['meta']['currentLangId'] = array_unique($editData['meta']['currentLangId']);
2148
2149
2150 // if (!$langDisabled && count($languages) > 1) {
2151 // $item.=$this->getSingleField_typeFlex_langMenu($languages, $PA['itemFormElName'].'[meta][currentLangId]', $editData['meta']['currentLangId']).'<br />';
2152 // }
2153
2154 $PA['_noEditDEF'] = FALSE;
2155 if ($langChildren || $langDisabled) {
2156 $rotateLang = array('DEF');
2157 } else {
2158 if (!in_array('DEF',$editData['meta']['currentLangId'])) {
2159 array_unshift($editData['meta']['currentLangId'],'DEF');
2160 $PA['_noEditDEF'] = TRUE;
2161 }
2162 $rotateLang = $editData['meta']['currentLangId'];
2163 }
2164
2165 // Tabs sheets
2166 if (is_array($dataStructArray['sheets'])) {
2167 $tabsToTraverse = array_keys($dataStructArray['sheets']);
2168 } else {
2169 $tabsToTraverse = array($sheet);
2170 }
2171
2172 foreach ($rotateLang as $lKey) {
2173 if (!$langChildren && !$langDisabled) {
2174 $item.= '<b>'.$this->getLanguageIcon($table,$row,'v'.$lKey).$lKey.':</b>';
2175 }
2176
2177 $tabParts = array();
2178 foreach ($tabsToTraverse as $sheet) {
2179 $sheetCfg = $dataStructArray['sheets'][$sheet];
2180 list ($dataStruct, $sheet) = t3lib_div::resolveSheetDefInDS($dataStructArray,$sheet);
2181
2182 // Render sheet:
2183 if (is_array($dataStruct['ROOT']) && is_array($dataStruct['ROOT']['el'])) {
2184 $cmdData = t3lib_div::_GP('flexFormsCmdData');
2185 $lang = 'l'.$lKey; // Default language, other options are "lUK" or whatever country code (independant of system!!!)
2186 $PA['_valLang'] = $langChildren && !$langDisabled ? $editData['meta']['currentLangId'] : 'DEF'; // Default language, other options are "lUK" or whatever country code (independant of system!!!)
2187 $PA['_lang'] = $lang;
2188
2189 // Render flexform:
2190 $tRows = $this->getSingleField_typeFlex_draw(
2191 $dataStruct['ROOT']['el'],
2192 $editData['data'][$sheet][$lang],
2193 $cmdData['data'][$sheet][$lang],
2194 $table,
2195 $field,
2196 $row,
2197 $PA,
2198 '[data]['.$sheet.']['.$lang.']'
2199 );
2200 $sheetContent= '<table border="0" cellpadding="1" cellspacing="1" class="typo3-TCEforms-flexForm">'.implode('',$tRows).'</table>';
2201
2202 # $item = '<div style=" position:absolute;">'.$item.'</div>';
2203 //visibility:hidden;
2204 } else $sheetContent='Data Structure ERROR: No ROOT element found for sheet "'.$sheet.'".';
2205
2206 // Add to tab:
2207 $tabParts[] = array(
2208 'label' => ($sheetCfg['ROOT']['TCEforms']['sheetTitle'] ? $this->sL($sheetCfg['ROOT']['TCEforms']['sheetTitle']) : $sheet),
2209 'description' => ($sheetCfg['ROOT']['TCEforms']['sheetDescription'] ? $this->sL($sheetCfg['ROOT']['TCEforms']['sheetDescription']) : ''),
2210 'linkTitle' => ($sheetCfg['ROOT']['TCEforms']['sheetShortDescr'] ? $this->sL($sheetCfg['ROOT']['TCEforms']['sheetShortDescr']) : ''),
2211 'content' => $sheetContent
2212 );
2213 }
2214
2215 if (is_array($dataStructArray['sheets'])) {
2216 $item.= $this->getDynTabMenu($tabParts,'TCEFORMS:flexform:'.$PA['itemFormElName'].$PA['_lang']);
2217 } else {
2218 $item.= $sheetContent;
2219 }
2220 }
2221 } else $item='Data Structure ERROR: '.$dataStructArray;
2222
2223 return $item;
2224 }
2225
2226 /**
2227 * Creates the language menu for FlexForms:
2228 *
2229 * @param [type] $languages: ...
2230 * @param [type] $elName: ...
2231 * @param [type] $selectedLanguage: ...
2232 * @param [type] $multi: ...
2233 * @return string HTML for menu
2234 */
2235 function getSingleField_typeFlex_langMenu($languages,$elName,$selectedLanguage,$multi=1) {
2236 $opt=array();
2237 foreach($languages as $lArr) {
2238 $opt[]='<option value="'.htmlspecialchars($lArr['ISOcode']).'"'.(in_array($lArr['ISOcode'],$selectedLanguage)?' selected="selected"':'').'>'.htmlspecialchars($lArr['title']).'</option>';
2239 }
2240
2241 $output = '<select name="'.$elName.'[]"'.($multi ? ' multiple="multiple" size="'.count($languages).'"' : '').'>'.implode('',$opt).'</select>';
2242
2243 return $output;
2244 }
2245
2246 /**
2247 * Creates the menu for selection of the sheets:
2248 *
2249 * @param array Sheet array for which to render the menu
2250 * @param string Form element name of the field containing the sheet pointer
2251 * @param string Current sheet key
2252 * @return string HTML for menu
2253 */
2254 function getSingleField_typeFlex_sheetMenu($sArr,$elName,$sheetKey) {
2255
2256 $tCells =array();
2257 $pct = round(100/count($sArr));
2258 foreach($sArr as $sKey => $sheetCfg) {
2259 if ($GLOBALS['BE_USER']->jsConfirmation(1)) {
2260 $onClick = 'if (confirm(TBE_EDITOR.labels.onChangeAlert) && TBE_EDITOR.checkSubmit(-1)){'.$this->elName($elName).".value='".$sKey."'; TBE_EDITOR.submitForm()};";
2261 } else {
2262 $onClick = 'if(TBE_EDITOR.checkSubmit(-1)){ '.$this->elName($elName).".value='".$sKey."'; TBE_EDITOR.submitForm();}";
2263 }
2264
2265
2266 $tCells[]='<td width="'.$pct.'%" style="'.($sKey==$sheetKey ? 'background-color: #9999cc; font-weight: bold;' : 'background-color: #aaaaaa;').' cursor: hand;" onclick="'.htmlspecialchars($onClick).'" align="center">'.
2267 ($sheetCfg['ROOT']['TCEforms']['sheetTitle'] ? $this->sL($sheetCfg['ROOT']['TCEforms']['sheetTitle']) : $sKey).
2268 '</td>';
2269 }
2270
2271 return '<table border="0" cellpadding="0" cellspacing="2" class="typo3-TCEforms-flexForm-sheetMenu"><tr>'.implode('',$tCells).'</tr></table>';
2272 }
2273
2274 /**
2275 * [Describe function...]
2276 *
2277 * @param [type] $dataStruct: ...
2278 * @param [type] $editData: ...
2279 * @param [type] $cmdData: ...
2280 * @param [type] $table: ...
2281 * @param [type] $field: ...
2282 * @param [type] $row: ...
2283 * @param [type] $PA: ...
2284 * @param [type] $formPrefix: ...
2285 * @param [type] $level: ...
2286 * @param [type] $tRows: ...
2287 * @return [type] ...
2288 */
2289 function getSingleField_typeFlex_draw($dataStruct,$editData,$cmdData,$table,$field,$row,&$PA,$formPrefix='',$level=0,$tRows=array()) {
2290
2291 // Data Structure array must be ... and array of course...
2292 if (is_array($dataStruct)) {
2293 foreach($dataStruct as $key => $value) {
2294 if (is_array($value)) { // The value of each entry must be an array.
2295
2296 // ********************
2297 // Making the row:
2298 // ********************
2299 $rowCells=array();
2300
2301 // Icon:
2302 $rowCells['title'] = '<img src="clear.gif" width="'.($level*16).'" height="1" alt="" /><strong>'.htmlspecialchars(t3lib_div::fixed_lgd_cs($this->sL($value['tx_templavoila']['title']),30)).'</strong>';;
2303
2304 $rowCells['formEl']='';
2305 if ($value['type']=='array') {
2306 if ($value['section']) {
2307 // Render "NEW [container]" selectorbox:
2308 if (is_array($value['el'])) {
2309 $opt=array();
2310 $opt[]='<option value=""></option>';
2311 foreach($value['el'] as $kk => $vv) {
2312 $opt[]='<option value="'.$kk.'">'.htmlspecialchars($this->getLL('l_new') . ' "'.$this->sL($value['el'][$kk]['tx_templavoila']['title']).'"').'</option>';
2313 }
2314 $rowCells['formEl']='<select name="flexFormsCmdData'.$formPrefix.'['.$key.'][value]">'.implode('',$opt).'</select>';
2315 }
2316
2317 // Put row together
2318 $tRows[]='<tr class="bgColor2">
2319 <td nowrap="nowrap" valign="top">'.$rowCells['title'].'</td>
2320 <td>'.$rowCells['formEl'].'</td>
2321 </tr>';
2322
2323 $cc=0;
2324 if (is_array($editData[$key]['el'])) {
2325 foreach ($editData[$key]['el'] as $k3 => $v3) {
2326 $cc=$k3;
2327 $theType = key($v3);
2328 $theDat = $v3[$theType];
2329 $newSectionEl = $value['el'][$theType];
2330 if (is_array($newSectionEl)) {
2331 $tRows = $this->getSingleField_typeFlex_draw(
2332 array($theType => $newSectionEl),
2333 array($theType => $theDat),
2334 $cmdData[$key]['el'][$cc],
2335 $table,
2336 $field,
2337 $row,
2338 $PA,
2339 $formPrefix.'['.$key.'][el]['.$cc.']',
2340 $level+1,
2341 $tRows
2342 );
2343 }
2344 }
2345 }
2346
2347
2348
2349 // New form?
2350 if ($cmdData[$key]['value']) {
2351 $newSectionEl = $value['el'][$cmdData[$key]['value']];
2352 if (is_array($newSectionEl)) {
2353 $tRows = $this->getSingleField_typeFlex_draw(
2354 array($cmdData[$key]['value'] => $newSectionEl),
2355 array(),
2356 array(),
2357 $table,
2358 $field,
2359 $row,
2360 $PA,
2361 $formPrefix.'['.$key.'][el]['.($cc+1).']',
2362 $level+1,
2363 $tRows
2364 );
2365 }
2366 }
2367 } else {
2368 $idTagPrefix = uniqid('id',true); // ID attributes are used for the move and delete checkboxes for referencing to them in the label tag (<label for="the form field id">) that's rendered around the icons
2369
2370 // Put row together
2371 $tRows[]='<tr class="bgColor2">
2372 <td nowrap="nowrap" valign="top">'.
2373 '<input name="_DELETE_FLEX_FORM'.$PA['itemFormElName'].$formPrefix.'" id="'.$idTagPrefix.'-del" type="checkbox"'.$this->insertDefStyle('check').' value="1" /><label for="'.$idTagPrefix.'-del"><img src="'.$this->backPath.'gfx/garbage.gif" border="0" alt="" /></label>'.
2374 '<input name="_MOVEUP_FLEX_FORM'.$PA['itemFormElName'].$formPrefix.'" id="'.$idTagPrefix.'-mvup" type="checkbox"'.$this->insertDefStyle('check').' value="1" /><label for="'.$idTagPrefix.'-mvup"><img src="'.$this->backPath.'gfx/button_up.gif" border="0" alt="" /></label>'.
2375 '<input name="_MOVEDOWN_FLEX_FORM'.$PA['itemFormElName'].$formPrefix.'" id="'.$idTagPrefix.'-mvdown" type="checkbox"'.$this->insertDefStyle('check').' value="1" /><label for="'.$idTagPrefix.'-mvdown"><img src="'.$this->backPath.'gfx/button_down.gif" border="0" alt="" /></label>'.
2376 $rowCells['title'].'</td>
2377 <td>'.$rowCells['formEl'].'</td>
2378 </tr>';
2379
2380 $tRows = $this->getSingleField_typeFlex_draw(
2381 $value['el'],
2382 $editData[$key]['el'],
2383 $cmdData[$key]['el'],
2384 $table,
2385 $field,
2386 $row,
2387 $PA,
2388 $formPrefix.'['.$key.'][el]',
2389 $level+1,
2390 $tRows
2391 );
2392 }
2393
2394 } elseif (is_array($value['TCEforms']['config'])) { // Rendering a single form element:
2395
2396 if (is_array($PA['_valLang'])) {
2397 $rotateLang = $PA['_valLang'];
2398 } else {
2399 $rotateLang = array($PA['_valLang']);
2400 }
2401
2402 foreach($rotateLang as $vDEFkey) {
2403 $vDEFkey = 'v'.$vDEFkey;
2404
2405 if (!$value['TCEforms']['displayCond'] || $this->isDisplayCondition($value['TCEforms']['displayCond'],$editData,$vDEFkey)) {
2406 $fakePA=array();
2407 $fakePA['fieldConf']=array(
2408 'label' => $this->sL(trim($value['TCEforms']['label'])),
2409 'config' => $value['TCEforms']['config'],
2410 'defaultExtras' => $value['TCEforms']['defaultExtras'],
2411 'onChange' => $value['TCEforms']['onChange']
2412 );
2413 if ($PA['_noEditDEF'] && $PA['_lang']==='lDEF') {
2414 $fakePA['fieldConf']['config'] = array(
2415 'type' => 'none',
2416 'rows' => 2
2417 );
2418 }
2419
2420 if (
2421 $fakePA['fieldConf']['onChange'] == 'reload' ||
2422 ($GLOBALS['TCA'][$table]['ctrl']['type'] && !strcmp($key,$GLOBALS['TCA'][$table]['ctrl']['type'])) ||
2423 ($GLOBALS['TCA'][$table]['ctrl']['requestUpdate'] && t3lib_div::inList($GLOBALS['TCA'][$table]['ctrl']['requestUpdate'],$key))) {
2424 if ($GLOBALS['BE_USER']->jsConfirmation(1)) {
2425 $alertMsgOnChange = 'if (confirm(TBE_EDITOR.labels.onChangeAlert) && TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };';
2426 } else {
2427 $alertMsgOnChange = 'if(TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm();}';
2428 }
2429 } else {
2430 $alertMsgOnChange = '';
2431 }
2432
2433 $fakePA['fieldChangeFunc']=$PA['fieldChangeFunc'];
2434 if (strlen($alertMsgOnChange)) {
2435 $fakePA['fieldChangeFunc']['alert']=$alertMsgOnChange;
2436 }
2437 $fakePA['onFocus']=$PA['onFocus'];
2438 $fakePA['label']=$PA['label'];
2439
2440 $fakePA['itemFormElName']=$PA['itemFormElName'].$formPrefix.'['.$key.']['.$vDEFkey.']';
2441 $fakePA['itemFormElName_file']=$PA['itemFormElName_file'].$formPrefix.'['.$key.']['.$vDEFkey.']';
2442
2443 if(isset($editData[$key][$vDEFkey])) {
2444 $fakePA['itemFormElValue']=$editData[$key][$vDEFkey];
2445 } else {
2446 $fakePA['itemFormElValue']=$fakePA['fieldConf']['config']['default'];
2447 }
2448
2449 $rowCells['formEl']= $this->getSingleField_SW($table,$field,$row,$fakePA);
2450 $rowCells['title']= htmlspecialchars($fakePA['fieldConf']['label']);
2451
2452 if (!in_array('DEF',$rotateLang)) {
2453 $defInfo = '<div class="typo3-TCEforms-originalLanguageValue">'.$this->getLanguageIcon($table,$row,0).$this->previewFieldValue($editData[$key]['vDEF'], $fakePA['fieldConf']).'&nbsp;</div>';
2454 } else {
2455 $defInfo = '';
2456 }
2457
2458 if (!$PA['_noEditDEF']) {
2459 $prLang = $this->getAdditionalPreviewLanguages();
2460 foreach($prLang as $prL) {
2461 $defInfo.= '<div class="typo3-TCEforms-originalLanguageValue">'.$this->getLanguageIcon($table,$row,'v'.$prL['ISOcode']).$this->previewFieldValue($editData[$key]['v'.$prL['ISOcode']], $fakePA['fieldConf']).'&nbsp;</div>';
2462 }
2463 }
2464
2465 // Put row together
2466 $tRows[]='<tr>
2467 <td nowrap="nowrap" valign="top" class="bgColor5">'.($vDEFkey=='vDEF' ? '' : $this->getLanguageIcon($table,$row,$vDEFkey)).$rowCells['title'].'</td>
2468 <td class="bgColor4">'.$rowCells['formEl'].$defInfo.'</td>
2469 </tr>';
2470 }
2471 }
2472 }
2473 }
2474 }
2475 }
2476
2477 return $tRows;
2478 }
2479
2480 /**
2481 * Handler for unknown types.
2482 *
2483 * @param string The table name of the record
2484 * @param string The field name which this element is supposed to edit
2485 * @param array The record data array where the value(s) for the field can be found
2486 * @param array An array with additional configuration options.
2487 * @return string The HTML code for the TCEform field
2488 */
2489 function getSingleField_typeUnknown($table,$field,$row,&$PA) {
2490 $item='Unknown type: '.$PA['fieldConf']['config']['form_type'].'<br />';
2491
2492 return $item;
2493 }
2494
2495 /**
2496 * User defined field type
2497 *
2498 * @param string The table name of the record
2499 * @param string The field name which this element is supposed to edit
2500 * @param array The record data array where the value(s) for the field can be found
2501 * @param array An array with additional configuration options.
2502 * @return string The HTML code for the TCEform field
2503 */
2504 function getSingleField_typeUser($table,$field,$row,&$PA) {
2505 $PA['table']=$table;
2506 $PA['field']=$field;
2507 $PA['row']=$row;
2508
2509 $PA['pObj']=&$this;
2510
2511 return t3lib_div::callUserFunction($PA['fieldConf']['config']['userFunc'],$PA,$this);
2512 }
2513
2514
2515
2516
2517
2518
2519 /************************************************************
2520 *
2521 * Field content processing
2522 *
2523 ************************************************************/
2524
2525 /**
2526 * Format field content of various types if $config['format'] is set to date, filesize, ..., user
2527 * This is primarily for the field type none but can be used for user field types for example
2528 *
2529 * @param array Configuration for the display
2530 * @param string The value to display
2531 * @return string Formatted Field content
2532 */
2533 function formatValue ($config, $itemValue) {
2534 $format = trim($config['format']);
2535 switch($format) {
2536 case 'date':
2537 if ($itemValue) {
2538 $option = trim($config['format.']['option']);
2539 if ($option) {
2540 if ($config['format.']['strftime']) {
2541 $value = strftime($option,$itemValue);
2542 } else {
2543 $value = date($option,$itemValue);
2544 }
2545 } else {
2546 $value = date('d-m-Y',$itemValue);
2547 }
2548 } else {
2549 $value = '';
2550 }
2551 if ($config['format.']['appendAge']) {
2552 $value .= ' ('.t3lib_BEfunc::calcAge((time()-$itemValue), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears')).')';
2553 }
2554 $itemValue = $value;
2555 break;
2556 case 'datetime': // compatibility with "eval" (type "input")
2557 $itemValue = date('H:i d-m-Y',$itemValue);
2558 break;
2559 case 'time': // compatibility with "eval" (type "input")
2560 $itemValue = date('H:i',$itemValue);
2561 break;
2562 case 'timesec': // compatibility with "eval" (type "input")
2563 $itemValue = date('H:i:s',$itemValue);
2564 break;
2565 case 'year': // compatibility with "eval" (type "input")
2566 $itemValue = date('Y',$itemValue);
2567 break;
2568 case 'int':
2569 $baseArr = array('dec'=>'d','hex'=>'x','HEX'=>'X','oct'=>'o','bin'=>'b');
2570 $base = trim($config['format.']['base']);
2571 $format = $baseArr[$base] ? $baseArr[$base] : 'd';
2572 $itemValue = sprintf('%'.$format,$itemValue);
2573 break;
2574 case 'float':
2575 $precision = t3lib_div::intInRange($config['format.']['precision'],1,10,2);
2576 $itemValue = sprintf('%.'.$precision.'f',$itemValue);
2577 break;
2578 case 'number':
2579 $format = trim($config['format.']['option']);
2580 $itemValue = sprintf('%'.$format,$itemValue);
2581 break;
2582 case 'md5':
2583 $itemValue = md5($itemValue);
2584 break;
2585 case 'filesize':
2586 $value = t3lib_div::formatSize(intval($itemValue));
2587 if ($config['format.']['appendByteSize']) {
2588 $value .= ' ('.$itemValue.')';
2589 }
2590 $itemValue = $value;
2591 break;
2592 case 'user':
2593 $func = trim($config['format.']['userFunc']);
2594 if ($func) {
2595 $params = array(
2596 'value' => $itemValue,
2597 'args' => $config['format.']['userFunc'],
2598 'config' => $config,
2599 'pObj' => &$this
2600 );
2601 $itemValue = t3lib_div::callUserFunction($func,$params,$this);
2602 }
2603 break;
2604 default:
2605 break;
2606 }
2607
2608 return $itemValue;
2609 }
2610
2611
2612
2613
2614
2615
2616 /************************************************************
2617 *
2618 * "Configuration" fetching/processing functions
2619 *
2620 ************************************************************/
2621
2622 /**
2623 * Calculate and return the current "types" pointer value for a record
2624 *
2625 * @param string The table name. MUST be in $TCA
2626 * @param array The row from the table, should contain at least the "type" field, if applicable.
2627 * @return string Return the "type" value for this record, ready to pick a "types" configuration from the $TCA array.
2628 */
2629 function getRTypeNum($table,$row) {
2630 global $TCA;
2631 // If there is a "type" field configured...
2632 if ($TCA[$table]['ctrl']['type']) {
2633 $typeFieldName = $TCA[$table]['ctrl']['type'];
2634 $typeNum=$row[$typeFieldName]; // Get value of the row from the record which contains the type value.
2635 if (!strcmp($typeNum,'')) $typeNum=0; // If that value is an empty string, set it to "0" (zero)
2636 } else {
2637 $typeNum = 0; // If no "type" field, then set to "0" (zero)
2638 }
2639
2640 $typeNum = (string)$typeNum; // Force to string. Necessary for eg '-1' to be recognized as a type value.
2641 if (!$TCA[$table]['types'][$typeNum]) { // However, if the type "0" is not found in the "types" array, then default to "1" (for historical reasons)
2642 $typeNum = 1;
2643 }
2644
2645 return $typeNum;
2646 }
2647
2648 /**
2649 * Used to adhoc-rearrange the field order normally set in the [types][showitem] list
2650 *
2651 * @param array A [types][showitem] list of fields, exploded by ","
2652 * @return array Returns rearranged version (keys are changed around as well.)
2653 * @see getMainFields()
2654 */
2655 function rearrange($fields) {
2656 $fO = array_flip(t3lib_div::trimExplode(',',$this->fieldOrder,1));
2657 reset($fields);
2658 $newFields=array();
2659 while(list($cc,$content)=each($fields)) {
2660 $cP = t3lib_div::trimExplode(';',$content);
2661 if (isset($fO[$cP[0]])) {
2662 $newFields[$fO[$cP[0]]] = $content;
2663 unset($fields[$cc]);
2664 }
2665 }
2666 ksort($newFields);
2667 $fields=array_merge($newFields,$fields); // Candidate for t3lib_div::array_merge() if integer-keys will some day make trouble...
2668 return $fields;
2669 }
2670
2671 /**
2672 * Producing an array of field names NOT to display in the form, based on settings from subtype_value_field, bitmask_excludelist_bits etc.
2673 * Notice, this list is in NO way related to the "excludeField" flag
2674 *
2675 * @param string Table name, MUST be in $TCA
2676 * @param array A record from table.
2677 * @param string A "type" pointer value, probably the one calculated based on the record array.
2678 * @return array Array with fieldnames as values. The fieldnames are those which should NOT be displayed "anyways"
2679 * @see getMainFields()
2680 */
2681 function getExcludeElements($table,$row,$typeNum) {
2682 global $TCA;
2683
2684 // Init:
2685 $excludeElements=array();
2686
2687 // If a subtype field is defined for the type
2688 if ($TCA[$table]['types'][$typeNum]['subtype_value_field']) {
2689 $sTfield = $TCA[$table]['types'][$typeNum]['subtype_value_field'];
2690 if (trim($TCA[$table]['types'][$typeNum]['subtypes_excludelist'][$row[$sTfield]])) {
2691 $excludeElements=t3lib_div::trimExplode(',',$TCA[$table]['types'][$typeNum]['subtypes_excludelist'][$row[$sTfield]],1);
2692 }
2693 }
2694
2695 // If a bitmask-value field has been configured, then find possible fields to exclude based on that:
2696 if ($TCA[$table]['types'][$typeNum]['bitmask_value_field']) {
2697 $sTfield = $TCA[$table]['types'][$typeNum]['bitmask_value_field'];
2698 $sTValue = t3lib_div::intInRange($row[$sTfield],0);
2699 if (is_array($TCA[$table]['types'][$typeNum]['bitmask_excludelist_bits'])) {
2700 reset($TCA[$table]['types'][$typeNum]['bitmask_excludelist_bits']);
2701 while(list($bitKey,$eList)=each($TCA[$table]['types'][$typeNum]['bitmask_excludelist_bits'])) {
2702 $bit=substr($bitKey,1);
2703 if (t3lib_div::testInt($bit)) {
2704 $bit = t3lib_div::intInRange($bit,0,30);
2705 if (
2706 (substr($bitKey,0,1)=='-' && !($sTValue&pow(2,$bit))) ||
2707 (substr($bitKey,0,1)=='+' && ($sTValue&pow(2,$bit)))
2708 ) {
2709 $excludeElements = array_merge($excludeElements,t3lib_div::trimExplode(',',$eList,1));
2710 }
2711 }
2712 }
2713 }