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