Feature #5690: TCEforms: add inline editing of secondary options (thanks to Martin...
[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 $part = $this->getSingleField($table,$theField,$row,$parts[1],1,'',$parts[2]);
743 if (is_array($part)) {
744 $palParts[] = $part;
745 }
746 }
747 }
748 }
749 }
750
751 // Put palette together if there are fields in it:
752 if (count($palParts)) {
753 if ($header) {
754 $out.= $this->intoTemplate(array(
755 'HEADER' => htmlspecialchars($header)
756 ),
757 $this->palFieldTemplateHeader
758 );
759 }
760 $collapsed = $this->isPalettesCollapsed($table,$palette);
761 $out.= $this->intoTemplate(array(
762 'PALETTE' => $this->wrapPaletteField($this->printPalette($palParts), $table, $row ,$palette, $collapsed)
763 ),
764 $this->palFieldTemplate
765 );
766 }
767
768 return $out;
769 }
770
771 /**
772 * Returns the form HTML code for a database table field.
773 *
774 * @param string The table name
775 * @param string The field name
776 * @param array The record to edit from the database table.
777 * @param string Alternative field name label to show.
778 * @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).
779 * @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.
780 * @param integer The palette pointer.
781 * @return mixed String (normal) or array (palettes)
782 */
783 function getSingleField($table,$field,$row,$altName='',$palette=0,$extra='',$pal=0) {
784 global $TCA,$BE_USER;
785
786 // Hook: getSingleField_preProcess
787 foreach ($this->hookObjectsSingleField as $hookObj) {
788 if (method_exists($hookObj,'getSingleField_preProcess')) {
789 $hookObj->getSingleField_preProcess($table, $field, $row, $altName, $palette, $extra, $pal, $this);
790 }
791 }
792
793 $out = '';
794 $PA = array();
795 $PA['altName'] = $altName;
796 $PA['palette'] = $palette;
797 $PA['extra'] = $extra;
798 $PA['pal'] = $pal;
799
800 // Make sure to load full $TCA array for the table:
801 t3lib_div::loadTCA($table);
802
803 // Get the TCA configuration for the current field:
804 $PA['fieldConf'] = $TCA[$table]['columns'][$field];
805 $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
806
807 $skipThisField = $this->inline->skipField($table, $field, $row, $PA['fieldConf']['config']);
808
809 // Now, check if this field is configured and editable (according to excludefields + other configuration)
810 if ( is_array($PA['fieldConf']) &&
811 !$skipThisField &&
812 (!$PA['fieldConf']['exclude'] || $BE_USER->check('non_exclude_fields',$table.':'.$field)) &&
813 $PA['fieldConf']['config']['form_type']!='passthrough' &&
814 ($this->RTEenabled || !$PA['fieldConf']['config']['showIfRTE']) &&
815 (!$PA['fieldConf']['displayCond'] || $this->isDisplayCondition($PA['fieldConf']['displayCond'],$row)) &&
816 (!$TCA[$table]['ctrl']['languageField'] || $PA['fieldConf']['l10n_display'] || strcmp($PA['fieldConf']['l10n_mode'],'exclude') || $row[$TCA[$table]['ctrl']['languageField']]<=0) &&
817 (!$TCA[$table]['ctrl']['languageField'] || !$this->localizationMode || $this->localizationMode===$PA['fieldConf']['l10n_cat'])
818 ) {
819
820
821
822 // Fetching the TSconfig for the current table/field. This includes the $row which means that
823 $PA['fieldTSConfig'] = $this->setTSconfig($table,$row,$field);
824
825 // If the field is NOT disabled from TSconfig (which it could have been) then render it
826 if (!$PA['fieldTSConfig']['disabled']) {
827 // Override fieldConf by fieldTSconfig:
828 $PA['fieldConf']['config'] = $this->overrideFieldConf($PA['fieldConf']['config'], $PA['fieldTSConfig']);
829
830 // Init variables:
831 $PA['itemFormElName']=$this->prependFormFieldNames.'['.$table.']['.$row['uid'].']['.$field.']'; // Form field name
832 $PA['itemFormElName_file']=$this->prependFormFieldNames_file.'['.$table.']['.$row['uid'].']['.$field.']'; // Form field name, in case of file uploads
833 $PA['itemFormElValue']=$row[$field]; // The value to show in the form field.
834 $PA['itemFormElID']=$this->prependFormFieldNames.'_'.$table.'_'.$row['uid'].'_'.$field;
835
836 // set field to read-only if configured for translated records to show default language content as readonly
837 if ($PA['fieldConf']['l10n_display'] AND t3lib_div::inList($PA['fieldConf']['l10n_display'], 'defaultAsReadonly') AND $row[$TCA[$table]['ctrl']['languageField']]) {
838 $PA['fieldConf']['config']['readOnly'] = true;
839 $PA['itemFormElValue'] = $this->defaultLanguageData[$table.':'.$row['uid']][$field];
840 }
841
842 // 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"
843 if (
844 ($TCA[$table]['ctrl']['type'] && !strcmp($field,$TCA[$table]['ctrl']['type'])) ||
845 ($TCA[$table]['ctrl']['requestUpdate'] && t3lib_div::inList($TCA[$table]['ctrl']['requestUpdate'],$field))) {
846 if($GLOBALS['BE_USER']->jsConfirmation(1)) {
847 $alertMsgOnChange = 'if (confirm(TBE_EDITOR.labels.onChangeAlert) && TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };';
848 } else {
849 $alertMsgOnChange = 'if (TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };';
850 }
851 } else {
852 $alertMsgOnChange = '';
853 }
854
855 // Render as a hidden field?
856 if (in_array($field,$this->hiddenFieldListArr)) {
857 $this->hiddenFieldAccum[]='<input type="hidden" name="'.$PA['itemFormElName'].'" value="'.htmlspecialchars($PA['itemFormElValue']).'" />';
858 } else { // Render as a normal field:
859
860 // 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.
861 if (!$PA['palette']) {
862 if ($PA['pal'] && $this->isPalettesCollapsed($table,$PA['pal'])) {
863 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);
864 } else {
865 $thePalIcon = '';
866 $palJSfunc = '';
867 }
868 }
869 // onFocus attribute to add to the field:
870 $PA['onFocus'] = ($palJSfunc && !$BE_USER->uc['dontShowPalettesOnFocusInAB']) ? ' onfocus="'.htmlspecialchars($palJSfunc).'"' : '';
871
872 // Find item
873 $item='';
874 $PA['label'] = $PA['altName'] ? $PA['altName'] : $PA['fieldConf']['label'];
875 $PA['label'] = $this->sL($PA['label']);
876 // JavaScript code for event handlers:
877 $PA['fieldChangeFunc']=array();
878 $PA['fieldChangeFunc']['TBE_EDITOR_fieldChanged'] = "TBE_EDITOR.fieldChanged('".$table."','".$row['uid']."','".$field."','".$PA['itemFormElName']."');";
879 $PA['fieldChangeFunc']['alert']=$alertMsgOnChange;
880 // if this is the child of an inline type and it is the field creating the label
881 if ($this->inline->isInlineChildAndLabelField($table, $field)) {
882 $PA['fieldChangeFunc']['inline'] = "inline.handleChangedField('".$PA['itemFormElName']."','".$this->inline->inlineNames['object']."[$table][".$row['uid']."]');";
883 }
884
885 // Based on the type of the item, call a render function:
886 $item = $this->getSingleField_SW($table,$field,$row,$PA);
887
888 // Add language + diff
889 if ($PA['fieldConf']['l10n_display'] && (t3lib_div::inList($PA['fieldConf']['l10n_display'], 'hideDiff') || t3lib_div::inList($PA['fieldConf']['l10n_display'], 'defaultAsReadonly'))) {
890 $renderLanguageDiff = false;
891 } else {
892 $renderLanguageDiff = true;
893 }
894
895 if ($renderLanguageDiff) {
896 $item = $this->renderDefaultLanguageContent($table,$field,$row,$item);
897 $item = $this->renderDefaultLanguageDiff($table,$field,$row,$item);
898 }
899
900 // 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
901 $PA['label'] = t3lib_div::deHSCentities(htmlspecialchars($PA['label']));
902 if (t3lib_div::testInt($row['uid']) && $PA['fieldTSConfig']['linkTitleToSelf'] && !t3lib_div::_GP('columnsOnly')) {
903 $lTTS_url = $this->backPath.'alt_doc.php?edit['.$table.']['.$row['uid'].']=edit&columnsOnly='.$field.'&returnUrl='.rawurlencode($this->thisReturnUrl());
904 $PA['label'] = '<a href="'.htmlspecialchars($lTTS_url).'">'.$PA['label'].'</a>';
905 }
906
907 // Create output value:
908 if ($PA['fieldConf']['config']['form_type']=='user' && $PA['fieldConf']['config']['noTableWrapping']) {
909 $out = $item;
910 } elseif ($PA['palette']) {
911 // Array:
912 $out=array(
913 'NAME'=>$PA['label'],
914 'ID'=>$row['uid'],
915 'FIELD'=>$field,
916 'TABLE'=>$table,
917 'ITEM'=>$item,
918 'HELP_ICON' => $this->helpTextIcon($table,$field,1)
919 );
920 $out = $this->addUserTemplateMarkers($out,$table,$field,$row,$PA);
921 } else {
922 // String:
923 $out=array(
924 'NAME'=>$PA['label'],
925 'ITEM'=>$item,
926 'TABLE'=>$table,
927 'ID'=>$row['uid'],
928 'HELP_ICON'=>$this->helpTextIcon($table,$field),
929 'HELP_TEXT'=>$this->helpText($table,$field),
930 'PAL_LINK_ICON'=>$thePalIcon,
931 'FIELD'=>$field
932 );
933 $out = $this->addUserTemplateMarkers($out,$table,$field,$row,$PA);
934 // String:
935 $out=$this->intoTemplate($out);
936 }
937 }
938 } else $this->commentMessages[]=$this->prependFormFieldNames.'['.$table.']['.$row['uid'].']['.$field.']: Disabled by TSconfig';
939 }
940 // Hook: getSingleField_postProcess
941 foreach ($this->hookObjectsSingleField as $hookObj) {
942 if (method_exists($hookObj,'getSingleField_postProcess')) {
943 $hookObj->getSingleField_postProcess($table, $field, $row, $out, $PA, $this);
944 }
945 }
946 // Return value (string or array)
947 return $out;
948 }
949
950 /**
951 * Rendering a single item for the form
952 *
953 * @param string Table name of record
954 * @param string Fieldname to render
955 * @param array The record
956 * @param array parameters array containing a lot of stuff. Value by Reference!
957 * @return string Returns the item as HTML code to insert
958 * @access private
959 * @see getSingleField(), getSingleField_typeFlex_draw()
960 */
961 function getSingleField_SW($table,$field,$row,&$PA) {
962 $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
963
964 switch($PA['fieldConf']['config']['form_type']) {
965 case 'input':
966 $item = $this->getSingleField_typeInput($table,$field,$row,$PA);
967 break;
968 case 'text':
969 $item = $this->getSingleField_typeText($table,$field,$row,$PA);
970 break;
971 case 'check':
972 $item = $this->getSingleField_typeCheck($table,$field,$row,$PA);
973 break;
974 case 'radio':
975 $item = $this->getSingleField_typeRadio($table,$field,$row,$PA);
976 break;
977 case 'select':
978 $item = $this->getSingleField_typeSelect($table,$field,$row,$PA);
979 break;
980 case 'group':
981 $item = $this->getSingleField_typeGroup($table,$field,$row,$PA);
982 break;
983 case 'inline':
984 $item = $this->inline->getSingleField_typeInline($table,$field,$row,$PA);
985 break;
986 case 'none':
987 $item = $this->getSingleField_typeNone($table,$field,$row,$PA);
988 break;
989 case 'user':
990 $item = $this->getSingleField_typeUser($table,$field,$row,$PA);
991 break;
992 case 'flex':
993 $item = $this->getSingleField_typeFlex($table,$field,$row,$PA);
994 break;
995 default:
996 $item = $this->getSingleField_typeUnknown($table,$field,$row,$PA);
997 break;
998 }
999
1000 return $item;
1001 }
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021 /**********************************************************
1022 *
1023 * Rendering of each TCEform field type
1024 *
1025 ************************************************************/
1026
1027 /**
1028 * Generation of TCEform elements of the type "input"
1029 * This will render a single-line input form field, possibly with various control/validation features
1030 *
1031 * @param string The table name of the record
1032 * @param string The field name which this element is supposed to edit
1033 * @param array The record data array where the value(s) for the field can be found
1034 * @param array An array with additional configuration options.
1035 * @return string The HTML code for the TCEform field
1036 */
1037 function getSingleField_typeInput($table,$field,$row,&$PA) {
1038 // typo3FormFieldSet(theField, evallist, is_in, checkbox, checkboxValue)
1039 // typo3FormFieldGet(theField, evallist, is_in, checkbox, checkboxValue, checkbox_off)
1040
1041 $config = $PA['fieldConf']['config'];
1042
1043 # $specConf = $this->getSpecConfForField($table,$row,$field);
1044 $specConf = $this->getSpecConfFromString($PA['extra'], $PA['fieldConf']['defaultExtras']);
1045 $size = t3lib_div::intInRange($config['size']?$config['size']:30,5,$this->maxInputWidth);
1046 $evalList = t3lib_div::trimExplode(',',$config['eval'],1);
1047
1048
1049 if($this->renderReadonly || $config['readOnly']) {
1050 $itemFormElValue = $PA['itemFormElValue'];
1051 if (in_array('date',$evalList)) {
1052 $config['format'] = 'date';
1053 } elseif (in_array('date',$evalList)) {
1054 $config['format'] = 'date';
1055 } elseif (in_array('datetime',$evalList)) {
1056 $config['format'] = 'datetime';
1057 } elseif (in_array('time',$evalList)) {
1058 $config['format'] = 'time';
1059 }
1060 if (in_array('password',$evalList)) {
1061 $itemFormElValue = $itemFormElValue ? '*********' : '';
1062 }
1063 return $this->getSingleField_typeNone_render($config, $itemFormElValue);
1064 }
1065
1066 foreach ($evalList as $func) {
1067 switch ($func) {
1068 case 'required':
1069 $this->requiredFields[$table.'_'.$row['uid'].'_'.$field]=$PA['itemFormElName'];
1070 break;
1071 default:
1072 if (substr($func, 0, 3) == 'tx_') {
1073 // Pair hook to the one in t3lib_TCEmain::checkValue_input_Eval()
1074 $evalObj = t3lib_div::getUserObj($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tce']['formevals'][$func].':&'.$func);
1075 if (is_object($evalObj) && method_exists($evalObj, 'deevaluateFieldValue')) {
1076 $_params = array(
1077 'value' => $PA['itemFormElValue']
1078 );
1079 $PA['itemFormElValue'] = $evalObj->deevaluateFieldValue($_params);
1080 }
1081 }
1082 break;
1083 }
1084 }
1085
1086 $paramsList = "'".$PA['itemFormElName']."','".implode(',',$evalList)."','".trim($config['is_in'])."',".(isset($config['checkbox'])?1:0).",'".$config['checkbox']."'";
1087 if (isset($config['checkbox'])) {
1088 // Setting default "click-checkbox" values for eval types "date" and "datetime":
1089 $thisMidnight = mktime(0,0,0);
1090 $checkSetValue = in_array('date',$evalList) ? $thisMidnight : '';
1091 $checkSetValue = in_array('datetime',$evalList) ? time() : $checkSetValue;
1092
1093 $cOnClick = 'typo3form.fieldGet('.$paramsList.',1,\''.$checkSetValue.'\');'.implode('',$PA['fieldChangeFunc']);
1094 $item.='<input type="checkbox"'.$this->insertDefStyle('check').' name="'.$PA['itemFormElName'].'_cb" onclick="'.htmlspecialchars($cOnClick).'" />';
1095 }
1096
1097 $PA['fieldChangeFunc'] = array_merge(array('typo3form.fieldGet'=>'typo3form.fieldGet('.$paramsList.');'), $PA['fieldChangeFunc']);
1098 $mLgd = ($config['max']?$config['max']:256);
1099 $iOnChange = implode('',$PA['fieldChangeFunc']);
1100 $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.
1101 $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.
1102 $this->extJSCODE.='typo3form.fieldSet('.$paramsList.');';
1103
1104 // going through all custom evaluations configured for this field
1105 foreach ($evalList as $evalData) {
1106 if (substr($evalData, 0, 3) == 'tx_') {
1107 $evalObj = t3lib_div::getUserObj($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tce']['formevals'][$evalData].':&'.$evalData);
1108 if(is_object($evalObj) && method_exists($evalObj, 'returnFieldJS')) {
1109 $this->extJSCODE .= "\n\nfunction ".$evalData."(value) {\n".$evalObj->returnFieldJS()."\n}\n";
1110 }
1111 }
1112 }
1113
1114 // Creating an alternative item without the JavaScript handlers.
1115 $altItem = '<input type="hidden" name="'.$PA['itemFormElName'].'_hr" value="" />';
1116 $altItem.= '<input type="hidden" name="'.$PA['itemFormElName'].'" value="'.htmlspecialchars($PA['itemFormElValue']).'" />';
1117
1118 // Wrap a wizard around the item?
1119 $item= $this->renderWizards(array($item,$altItem),$config['wizards'],$table,$row,$field,$PA,$PA['itemFormElName'].'_hr',$specConf);
1120
1121 return $item;
1122 }
1123
1124 /**
1125 * Generation of TCEform elements of the type "text"
1126 * This will render a <textarea> OR RTE area form field, possibly with various control/validation features
1127 *
1128 * @param string The table name of the record
1129 * @param string The field name which this element is supposed to edit
1130 * @param array The record data array where the value(s) for the field can be found
1131 * @param array An array with additional configuration options.
1132 * @return string The HTML code for the TCEform field
1133 */
1134 function getSingleField_typeText($table,$field,$row,&$PA) {
1135
1136 // Init config:
1137 $config = $PA['fieldConf']['config'];
1138
1139 if($this->renderReadonly || $config['readOnly']) {
1140 return $this->getSingleField_typeNone_render($config, $PA['itemFormElValue']);
1141 }
1142
1143 // Setting columns number:
1144 $cols = t3lib_div::intInRange($config['cols'] ? $config['cols'] : 30, 5, $this->maxTextareaWidth);
1145
1146 // Setting number of rows:
1147 $origRows = $rows = t3lib_div::intInRange($config['rows'] ? $config['rows'] : 5, 1, 20);
1148 if (strlen($PA['itemFormElValue']) > $this->charsPerRow*2) {
1149 $cols = $this->maxTextareaWidth;
1150 $rows = t3lib_div::intInRange(round(strlen($PA['itemFormElValue'])/$this->charsPerRow), count(explode(chr(10),$PA['itemFormElValue'])), 20);
1151 if ($rows<$origRows) $rows = $origRows;
1152 }
1153
1154 // Init RTE vars:
1155 $RTEwasLoaded = 0; // Set true, if the RTE is loaded; If not a normal textarea is shown.
1156 $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...
1157
1158 // "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist. Traditionally, this is where RTE configuration has been found.
1159 $specConf = $this->getSpecConfFromString($PA['extra'], $PA['fieldConf']['defaultExtras']);
1160
1161 // Setting up the altItem form field, which is a hidden field containing the value
1162 $altItem = '<input type="hidden" name="'.htmlspecialchars($PA['itemFormElName']).'" value="'.htmlspecialchars($PA['itemFormElValue']).'" />';
1163
1164 // If RTE is generally enabled (TYPO3_CONF_VARS and user settings)
1165 if ($this->RTEenabled) {
1166 $p = t3lib_BEfunc::getSpecConfParametersFromArray($specConf['rte_transform']['parameters']);
1167 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.
1168 t3lib_BEfunc::fixVersioningPid($table,$row);
1169 list($tscPID,$thePidValue) = $this->getTSCpid($table,$row['uid'],$row['pid']);
1170
1171 // If the pid-value is not negative (that is, a pid could NOT be fetched)
1172 if ($thePidValue >= 0) {
1173 $RTEsetup = $GLOBALS['BE_USER']->getTSConfig('RTE',t3lib_BEfunc::getPagesTSconfig($tscPID));
1174 $RTEtypeVal = t3lib_BEfunc::getTCAtypeValue($table,$row);
1175 $thisConfig = t3lib_BEfunc::RTEsetup($RTEsetup['properties'],$table,$field,$RTEtypeVal);
1176
1177 if (!$thisConfig['disabled']) {
1178 if (!$this->disableRTE) {
1179 $this->RTEcounter++;
1180
1181 // Find alternative relative path for RTE images/links:
1182 $eFile = t3lib_parsehtml_proc::evalWriteFile($specConf['static_write'], $row);
1183 $RTErelPath = is_array($eFile) ? dirname($eFile['relEditFile']) : '';
1184
1185 // Get RTE object, draw form and set flag:
1186 $RTEobj = &t3lib_BEfunc::RTEgetObj();
1187 $item = $RTEobj->drawRTE($this,$table,$field,$row,$PA,$specConf,$thisConfig,$RTEtypeVal,$RTErelPath,$thePidValue);
1188
1189 // Wizard:
1190 $item = $this->renderWizards(array($item,$altItem),$config['wizards'],$table,$row,$field,$PA,$PA['itemFormElName'],$specConf,1);
1191
1192 $RTEwasLoaded = 1;
1193 } else {
1194 $RTEwouldHaveBeenLoaded = 1;
1195 $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!)';
1196 }
1197 } else $this->commentMessages[] = $PA['itemFormElName'].': RTE is disabled by the Page TSconfig, "RTE"-key (eg. by RTE.default.disabled=0 or such)';
1198 } else $this->commentMessages[] = $PA['itemFormElName'].': PID value could NOT be fetched. Rare error, normally with new records.';
1199 } else {
1200 if (!isset($specConf['richtext'])) $this->commentMessages[] = $PA['itemFormElName'].': RTE was not configured for this field in TCA-types';
1201 if (!(!$p['flag'] || !$row[$p['flag']])) $this->commentMessages[] = $PA['itemFormElName'].': Field-flag ('.$PA['flag'].') has been set to disable RTE!';
1202 }
1203 }
1204
1205 // Display ordinary field if RTE was not loaded.
1206 if (!$RTEwasLoaded) {
1207 if ($specConf['rte_only']) { // Show message, if no RTE (field can only be edited with RTE!)
1208 $item = '<p><em>'.htmlspecialchars($this->getLL('l_noRTEfound')).'</em></p>';
1209 } else {
1210 if ($specConf['nowrap']) {
1211 $wrap = 'off';
1212 } else {
1213 $wrap = ($config['wrap'] ? $config['wrap'] : 'virtual');
1214 }
1215
1216 $classes = array();
1217 if ($specConf['fixed-font']) { $classes[] = 'fixed-font'; }
1218 if ($specConf['enable-tab']) { $classes[] = 'enable-tab'; }
1219
1220 $formWidthText = $this->formWidthText($cols,$wrap);
1221
1222 // Extract class attributes from $formWidthText (otherwise it would be added twice to the output)
1223 $res = array();
1224 if (preg_match('/ class="(.+?)"/',$formWidthText,$res)) {
1225 $formWidthText = str_replace(' class="'.$res[1].'"','',$formWidthText);
1226 $classes = array_merge($classes, explode(' ',$res[1]));
1227 }
1228
1229 if (count($classes)) {
1230 $class = ' class="'.implode(' ',$classes).'"';
1231 } else $class='';
1232
1233 $iOnChange = implode('',$PA['fieldChangeFunc']);
1234 $item.= '
1235 <textarea name="'.$PA['itemFormElName'].'"'.$formWidthText.$class.' rows="'.$rows.'" wrap="'.$wrap.'" onchange="'.htmlspecialchars($iOnChange).'"'.$PA['onFocus'].'>'.
1236 t3lib_div::formatForTextarea($PA['itemFormElValue']).
1237 '</textarea>';
1238 $item = $this->renderWizards(array($item,$altItem),$config['wizards'],$table,$row,$field,$PA,$PA['itemFormElName'],$specConf,$RTEwouldHaveBeenLoaded);
1239 }
1240 }
1241
1242 // Return field HTML:
1243 return $item;
1244 }
1245
1246 /**
1247 * Generation of TCEform elements of the type "check"
1248 * This will render a check-box OR an array of checkboxes
1249 *
1250 * @param string The table name of the record
1251 * @param string The field name which this element is supposed to edit
1252 * @param array The record data array where the value(s) for the field can be found
1253 * @param array An array with additional configuration options.
1254 * @return string The HTML code for the TCEform field
1255 */
1256 function getSingleField_typeCheck($table,$field,$row,&$PA) {
1257 $config = $PA['fieldConf']['config'];
1258
1259 $disabled = '';
1260 if($this->renderReadonly || $config['readOnly']) {
1261 $disabled = ' disabled="disabled"';
1262 }
1263
1264 // Traversing the array of items:
1265 $selItems = $this->initItemArray($PA['fieldConf']);
1266 if ($config['itemsProcFunc']) $selItems = $this->procItems($selItems,$PA['fieldTSConfig']['itemsProcFunc.'],$config,$table,$row,$field);
1267
1268 if (!count($selItems)) {
1269 $selItems[]=array('','');
1270 }
1271 $thisValue = intval($PA['itemFormElValue']);
1272
1273 $cols = intval($config['cols']);
1274 if ($cols > 1) {
1275 $item.= '<table border="0" cellspacing="0" cellpadding="0" class="typo3-TCEforms-checkboxArray">';
1276 for ($c=0;$c<count($selItems);$c++) {
1277 $p = $selItems[$c];
1278 if(!($c%$cols)) { $item.='<tr>'; }
1279 $cBP = $this->checkBoxParams($PA['itemFormElName'],$thisValue,$c,count($selItems),implode('',$PA['fieldChangeFunc']));
1280 $cBName = $PA['itemFormElName'].'_'.$c;
1281 $cBID = $PA['itemFormElID'].'_'.$c;
1282 $item.= '<td nowrap="nowrap">'.
1283 '<input type="checkbox"'.$this->insertDefStyle('check').' value="1" name="'.$cBName.'"'.$cBP.$disabled.' id="'.$cBID.'" />'.
1284 $this->wrapLabels('<label for="'.$cBID.'">'.htmlspecialchars($p[0]).'</label>&nbsp;').
1285 '</td>';
1286 if(($c%$cols)+1==$cols) {$item.='</tr>';}
1287 }
1288 if ($c%$cols) {
1289 $rest=$cols-($c%$cols);
1290 for ($c=0;$c<$rest;$c++) {
1291 $item.= '<td></td>';
1292 }
1293 if ($c>0) { $item.= '</tr>'; }
1294 }
1295 $item.= '</table>';
1296 } else {
1297 for ($c=0;$c<count($selItems);$c++) {
1298 $p = $selItems[$c];
1299 $cBP = $this->checkBoxParams($PA['itemFormElName'],$thisValue,$c,count($selItems),implode('',$PA['fieldChangeFunc']));
1300 $cBName = $PA['itemFormElName'].'_'.$c;
1301 $cBID = $PA['itemFormElID'].'_'.$c;
1302 $item.= ($c>0?'<br />':'').
1303 '<input type="checkbox"'.$this->insertDefStyle('check').' value="1" name="'.$cBName.'"'.$cBP.$PA['onFocus'].$disabled.' id="'.$cBID.'" />'.
1304 htmlspecialchars($p[0]);
1305 }
1306 }
1307 if (!$disabled) {
1308 $item.= '<input type="hidden" name="'.$PA['itemFormElName'].'" value="'.htmlspecialchars($thisValue).'" />';
1309 }
1310
1311 return $item;
1312 }
1313
1314 /**
1315 * Generation of TCEform elements of the type "radio"
1316 * This will render a series of radio buttons.
1317 *
1318 * @param string The table name of the record
1319 * @param string The field name which this element is supposed to edit
1320 * @param array The record data array where the value(s) for the field can be found
1321 * @param array An array with additional configuration options.
1322 * @return string The HTML code for the TCEform field
1323 */
1324 function getSingleField_typeRadio($table,$field,$row,&$PA) {
1325 $config = $PA['fieldConf']['config'];
1326
1327 $disabled = '';
1328 if($this->renderReadonly || $config['readOnly']) {
1329 $disabled = ' disabled="disabled"';
1330 }
1331
1332 // Get items for the array:
1333 $selItems = $this->initItemArray($PA['fieldConf']);
1334 if ($config['itemsProcFunc']) $selItems = $this->procItems($selItems,$PA['fieldTSConfig']['itemsProcFunc.'],$config,$table,$row,$field);
1335
1336 // Traverse the items, making the form elements:
1337 for ($c=0;$c<count($selItems);$c++) {
1338 $p = $selItems[$c];
1339 $rID = $PA['itemFormElID'].'_'.$c;
1340 $rOnClick = implode('',$PA['fieldChangeFunc']);
1341 $rChecked = (!strcmp($p[1],$PA['itemFormElValue'])?' checked="checked"':'');
1342 $item.= '<input type="radio"'.$this->insertDefStyle('radio').' name="'.$PA['itemFormElName'].'" value="'.htmlspecialchars($p[1]).'" onclick="'.htmlspecialchars($rOnClick).'"'.$rChecked.$PA['onFocus'].$disabled.' id="'.$rID.'" />
1343 <label for="'.$rID.'">'.htmlspecialchars($p[0]).'</label>
1344 <br />';
1345 }
1346
1347 return $item;
1348 }
1349
1350 /**
1351 * Generation of TCEform elements of the type "select"
1352 * This will render a selector box element, or possibly a special construction with two selector boxes. That depends on configuration.
1353 *
1354 * @param string The table name of the record
1355 * @param string The field name which this element is supposed to edit
1356 * @param array The record data array where the value(s) for the field can be found
1357 * @param array An array with additional configuration options.
1358 * @return string The HTML code for the TCEform field
1359 */
1360 function getSingleField_typeSelect($table,$field,$row,&$PA) {
1361 global $TCA;
1362
1363 // Field configuration from TCA:
1364 $config = $PA['fieldConf']['config'];
1365
1366 $disabled = '';
1367 if($this->renderReadonly || $config['readOnly']) {
1368 $disabled = ' disabled="disabled"';
1369 }
1370
1371 // "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/.
1372 $specConf = $this->getSpecConfFromString($PA['extra'], $PA['fieldConf']['defaultExtras']);
1373
1374 // Getting the selector box items from the system
1375 $selItems = $this->addSelectOptionsToItemArray($this->initItemArray($PA['fieldConf']),$PA['fieldConf'],$this->setTSconfig($table,$row),$field);
1376 $selItems = $this->addItems($selItems,$PA['fieldTSConfig']['addItems.']);
1377 if ($config['itemsProcFunc']) $selItems = $this->procItems($selItems,$PA['fieldTSConfig']['itemsProcFunc.'],$config,$table,$row,$field);
1378
1379 // Possibly remove some items:
1380 $removeItems = t3lib_div::trimExplode(',',$PA['fieldTSConfig']['removeItems'],1);
1381 foreach($selItems as $tk => $p) {
1382
1383 // Checking languages and authMode:
1384 $languageDeny = $TCA[$table]['ctrl']['languageField'] && !strcmp($TCA[$table]['ctrl']['languageField'], $field) && !$GLOBALS['BE_USER']->checkLanguageAccess($p[1]);
1385 $authModeDeny = $config['form_type']=='select' && $config['authMode'] && !$GLOBALS['BE_USER']->checkAuthMode($table,$field,$p[1],$config['authMode']);
1386 if (in_array($p[1],$removeItems) || $languageDeny || $authModeDeny) {
1387 unset($selItems[$tk]);
1388 } elseif (isset($PA['fieldTSConfig']['altLabels.'][$p[1]])) {
1389 $selItems[$tk][0]=$this->sL($PA['fieldTSConfig']['altLabels.'][$p[1]]);
1390 }
1391
1392 // Removing doktypes with no access:
1393 if ($table.'.'.$field == 'pages.doktype') {
1394 if (!($GLOBALS['BE_USER']->isAdmin() || t3lib_div::inList($GLOBALS['BE_USER']->groupData['pagetypes_select'],$p[1]))) {
1395 unset($selItems[$tk]);
1396 }
1397 }
1398 }
1399
1400 // Creating the label for the "No Matching Value" entry.
1401 $nMV_label = isset($PA['fieldTSConfig']['noMatchingValue_label']) ? $this->sL($PA['fieldTSConfig']['noMatchingValue_label']) : '[ '.$this->getLL('l_noMatchingValue').' ]';
1402
1403 // Prepare some values:
1404 $maxitems = intval($config['maxitems']);
1405
1406 // If a SINGLE selector box...
1407 if ($maxitems<=1) {
1408 $item = $this->getSingleField_typeSelect_single($table,$field,$row,$PA,$config,$selItems,$nMV_label);
1409 } elseif (!strcmp($config['renderMode'],'checkbox')) { // Checkbox renderMode
1410 $item = $this->getSingleField_typeSelect_checkbox($table,$field,$row,$PA,$config,$selItems,$nMV_label);
1411 } elseif (!strcmp($config['renderMode'],'singlebox')) { // Single selector box renderMode
1412 $item = $this->getSingleField_typeSelect_singlebox($table,$field,$row,$PA,$config,$selItems,$nMV_label);
1413 } else { // Traditional multiple selector box:
1414 $item = $this->getSingleField_typeSelect_multiple($table,$field,$row,$PA,$config,$selItems,$nMV_label);
1415 }
1416
1417 // Wizards:
1418 if (!$disabled) {
1419 $altItem = '<input type="hidden" name="'.$PA['itemFormElName'].'" value="'.htmlspecialchars($PA['itemFormElValue']).'" />';
1420 $item = $this->renderWizards(array($item,$altItem),$config['wizards'],$table,$row,$field,$PA,$PA['itemFormElName'],$specConf);
1421 }
1422
1423 return $item;
1424 }
1425
1426 /**
1427 * Creates a single-selector box
1428 * (Render function for getSingleField_typeSelect())
1429 *
1430 * @param string See getSingleField_typeSelect()
1431 * @param string See getSingleField_typeSelect()
1432 * @param array See getSingleField_typeSelect()
1433 * @param array See getSingleField_typeSelect()
1434 * @param array (Redundant) content of $PA['fieldConf']['config'] (for convenience)
1435 * @param array Items available for selection
1436 * @param string Label for no-matching-value
1437 * @return string The HTML code for the item
1438 * @see getSingleField_typeSelect()
1439 */
1440 function getSingleField_typeSelect_single($table,$field,$row,&$PA,$config,$selItems,$nMV_label) {
1441 // check against inline uniqueness
1442 $inlineParent = $this->inline->getStructureLevel(-1);
1443 if(is_array($inlineParent) && $inlineParent['uid']) {
1444 if ($inlineParent['config']['foreign_table'] == $table && $inlineParent['config']['foreign_unique'] == $field) {
1445 $uniqueIds = $this->inline->inlineData['unique'][$this->inline->inlineNames['object'].'['.$table.']']['used'];
1446 $PA['fieldChangeFunc']['inlineUnique'] = "inline.updateUnique(this,'".$this->inline->inlineNames['object'].'['.$table."]','".$this->inline->inlineNames['form']."','".$row['uid']."');";
1447 }
1448 // hide uid of parent record for symmetric relations
1449 if ($inlineParent['config']['foreign_table'] == $table && ($inlineParent['config']['foreign_field'] == $field || $inlineParent['config']['symmetric_field'] == $field)) {
1450 $uniqueIds[] = $inlineParent['uid'];
1451 }
1452 }
1453
1454 // Initialization:
1455 $c = 0;
1456 $sI = 0;
1457 $noMatchingValue = 1;
1458 $opt = array();
1459 $selicons = array();
1460 $onlySelectedIconShown = 0;
1461 $size = intval($config['size']);
1462
1463 $disabled = '';
1464 if($this->renderReadonly || $config['readOnly']) {
1465 $disabled = ' disabled="disabled"';
1466 $onlySelectedIconShown = 1;
1467 }
1468
1469 // Icon configuration:
1470 if ($config['suppress_icons']=='IF_VALUE_FALSE') {
1471 $suppressIcons = !$PA['itemFormElValue'] ? 1 : 0;
1472 } elseif ($config['suppress_icons']=='ONLY_SELECTED') {
1473 $suppressIcons=0;
1474 $onlySelectedIconShown=1;
1475 } elseif ($config['suppress_icons']) {
1476 $suppressIcons = 1;
1477 } else $suppressIcons = 0;
1478
1479 // Traverse the Array of selector box items:
1480 foreach($selItems as $p) {
1481 $sM = (!strcmp($PA['itemFormElValue'],$p[1])?' selected="selected"':'');
1482 if ($sM) {
1483 $sI = $c;
1484 $noMatchingValue = 0;
1485 }
1486
1487 // Getting style attribute value (for icons):
1488 if ($config['iconsInOptionTags']) {
1489 $styleAttrValue = $this->optionTagStyle($p[2]);
1490 }
1491
1492 // Compiling the <option> tag:
1493 if (!($p[1] != $PA['itemFormElValue'] && is_array($uniqueIds) && in_array($p[1], $uniqueIds))) {
1494 $opt[]= '<option value="'.htmlspecialchars($p[1]).'"'.
1495 $sM.
1496 ($styleAttrValue ? ' style="'.htmlspecialchars($styleAttrValue).'"' : '').
1497 (!strcmp($p[1],'--div--') ? ' class="c-divider"' : '').
1498 '>'.t3lib_div::deHSCentities(htmlspecialchars($p[0])).'</option>';
1499 }
1500
1501 // If there is an icon for the selector box (rendered in table under)...:
1502 if ($p[2] && !$suppressIcons && (!$onlySelectedIconShown || $sM)) {
1503 list($selIconFile,$selIconInfo)=$this->getIcon($p[2]);
1504 $iOnClick = $this->elName($PA['itemFormElName']).'.selectedIndex='.$c.'; '.implode('',$PA['fieldChangeFunc']).$this->blur().'return false;';
1505 $selicons[]=array(
1506 (!$onlySelectedIconShown ? '<a href="#" onclick="'.htmlspecialchars($iOnClick).'">' : '').
1507 '<img src="'.$selIconFile.'" '.$selIconInfo[3].' vspace="2" border="0" title="'.htmlspecialchars($p[0]).'" alt="'.htmlspecialchars($p[0]).'" />'.
1508 (!$onlySelectedIconShown ? '</a>' : ''),
1509 $c,$sM);
1510 }
1511 $c++;
1512 }
1513
1514 // No-matching-value:
1515 if ($PA['itemFormElValue'] && $noMatchingValue && !$PA['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) {
1516 $nMV_label = @sprintf($nMV_label, $PA['itemFormElValue']);
1517 $opt[]= '<option value="'.htmlspecialchars($PA['itemFormElValue']).'" selected="selected">'.htmlspecialchars($nMV_label).'</option>';
1518 }
1519
1520 // Create item form fields:
1521 $sOnChange = 'if (this.options[this.selectedIndex].value==\'--div--\') {this.selectedIndex='.$sI.';} '.implode('',$PA['fieldChangeFunc']);
1522 if(!$disabled) {
1523 $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...
1524 }
1525 $item.= '<select name="'.$PA['itemFormElName'].'"'.
1526 $this->insertDefStyle('select').
1527 ($size?' size="'.$size.'"':'').
1528 ' onchange="'.htmlspecialchars($sOnChange).'"'.
1529 $PA['onFocus'].$disabled.'>';
1530 $item.= implode('',$opt);
1531 $item.= '</select>';
1532
1533 // Create icon table:
1534 if (count($selicons)) {
1535 $item.='<table border="0" cellpadding="0" cellspacing="0" class="typo3-TCEforms-selectIcons">';
1536 $selicon_cols = intval($config['selicon_cols']);
1537 if (!$selicon_cols) $selicon_cols=count($selicons);
1538 $sR = ceil(count($selicons)/$selicon_cols);
1539 $selicons = array_pad($selicons,$sR*$selicon_cols,'');
1540 for($sa=0;$sa<$sR;$sa++) {
1541 $item.='<tr>';
1542 for($sb=0;$sb<$selicon_cols;$sb++) {
1543 $sk=($sa*$selicon_cols+$sb);
1544 $imgN = 'selIcon_'.$table.'_'.$row['uid'].'_'.$field.'_'.$selicons[$sk][1];
1545 $imgS = ($selicons[$sk][2]?$this->backPath.'gfx/content_selected.gif':'clear.gif');
1546 $item.='<td><img name="'.htmlspecialchars($imgN).'" src="'.$imgS.'" width="7" height="10" alt="" /></td>';
1547 $item.='<td>'.$selicons[$sk][0].'</td>';
1548 }
1549 $item.='</tr>';
1550 }
1551 $item.='</table>';
1552 }
1553
1554 return $item;
1555 }
1556
1557 /**
1558 * Creates a checkbox list (renderMode = "checkbox")
1559 * (Render function for getSingleField_typeSelect())
1560 *
1561 * @param string See getSingleField_typeSelect()
1562 * @param string See getSingleField_typeSelect()
1563 * @param array See getSingleField_typeSelect()
1564 * @param array See getSingleField_typeSelect()
1565 * @param array (Redundant) content of $PA['fieldConf']['config'] (for convenience)
1566 * @param array Items available for selection
1567 * @param string Label for no-matching-value
1568 * @return string The HTML code for the item
1569 * @see getSingleField_typeSelect()
1570 */
1571 function getSingleField_typeSelect_checkbox($table,$field,$row,&$PA,$config,$selItems,$nMV_label) {
1572
1573 // Get values in an array (and make unique, which is fine because there can be no duplicates anyway):
1574 $itemArray = array_flip($this->extractValuesOnlyFromValueLabelList($PA['itemFormElValue']));
1575
1576 $disabled = '';
1577 if($this->renderReadonly || $config['readOnly']) {
1578 $disabled = ' disabled="disabled"';
1579 }
1580
1581 // Traverse the Array of selector box items:
1582 $tRows = array();
1583 $c=0;
1584 if (!$disabled) {
1585 $sOnChange = implode('',$PA['fieldChangeFunc']);
1586 $setAll = array(); // Used to accumulate the JS needed to restore the original selection.
1587 foreach($selItems as $p) {
1588 // Non-selectable element:
1589 if (!strcmp($p[1],'--div--')) {
1590 if (count($setAll)) {
1591 $tRows[] = '
1592 <tr>
1593 <td colspan="2">'.
1594 '<a href="#" onclick="'.htmlspecialchars(implode('',$setAll).' return false;').'">'.
1595 htmlspecialchars($this->getLL('l_setAllCheckboxes')).
1596 '</a></td>
1597 </tr>';
1598 $setAll = array();
1599 }
1600
1601 $tRows[] = '
1602 <tr class="c-header">
1603 <td colspan="2">'.htmlspecialchars($p[0]).'</td>
1604 </tr>';
1605 } else {
1606 // Selected or not by default:
1607 $sM = '';
1608 if (isset($itemArray[$p[1]])) {
1609 $sM = ' checked="checked"';
1610 unset($itemArray[$p[1]]);
1611 }
1612
1613 // Icon:
1614 $selIconFile = '';
1615 if ($p[2]) {
1616 list($selIconFile,$selIconInfo) = $this->getIcon($p[2]);
1617 }
1618
1619 // Compile row:
1620 $onClickCell = $this->elName($PA['itemFormElName'].'['.$c.']').'.checked=!'.$this->elName($PA['itemFormElName'].'['.$c.']').'.checked;';
1621 $onClick = 'this.attributes.getNamedItem("class").nodeValue = '.$this->elName($PA['itemFormElName'].'['.$c.']').'.checked ? "c-selectedItem" : "";';
1622 $setAll[] = $this->elName($PA['itemFormElName'].'['.$c.']').'.checked=1;';
1623 $tRows[] = '
1624 <tr class="'.($sM ? 'c-selectedItem' : '').'" onclick="'.htmlspecialchars($onClick).'" style="cursor: pointer;">
1625 <td><input type="checkbox"'.$this->insertDefStyle('check').' name="'.htmlspecialchars($PA['itemFormElName'].'['.$c.']').'" value="'.htmlspecialchars($p[1]).'"'.$sM.' onclick="'.htmlspecialchars($sOnChange).'"'.$PA['onFocus'].' /></td>
1626 <td class="c-labelCell" onclick="'.htmlspecialchars($onClickCell).'">'.
1627 ($selIconFile ? '<img src="'.$selIconFile.'" '.$selIconInfo[3].' vspace="2" border="0" class="absmiddle" style="margin-right: 4px;" alt="" />' : '').
1628 t3lib_div::deHSCentities(htmlspecialchars($p[0])).
1629 (strcmp($p[3],'') ? '<br/><p class="c-descr">'.nl2br(trim(htmlspecialchars($p[3]))).'</p>' : '').
1630 '</td>
1631 </tr>';
1632 $c++;
1633 }
1634 }
1635
1636 // Remaining checkboxes will get their set-all link:
1637 if (count($setAll)) {
1638 $tRows[] = '
1639 <tr>
1640 <td colspan="2">'.
1641 '<a href="#" onclick="'.htmlspecialchars(implode('',$setAll).' return false;').'">'.
1642 htmlspecialchars($this->getLL('l_setAllCheckboxes')).
1643 '</a></td>
1644 </tr>';
1645 }
1646 }
1647
1648 // Remaining values (invalid):
1649 if (count($itemArray) && !$PA['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) {
1650 foreach($itemArray as $theNoMatchValue => $temp) {
1651 // Compile <checkboxes> tag:
1652 array_unshift($tRows,'
1653 <tr class="c-invalidItem">
1654 <td><input type="checkbox"'.$this->insertDefStyle('check').' name="'.htmlspecialchars($PA['itemFormElName'].'['.$c.']').'" value="'.htmlspecialchars($theNoMatchValue).'" checked="checked" onclick="'.htmlspecialchars($sOnChange).'"'.$PA['onFocus'].$disabled.' /></td>
1655 <td class="c-labelCell">'.
1656 t3lib_div::deHSCentities(htmlspecialchars(@sprintf($nMV_label, $theNoMatchValue))).
1657 '</td>
1658 </tr>');
1659 $c++;
1660 }
1661 }
1662
1663 // Add an empty hidden field which will send a blank value if all items are unselected.
1664 $item.='<input type="hidden" name="'.htmlspecialchars($PA['itemFormElName']).'" value="" />';
1665
1666 // Implode rows in table:
1667 $item.= '
1668 <table border="0" cellpadding="0" cellspacing="0" class="typo3-TCEforms-select-checkbox">'.
1669 implode('',$tRows).'
1670 </table>
1671 ';
1672
1673 return $item;
1674 }
1675
1676 /**
1677 * Creates a selectorbox list (renderMode = "singlebox")
1678 * (Render function for getSingleField_typeSelect())
1679 *
1680 * @param string See getSingleField_typeSelect()
1681 * @param string See getSingleField_typeSelect()
1682 * @param array See getSingleField_typeSelect()
1683 * @param array See getSingleField_typeSelect()
1684 * @param array (Redundant) content of $PA['fieldConf']['config'] (for convenience)
1685 * @param array Items available for selection
1686 * @param string Label for no-matching-value
1687 * @return string The HTML code for the item
1688 * @see getSingleField_typeSelect()
1689 */
1690 function getSingleField_typeSelect_singlebox($table,$field,$row,&$PA,$config,$selItems,$nMV_label) {
1691
1692 // Get values in an array (and make unique, which is fine because there can be no duplicates anyway):
1693 $itemArray = array_flip($this->extractValuesOnlyFromValueLabelList($PA['itemFormElValue']));
1694
1695 $disabled = '';
1696 if($this->renderReadonly || $config['readOnly']) {
1697 $disabled = ' disabled="disabled"';
1698 }
1699
1700 // Traverse the Array of selector box items:
1701 $opt = array();
1702 $restoreCmd = array(); // Used to accumulate the JS needed to restore the original selection.
1703 $c = 0;
1704 foreach($selItems as $p) {
1705 // Selected or not by default:
1706 $sM = '';
1707 if (isset($itemArray[$p[1]])) {
1708 $sM = ' selected="selected"';
1709 $restoreCmd[] = $this->elName($PA['itemFormElName'].'[]').'.options['.$c.'].selected=1;';
1710 unset($itemArray[$p[1]]);
1711 }
1712
1713 // Non-selectable element:
1714 $nonSel = '';
1715 if (!strcmp($p[1],'--div--')) {
1716 $nonSel = ' onclick="this.selected=0;" class="c-divider"';
1717 }
1718
1719 // Icon style for option tag:
1720 if ($config['iconsInOptionTags']) {
1721 $styleAttrValue = $this->optionTagStyle($p[2]);
1722 }
1723
1724 // Compile <option> tag:
1725 $opt[] = '<option value="'.htmlspecialchars($p[1]).'"'.
1726 $sM.
1727 $nonSel.
1728 ($styleAttrValue ? ' style="'.htmlspecialchars($styleAttrValue).'"' : '').
1729 '>'.t3lib_div::deHSCentities(htmlspecialchars($p[0])).'</option>';
1730 $c++;
1731 }
1732
1733 // Remaining values:
1734 if (count($itemArray) && !$PA['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) {
1735 foreach($itemArray as $theNoMatchValue => $temp) {
1736 // Compile <option> tag:
1737 array_unshift($opt,'<option value="'.htmlspecialchars($theNoMatchValue).'" selected="selected">'.t3lib_div::deHSCentities(htmlspecialchars(@sprintf($nMV_label, $theNoMatchValue))).'</option>');
1738 }
1739 }
1740
1741 // Compile selector box:
1742 $sOnChange = implode('',$PA['fieldChangeFunc']);
1743 $selector_itemListStyle = isset($config['itemListStyle']) ? ' style="'.htmlspecialchars($config['itemListStyle']).'"' : ' style="'.$this->defaultMultipleSelectorStyle.'"';
1744 $size = intval($config['size']);
1745 $size = $config['autoSizeMax'] ? t3lib_div::intInRange(count($selItems)+1,t3lib_div::intInRange($size,1),$config['autoSizeMax']) : $size;
1746 $selectBox = '<select name="'.$PA['itemFormElName'].'[]"'.
1747 $this->insertDefStyle('select').
1748 ($size ? ' size="'.$size.'"' : '').
1749 ' multiple="multiple" onchange="'.htmlspecialchars($sOnChange).'"'.
1750 $PA['onFocus'].
1751 $selector_itemListStyle.
1752 $disabled.'>
1753 '.
1754 implode('
1755 ',$opt).'
1756 </select>';
1757
1758 // Add an empty hidden field which will send a blank value if all items are unselected.
1759 if (!$disabled) {
1760 $item.='<input type="hidden" name="'.htmlspecialchars($PA['itemFormElName']).'" value="" />';
1761 }
1762
1763 // Put it all into a table:
1764 $item.= '
1765 <table border="0" cellspacing="0" cellpadding="0" width="1" class="typo3-TCEforms-select-singlebox">
1766 <tr>
1767 <td>
1768 '.$selectBox.'
1769 <br/>
1770 <em>'.
1771 htmlspecialchars($this->getLL('l_holdDownCTRL')).
1772 '</em>
1773 </td>
1774 <td valign="top">
1775 <a href="#" onclick="'.htmlspecialchars($this->elName($PA['itemFormElName'].'[]').'.selectedIndex=-1;'.implode('',$restoreCmd).' return false;').'">'.
1776 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/history.gif','width="13" height="12"').' title="'.htmlspecialchars($this->getLL('l_revertSelection')).'" alt="" />'.
1777 '</a>
1778 </td>
1779 </tr>
1780 </table>
1781 ';
1782
1783 return $item;
1784 }
1785
1786 /**
1787 * Creates a multiple-selector box (two boxes, side-by-side)
1788 * (Render function for getSingleField_typeSelect())
1789 *
1790 * @param string See getSingleField_typeSelect()
1791 * @param string See getSingleField_typeSelect()
1792 * @param array See getSingleField_typeSelect()
1793 * @param array See getSingleField_typeSelect()
1794 * @param array (Redundant) content of $PA['fieldConf']['config'] (for convenience)
1795 * @param array Items available for selection
1796 * @param string Label for no-matching-value
1797 * @return string The HTML code for the item
1798 * @see getSingleField_typeSelect()
1799 */
1800 function getSingleField_typeSelect_multiple($table,$field,$row,&$PA,$config,$selItems,$nMV_label) {
1801
1802 $disabled = '';
1803 if($this->renderReadonly || $config['readOnly']) {
1804 $disabled = ' disabled="disabled"';
1805 }
1806
1807 // Setting this hidden field (as a flag that JavaScript can read out)
1808 if (!$disabled) {
1809 $item.= '<input type="hidden" name="'.$PA['itemFormElName'].'_mul" value="'.($config['multiple']?1:0).'" />';
1810 }
1811
1812 // Set max and min items:
1813 $maxitems = t3lib_div::intInRange($config['maxitems'],0);
1814 if (!$maxitems) $maxitems=100000;
1815 $minitems = t3lib_div::intInRange($config['minitems'],0);
1816
1817 // Register the required number of elements:
1818 $this->requiredElements[$PA['itemFormElName']] = array($minitems,$maxitems,'imgName'=>$table.'_'.$row['uid'].'_'.$field);
1819
1820 // Get "removeItems":
1821 $removeItems = t3lib_div::trimExplode(',',$PA['fieldTSConfig']['removeItems'],1);
1822
1823 // Perform modification of the selected items array:
1824 $itemArray = t3lib_div::trimExplode(',',$PA['itemFormElValue'],1);
1825 foreach($itemArray as $tk => $tv) {
1826 $tvP = explode('|',$tv,2);
1827 $evalValue = rawurldecode($tvP[0]);
1828 $isRemoved = in_array($evalValue,$removeItems) || ($config['form_type']=='select' && $config['authMode'] && !$GLOBALS['BE_USER']->checkAuthMode($table,$field,$evalValue,$config['authMode']));
1829 if ($isRemoved && !$PA['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) {
1830 $tvP[1] = rawurlencode(@sprintf($nMV_label, $evalValue));
1831 } elseif (isset($PA['fieldTSConfig']['altLabels.'][$evalValue])) {
1832 $tvP[1] = rawurlencode($this->sL($PA['fieldTSConfig']['altLabels.'][$evalValue]));
1833 }
1834 $itemArray[$tk] = implode('|',$tvP);
1835 }
1836 $itemsToSelect = '';
1837
1838 if(!$disabled) {
1839 // Create option tags:
1840 $opt = array();
1841 $styleAttrValue = '';
1842 foreach($selItems as $p) {
1843 if ($config['iconsInOptionTags']) {
1844 $styleAttrValue = $this->optionTagStyle($p[2]);
1845 }
1846 $opt[]= '<option value="'.htmlspecialchars($p[1]).'"'.
1847 ($styleAttrValue ? ' style="'.htmlspecialchars($styleAttrValue).'"' : '').
1848 '>'.htmlspecialchars($p[0]).'</option>';
1849 }
1850
1851 // Put together the selector box:
1852 $selector_itemListStyle = isset($config['itemListStyle']) ? ' style="'.htmlspecialchars($config['itemListStyle']).'"' : ' style="'.$this->defaultMultipleSelectorStyle.'"';
1853 $size = intval($config['size']);
1854 $size = $config['autoSizeMax'] ? t3lib_div::intInRange(count($itemArray)+1,t3lib_div::intInRange($size,1),$config['autoSizeMax']) : $size;
1855 if ($config['exclusiveKeys']) {
1856 $sOnChange = 'setFormValueFromBrowseWin(\''.$PA['itemFormElName'].'\',this.options[this.selectedIndex].value,this.options[this.selectedIndex].text,\''.$config['exclusiveKeys'].'\'); ';
1857 } else {
1858 $sOnChange = 'setFormValueFromBrowseWin(\''.$PA['itemFormElName'].'\',this.options[this.selectedIndex].value,this.options[this.selectedIndex].text); ';
1859 }
1860 $sOnChange .= implode('',$PA['fieldChangeFunc']);
1861 $itemsToSelect = '
1862 <select name="'.$PA['itemFormElName'].'_sel"'.
1863 $this->insertDefStyle('select').
1864 ($size ? ' size="'.$size.'"' : '').
1865 ' onchange="'.htmlspecialchars($sOnChange).'"'.
1866 $PA['onFocus'].
1867 $selector_itemListStyle.'>
1868 '.implode('
1869 ',$opt).'
1870 </select>';
1871 }
1872
1873 // Pass to "dbFileIcons" function:
1874 $params = array(
1875 'size' => $size,
1876 'autoSizeMax' => t3lib_div::intInRange($config['autoSizeMax'],0),
1877 'style' => isset($config['selectedListStyle']) ? ' style="'.htmlspecialchars($config['selectedListStyle']).'"' : ' style="'.$this->defaultMultipleSelectorStyle.'"',
1878 'dontShowMoveIcons' => ($maxitems<=1),
1879 'maxitems' => $maxitems,
1880 'info' => '',
1881 'headers' => array(
1882 'selector' => $this->getLL('l_selected').':<br />',
1883 'items' => $this->getLL('l_items').':<br />'
1884 ),
1885 'noBrowser' => 1,
1886 'thumbnails' => $itemsToSelect,
1887 'readOnly' => $disabled
1888 );
1889 $item.= $this->dbFileIcons($PA['itemFormElName'],'','',$itemArray,'',$params,$PA['onFocus']);
1890
1891 return $item;
1892 }
1893
1894 /**
1895 * Generation of TCEform elements of the type "group"
1896 * This will render a selectorbox into which elements from either the file system or database can be inserted. Relations.
1897 *
1898 * @param string The table name of the record
1899 * @param string The field name which this element is supposed to edit
1900 * @param array The record data array where the value(s) for the field can be found
1901 * @param array An array with additional configuration options.
1902 * @return string The HTML code for the TCEform field
1903 */
1904 function getSingleField_typeGroup($table,$field,$row,&$PA) {
1905 // Init:
1906 $config = $PA['fieldConf']['config'];
1907 $internal_type = $config['internal_type'];
1908 $show_thumbs = $config['show_thumbs'];
1909 $size = intval($config['size']);
1910 $maxitems = t3lib_div::intInRange($config['maxitems'],0);
1911 if (!$maxitems) $maxitems=100000;
1912 $minitems = t3lib_div::intInRange($config['minitems'],0);
1913 $allowed = $config['allowed'];
1914 $disallowed = $config['disallowed'];
1915
1916 $disabled = '';
1917 if($this->renderReadonly || $config['readOnly']) {
1918 $disabled = ' disabled="disabled"';
1919 }
1920
1921 $item.= '<input type="hidden" name="'.$PA['itemFormElName'].'_mul" value="'.($config['multiple']?1:0).'"'.$disabled.' />';
1922 $this->requiredElements[$PA['itemFormElName']] = array($minitems,$maxitems,'imgName'=>$table.'_'.$row['uid'].'_'.$field);
1923 $info='';
1924
1925 // "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/.
1926 $specConf = $this->getSpecConfFromString($PA['extra'], $PA['fieldConf']['defaultExtras']);
1927
1928 // Acting according to either "file" or "db" type:
1929 switch((string)$config['internal_type']) {
1930 case 'file': // If the element is of the internal type "file":
1931
1932 // Creating string showing allowed types:
1933 $tempFT = t3lib_div::trimExplode(',',$allowed,1);
1934 if (!count($tempFT)) {$info.='*';}
1935 foreach($tempFT as $ext) {
1936 if ($ext) {
1937 $info.=strtoupper($ext).' ';
1938 }
1939 }
1940 // Creating string, showing disallowed types:
1941 $tempFT_dis = t3lib_div::trimExplode(',',$disallowed,1);
1942 if (count($tempFT_dis)) {$info.='<br />';}
1943 foreach($tempFT_dis as $ext) {
1944 if ($ext) {
1945 $info.='-'.strtoupper($ext).' ';
1946 }
1947 }
1948
1949 // Making the array of file items:
1950 $itemArray = t3lib_div::trimExplode(',',$PA['itemFormElValue'],1);
1951
1952 // Showing thumbnails:
1953 $thumbsnail = '';
1954 if ($show_thumbs) {
1955 $imgs = array();
1956 foreach($itemArray as $imgRead) {
1957 $imgP = explode('|',$imgRead);
1958 $imgPath = rawurldecode($imgP[0]);
1959
1960 $rowCopy = array();
1961 $rowCopy[$field] = $imgPath;
1962
1963 // Icon + clickmenu:
1964 $absFilePath = t3lib_div::getFileAbsFileName($config['uploadfolder'].'/'.$imgPath);
1965
1966 $fI = pathinfo($imgPath);
1967 $fileIcon = t3lib_BEfunc::getFileIcon(strtolower($fI['extension']));
1968 $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="" />';
1969
1970 $imgs[] = '<span class="nobr">'.t3lib_BEfunc::thumbCode($rowCopy,$table,$field,$this->backPath,'thumbs.php',$config['uploadfolder'],0,' align="middle"').
1971 ($absFilePath ? $this->getClickMenu($fileIcon, $absFilePath) : $fileIcon).
1972 $imgPath.
1973 '</span>';
1974 }
1975 $thumbsnail = implode('<br />',$imgs);
1976 }
1977
1978 // Creating the element:
1979 $params = array(
1980 'size' => $size,
1981 'dontShowMoveIcons' => ($maxitems<=1),
1982 'autoSizeMax' => t3lib_div::intInRange($config['autoSizeMax'],0),
1983 'maxitems' => $maxitems,
1984 'style' => isset($config['selectedListStyle']) ? ' style="'.htmlspecialchars($config['selectedListStyle']).'"' : ' style="'.$this->defaultMultipleSelectorStyle.'"',
1985 'info' => $info,
1986 'thumbnails' => $thumbsnail,
1987 'readOnly' => $disabled
1988 );
1989 $item.= $this->dbFileIcons($PA['itemFormElName'],'file',implode(',',$tempFT),$itemArray,'',$params,$PA['onFocus']);
1990
1991 if(!$disabled) {
1992 // Adding the upload field:
1993 if ($this->edit_docModuleUpload) $item.='<input type="file" name="'.$PA['itemFormElName_file'].'"'.$this->formWidth().' size="60" />';
1994 }
1995 break;
1996 case 'db': // If the element is of the internal type "db":
1997
1998 // Creating string showing allowed types:
1999 $tempFT = t3lib_div::trimExplode(',',$allowed,1);
2000 if (!strcmp(trim($tempFT[0]),'*')) {
2001 $info.='<span class="nobr">&nbsp;&nbsp;&nbsp;&nbsp;'.
2002 htmlspecialchars($this->getLL('l_allTables')).
2003 '</span><br />';
2004 } else {
2005 while(list(,$theT)=each($tempFT)) {
2006 if ($theT) {
2007 $info.='<span class="nobr">&nbsp;&nbsp;&nbsp;&nbsp;'.
2008 t3lib_iconWorks::getIconImage($theT,array(),$this->backPath,'align="top"').
2009 htmlspecialchars($this->sL($GLOBALS['TCA'][$theT]['ctrl']['title'])).
2010 '</span><br />';
2011 }
2012 }
2013 }
2014
2015 $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);
2016 $itemArray = array();
2017 $imgs = array();
2018
2019 // Thumbnails:
2020 $temp_itemArray = t3lib_div::trimExplode(',',$PA['itemFormElValue'],1);
2021 foreach($temp_itemArray as $dbRead) {
2022 $recordParts = explode('|',$dbRead);
2023 list($this_table,$this_uid) = t3lib_BEfunc::splitTable_Uid($recordParts[0]);
2024 $itemArray[] = array('table'=>$this_table, 'id'=>$this_uid);
2025 if (!$disabled && $show_thumbs) {
2026 $rr = t3lib_BEfunc::getRecordWSOL($this_table,$this_uid);
2027 $imgs[] = '<span class="nobr">'.
2028 $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).
2029 '&nbsp;'.
2030 t3lib_BEfunc::getRecordTitle($this_table,$rr,TRUE).' <span class="typo3-dimmed"><em>['.$rr['uid'].']</em></span>'.
2031 '</span>';
2032 }
2033 }
2034 $thumbsnail='';
2035 if (!$disabled && $show_thumbs) {
2036 $thumbsnail = implode('<br />',$imgs);
2037 }
2038
2039 // Creating the element:
2040 $params = array(
2041 'size' => $size,
2042 'dontShowMoveIcons' => ($maxitems<=1),
2043 'autoSizeMax' => t3lib_div::intInRange($config['autoSizeMax'],0),
2044 'maxitems' => $maxitems,
2045 'style' => isset($config['selectedListStyle']) ? ' style="'.htmlspecialchars($config['selectedListStyle']).'"' : ' style="'.$this->defaultMultipleSelectorStyle.'"',
2046 'info' => $info,
2047 'thumbnails' => $thumbsnail,
2048 'readOnly' => $disabled
2049 );
2050 $item.= $this->dbFileIcons($PA['itemFormElName'],'db',implode(',',$tempFT),$itemArray,'',$params,$PA['onFocus'],$table,$field,$row['uid']);
2051
2052 break;
2053 }
2054
2055 // Wizards:
2056 $altItem = '<input type="hidden" name="'.$PA['itemFormElName'].'" value="'.htmlspecialchars($PA['itemFormElValue']).'" />';
2057 if (!$disabled) {
2058 $item = $this->renderWizards(array($item,$altItem),$config['wizards'],$table,$row,$field,$PA,$PA['itemFormElName'],$specConf);
2059 }
2060
2061 return $item;
2062 }
2063
2064 /**
2065 * Generation of TCEform elements of the type "none"
2066 * This will render a non-editable display of the content of the field.
2067 *
2068 * @param string The table name of the record
2069 * @param string The field name which this element is supposed to edit
2070 * @param array The record data array where the value(s) for the field can be found
2071 * @param array An array with additional configuration options.
2072 * @return string The HTML code for the TCEform field
2073 */
2074 function getSingleField_typeNone($table,$field,$row,&$PA) {
2075 // Init:
2076 $config = $PA['fieldConf']['config'];
2077 $itemValue = $PA['itemFormElValue'];
2078
2079 return $this->getSingleField_typeNone_render($config,$itemValue);
2080 }
2081
2082 /**
2083 * HTML rendering of a value which is not editable.
2084 *
2085 * @param array Configuration for the display
2086 * @param string The value to display
2087 * @return string The HTML code for the display
2088 * @see getSingleField_typeNone();
2089 */
2090 function getSingleField_typeNone_render($config,$itemValue) {
2091
2092 // is colorScheme[0] the right value?
2093 $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;';
2094
2095 if ($config['format']) {
2096 $itemValue = $this->formatValue($config, $itemValue);
2097 }
2098
2099 $rows = intval($config['rows']);
2100 if ($rows > 1) {
2101 if(!$config['pass_content']) {
2102 $itemValue = nl2br(htmlspecialchars($itemValue));
2103 }
2104 // like textarea
2105 $cols = t3lib_div::intInRange($config['cols'] ? $config['cols'] : 30, 5, $this->maxTextareaWidth);
2106 if (!$config['fixedRows']) {
2107 $origRows = $rows = t3lib_div::intInRange($rows, 1, 20);
2108 if (strlen($itemValue)>$this->charsPerRow*2) {
2109 $cols = $this->maxTextareaWidth;
2110 $rows = t3lib_div::intInRange(round(strlen($itemValue)/$this->charsPerRow),count(explode(chr(10),$itemValue)),20);
2111 if ($rows<$origRows) $rows=$origRows;
2112 }
2113 }
2114
2115 if ($this->docLarge) $cols = round($cols*$this->form_largeComp);
2116 $width = ceil($cols*$this->form_rowsToStylewidth);
2117 // hardcoded: 12 is the height of the font
2118 $height=$rows*12;
2119
2120 $item='
2121 <div style="'.htmlspecialchars($divStyle.' overflow:auto; height:'.$height.'px; width:'.$width.'px;').'" class="'.htmlspecialchars($this->formElClass('none')).'">'.
2122 $itemValue.
2123 '</div>';
2124 } else {
2125 if(!$config['pass_content']) {
2126 $itemValue = htmlspecialchars($itemValue);
2127 }
2128
2129 $cols = $config['cols']?$config['cols']:($config['size']?$config['size']:$this->maxInputWidth);
2130 if ($this->docLarge) $cols = round($cols*$this->form_largeComp);
2131 $width = ceil($cols*$this->form_rowsToStylewidth);
2132
2133 // overflow:auto crashes mozilla here. Title tag is usefull when text is longer than the div box (overflow:hidden).
2134 $item = '
2135 <div style="'.htmlspecialchars($divStyle.' overflow:hidden; width:'.$width.'px;').'" class="'.htmlspecialchars($this->formElClass('none')).'" title="'.$itemValue.'">'.
2136 '<span class="nobr">'.(strcmp($itemValue,'')?$itemValue:'&nbsp;').'</span>'.
2137 '</div>';
2138 }
2139
2140 return $item;
2141 }
2142
2143 /**
2144 * Handler for Flex Forms
2145 *
2146 * @param string The table name of the record
2147 * @param string The field name which this element is supposed to edit
2148 * @param array The record data array where the value(s) for the field can be found
2149 * @param array An array with additional configuration options.
2150 * @return string The HTML code for the TCEform field
2151 */
2152 function getSingleField_typeFlex($table,$field,$row,&$PA) {
2153
2154 // Data Structure:
2155 $dataStructArray = t3lib_BEfunc::getFlexFormDS($PA['fieldConf']['config'],$row,$table);
2156
2157 // Get data structure:
2158 if (is_array($dataStructArray)) {
2159
2160 // Get data:
2161 $xmlData = $PA['itemFormElValue'];
2162 $xmlHeaderAttributes = t3lib_div::xmlGetHeaderAttribs($xmlData);
2163 $storeInCharset = strtolower($xmlHeaderAttributes['encoding']);
2164 if ($storeInCharset) {
2165 $currentCharset=$GLOBALS['LANG']->charSet;
2166 $xmlData = $GLOBALS['LANG']->csConvObj->conv($xmlData,$storeInCharset,$currentCharset,1);
2167 }
2168 $editData=t3lib_div::xml2array($xmlData);
2169 if (!is_array($editData)) { // Must be XML parsing error...
2170 $editData=array();
2171 } elseif (!isset($editData['meta']) || !is_array($editData['meta'])) {
2172 $editData['meta'] = array();
2173 }
2174
2175 // Find the data structure if sheets are found:
2176 $sheet = $editData['meta']['currentSheetId'] ? $editData['meta']['currentSheetId'] : 'sDEF'; // Sheet to display
2177
2178 // Create sheet menu:
2179 // if (is_array($dataStructArray['sheets'])) {
2180 // #$item.=$this->getSingleField_typeFlex_sheetMenu($dataStructArray['sheets'], $PA['itemFormElName'].'[meta][currentSheetId]', $sheet).'<br />';
2181 // }
2182
2183 // Create language menu:
2184 $langChildren = $dataStructArray['meta']['langChildren'] ? 1 : 0;
2185 $langDisabled = $dataStructArray['meta']['langDisable'] ? 1 : 0;
2186
2187 $editData['meta']['currentLangId']=array();
2188 $languages = $this->getAvailableLanguages();
2189
2190 foreach($languages as $lInfo) {
2191 if ($GLOBALS['BE_USER']->checkLanguageAccess($lInfo['uid'])) {
2192 $editData['meta']['currentLangId'][] = $lInfo['ISOcode'];
2193 }
2194 }
2195 if (!is_array($editData['meta']['currentLangId']) || !count($editData['meta']['currentLangId'])) {
2196 $editData['meta']['currentLangId']=array('DEF');
2197 }
2198
2199 $editData['meta']['currentLangId'] = array_unique($editData['meta']['currentLangId']);
2200
2201
2202 // if (!$langDisabled && count($languages) > 1) {
2203 // $item.=$this->getSingleField_typeFlex_langMenu($languages, $PA['itemFormElName'].'[meta][currentLangId]', $editData['meta']['currentLangId']).'<br />';
2204 // }
2205
2206 $PA['_noEditDEF'] = FALSE;
2207 if ($langChildren || $langDisabled) {
2208 $rotateLang = array('DEF');
2209 } else {
2210 if (!in_array('DEF',$editData['meta']['currentLangId'])) {
2211 array_unshift($editData['meta']['currentLangId'],'DEF');
2212 $PA['_noEditDEF'] = TRUE;
2213 }
2214 $rotateLang = $editData['meta']['currentLangId'];
2215 }
2216
2217 // Tabs sheets
2218 if (is_array($dataStructArray['sheets'])) {
2219 $tabsToTraverse = array_keys($dataStructArray['sheets']);
2220 } else {
2221 $tabsToTraverse = array($sheet);
2222 }
2223
2224 foreach ($rotateLang as $lKey) {
2225 if (!$langChildren && !$langDisabled) {
2226 $item.= '<b>'.$this->getLanguageIcon($table,$row,'v'.$lKey).$lKey.':</b>';
2227 }
2228
2229 $tabParts = array();
2230 foreach ($tabsToTraverse as $sheet) {
2231 $sheetCfg = $dataStructArray['sheets'][$sheet];
2232 list ($dataStruct, $sheet) = t3lib_div::resolveSheetDefInDS($dataStructArray,$sheet);
2233
2234 // Render sheet:
2235 if (is_array($dataStruct['ROOT']) && is_array($dataStruct['ROOT']['el'])) {
2236 $cmdData = t3lib_div::_GP('flexFormsCmdData');
2237 $lang = 'l'.$lKey; // Default language, other options are "lUK" or whatever country code (independant of system!!!)
2238 $PA['_valLang'] = $langChildren && !$langDisabled ? $editData['meta']['currentLangId'] : 'DEF'; // Default language, other options are "lUK" or whatever country code (independant of system!!!)
2239 $PA['_lang'] = $lang;
2240
2241 // Render flexform:
2242 $tRows = $this->getSingleField_typeFlex_draw(
2243 $dataStruct['ROOT']['el'],
2244 $editData['data'][$sheet][$lang],
2245 $cmdData['data'][$sheet][$lang],
2246 $table,
2247 $field,
2248 $row,
2249 $PA,
2250 '[data]['.$sheet.']['.$lang.']'
2251 );
2252 $sheetContent= '<table border="0" cellpadding="1" cellspacing="1" class="typo3-TCEforms-flexForm">'.implode('',$tRows).'</table>';
2253
2254 # $item = '<div style=" position:absolute;">'.$item.'</div>';
2255 //visibility:hidden;
2256 } else $sheetContent='Data Structure ERROR: No ROOT element found for sheet "'.$sheet.'".';
2257
2258 // Add to tab:
2259 $tabParts[] = array(
2260 'label' => ($sheetCfg['ROOT']['TCEforms']['sheetTitle'] ? $this->sL($sheetCfg['ROOT']['TCEforms']['sheetTitle']) : $sheet),
2261 'description' => ($sheetCfg['ROOT']['TCEforms']['sheetDescription'] ? $this->sL($sheetCfg['ROOT']['TCEforms']['sheetDescription']) : ''),
2262 'linkTitle' => ($sheetCfg['ROOT']['TCEforms']['sheetShortDescr'] ? $this->sL($sheetCfg['ROOT']['TCEforms']['sheetShortDescr']) : ''),
2263 'content' => $sheetContent
2264 );
2265 }
2266
2267 if (is_array($dataStructArray['sheets'])) {
2268 $item.= $this->getDynTabMenu($tabParts,'TCEFORMS:flexform:'.$PA['itemFormElName'].$PA['_lang']);
2269 } else {
2270 $item.= $sheetContent;
2271 }
2272 }
2273 } else $item='Data Structure ERROR: '.$dataStructArray;
2274
2275 return $item;
2276 }
2277
2278 /**
2279 * Creates the language menu for FlexForms:
2280 *
2281 * @param [type] $languages: ...
2282 * @param [type] $elName: ...
2283 * @param [type] $selectedLanguage: ...
2284 * @param [type] $multi: ...
2285 * @return string HTML for menu
2286 */
2287 function getSingleField_typeFlex_langMenu($languages,$elName,$selectedLanguage,$multi=1) {
2288 $opt=array();
2289 foreach($languages as $lArr) {
2290 $opt[]='<option value="'.htmlspecialchars($lArr['ISOcode']).'"'.(in_array($lArr['ISOcode'],$selectedLanguage)?' selected="selected"':'').'>'.htmlspecialchars($lArr['title']).'</option>';
2291 }
2292
2293 $output = '<select name="'.$elName.'[]"'.($multi ? ' multiple="multiple" size="'.count($languages).'"' : '').'>'.implode('',$opt).'</select>';
2294
2295 return $output;
2296 }
2297
2298 /**
2299 * Creates the menu for selection of the sheets:
2300 *
2301 * @param array Sheet array for which to render the menu
2302 * @param string Form element name of the field containing the sheet pointer
2303 * @param string Current sheet key
2304 * @return string HTML for menu
2305 */
2306 function getSingleField_typeFlex_sheetMenu($sArr,$elName,$sheetKey) {
2307
2308 $tCells =array();
2309 $pct = round(100/count($sArr));
2310 foreach($sArr as $sKey => $sheetCfg) {
2311 if ($GLOBALS['BE_USER']->jsConfirmation(1)) {
2312 $onClick = 'if (confirm(TBE_EDITOR.labels.onChangeAlert) && TBE_EDITOR.checkSubmit(-1)){'.$this->elName($elName).".value='".$sKey."'; TBE_EDITOR.submitForm()};";
2313 } else {
2314 $onClick = 'if(TBE_EDITOR.checkSubmit(-1)){ '.$this->elName($elName).".value='".$sKey."'; TBE_EDITOR.submitForm();}";
2315 }
2316
2317
2318 $tCells[]='<td width="'.$pct.'%" style="'.($sKey==$sheetKey ? 'background-color: #9999cc; font-weight: bold;' : 'background-color: #aaaaaa;').' cursor: hand;" onclick="'.htmlspecialchars($onClick).'" align="center">'.
2319 ($sheetCfg['ROOT']['TCEforms']['sheetTitle'] ? $this->sL($sheetCfg['ROOT']['TCEforms']['sheetTitle']) : $sKey).
2320 '</td>';
2321 }
2322
2323 return '<table border="0" cellpadding="0" cellspacing="2" class="typo3-TCEforms-flexForm-sheetMenu"><tr>'.implode('',$tCells).'</tr></table>';
2324 }
2325
2326 /**
2327 * [Describe function...]
2328 *
2329 * @param [type] $dataStruct: ...
2330 * @param [type] $editData: ...
2331 * @param [type] $cmdData: ...
2332 * @param [type] $table: ...
2333 * @param [type] $field: ...
2334 * @param [type] $row: ...
2335 * @param [type] $PA: ...
2336 * @param [type] $formPrefix: ...
2337 * @param [type] $level: ...
2338 * @param [type] $tRows: ...
2339 * @return [type] ...
2340 */
2341 function getSingleField_typeFlex_draw($dataStruct,$editData,$cmdData,$table,$field,$row,&$PA,$formPrefix='',$level=0,$tRows=array()) {
2342
2343 // Data Structure array must be ... and array of course...
2344 if (is_array($dataStruct)) {
2345 foreach($dataStruct as $key => $value) {
2346 if (is_array($value)) { // The value of each entry must be an array.
2347
2348 // ********************
2349 // Making the row:
2350 // ********************
2351 $rowCells=array();
2352
2353 // Icon:
2354 $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>';;
2355
2356 $rowCells['formEl']='';
2357 if ($value['type']=='array') {
2358 if ($value['section']) {
2359 // Render "NEW [container]" selectorbox:
2360 if (is_array($value['el'])) {
2361 $opt=array();
2362 $opt[]='<option value=""></option>';
2363 foreach($value['el'] as $kk => $vv) {
2364 $opt[]='<option value="'.$kk.'">'.htmlspecialchars($this->sL($value['el'][$kk]['tx_templavoila']['title'])).'</option>';
2365 }
2366 $rowCells['formEl']=$this->getLL('l_new_section') . ' <select name="flexFormsCmdData'.$formPrefix.'['.$key.'][value]">'.implode('',$opt).'</select> ';
2367 $rowCells['formEl'].=$this->getLL('l_count') . ' <select name="flexFormsCmdData'.$formPrefix.'['.$key.'][count]">';
2368 for ($i = 1; $i <= 10; $i++) {
2369 $rowCells['formEl'].='<option value="' . $i . '">' . $i . '</option>';
2370 }
2371 $rowCells['formEl'].='</select>';
2372 }
2373
2374 // Put row together
2375 $tRows[]='<tr class="bgColor2">
2376 <td nowrap="nowrap" valign="top">'.$rowCells['title'].'</td>
2377 <td>'.$rowCells['formEl'].'</td>
2378 </tr>';
2379
2380 $cc=0;
2381 if (is_array($editData[$key]['el'])) {
2382 foreach ($editData[$key]['el'] as $k3 => $v3) {
2383 $cc=$k3;
2384 $theType = key($v3);
2385 $theDat = $v3[$theType];
2386 $newSectionEl = $value['el'][$theType];
2387 if (is_array($newSectionEl)) {
2388 $tRows = $this->getSingleField_typeFlex_draw(
2389 array($theType => $newSectionEl),
2390 array($theType => $theDat),
2391 $cmdData[$key]['el'][$cc],
2392 $table,
2393 $field,
2394 $row,
2395 $PA,
2396 $formPrefix.'['.$key.'][el]['.$cc.']',
2397 $level+1,
2398 $tRows
2399 );
2400 }
2401 }
2402 }
2403
2404 // New form?
2405 if ($cmdData[$key]['value']) {
2406 $newSectionEl = $value['el'][$cmdData[$key]['value']];
2407 if (is_array($newSectionEl)) {
2408 $newElCount = max(1, intval($cmdData[$key]['count']));
2409 for ($newElNum = 0; $newElNum < $newElCount; $newElNum++) {
2410 $tRows = $this->getSingleField_typeFlex_draw(
2411 array($cmdData[$key]['value'] => $newSectionEl),
2412 array(),
2413 array(),
2414 $table,
2415 $field,
2416 $row,
2417 $PA,
2418 $formPrefix.'['.$key.'][el]['.($cc+1+$newElNum).']',
2419 $level+1,
2420 $tRows
2421 );
2422 }
2423 }
2424 }
2425 } else {
2426 $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
2427
2428 // Put row together
2429 $tRows[]='<tr class="bgColor2">
2430 <td nowrap="nowrap" valign="top">'.
2431 '<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>'.
2432 '<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>'.
2433 '<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>'.
2434 $rowCells['title'].'</td>
2435 <td>'.$rowCells['formEl'].'</td>
2436 </tr>';
2437
2438 $tRows = $this->getSingleField_typeFlex_draw(
2439 $value['el'],
2440 $editData[$key]['el'],
2441 $cmdData[$key]['el'],
2442 $table,
2443 $field,
2444 $row,
2445 $PA,
2446 $formPrefix.'['.$key.'][el]',
2447 $level+1,
2448 $tRows
2449 );
2450 }
2451
2452 } elseif (is_array($value['TCEforms']['config'])) { // Rendering a single form element:
2453
2454 if (is_array($PA['_valLang'])) {
2455 $rotateLang = $PA['_valLang'];
2456 } else {
2457 $rotateLang = array($PA['_valLang']);
2458 }
2459
2460 foreach($rotateLang as $vDEFkey) {
2461 $vDEFkey = 'v'.$vDEFkey;
2462
2463 if (!$value['TCEforms']['displayCond'] || $this->isDisplayCondition($value['TCEforms']['displayCond'],$editData,$vDEFkey)) {
2464 $fakePA=array();
2465 $fakePA['fieldConf']=array(
2466 'label' => $this->sL(trim($value['TCEforms']['label'])),
2467 'config' => $value['TCEforms']['config'],
2468 'defaultExtras' => $value['TCEforms']['defaultExtras'],
2469 'onChange' => $value['TCEforms']['onChange']
2470 );
2471 if ($PA['_noEditDEF'] && $PA['_lang']==='lDEF') {
2472 $fakePA['fieldConf']['config'] = array(
2473 'type' => 'none',
2474 'rows' => 2
2475 );
2476 }
2477
2478 if (
2479 $fakePA['fieldConf']['onChange'] == 'reload' ||
2480 ($GLOBALS['TCA'][$table]['ctrl']['type'] && !strcmp($key,$GLOBALS['TCA'][$table]['ctrl']['type'])) ||
2481 ($GLOBALS['TCA'][$table]['ctrl']['requestUpdate'] && t3lib_div::inList($GLOBALS['TCA'][$table]['ctrl']['requestUpdate'],$key))) {
2482 if ($GLOBALS['BE_USER']->jsConfirmation(1)) {
2483 $alertMsgOnChange = 'if (confirm(TBE_EDITOR.labels.onChangeAlert) && TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };';
2484 } else {
2485 $alertMsgOnChange = 'if(TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm();}';
2486 }
2487 } else {
2488 $alertMsgOnChange = '';
2489 }
2490
2491 $fakePA['fieldChangeFunc']=$PA['fieldChangeFunc'];
2492 if (strlen($alertMsgOnChange)) {
2493 $fakePA['fieldChangeFunc']['alert']=$alertMsgOnChange;
2494 }
2495 $fakePA['onFocus']=$PA['onFocus'];
2496 $fakePA['label']=$PA['label'];
2497
2498 $fakePA['itemFormElName']=$PA['itemFormElName'].$formPrefix.'['.$key.']['.$vDEFkey.']';
2499 $fakePA['itemFormElName_file']=$PA['itemFormElName_file'].$formPrefix.'['.$key.']['.$vDEFkey.']';
2500
2501 if(isset($editData[$key][$vDEFkey])) {
2502 $fakePA['itemFormElValue']=$editData[$key][$vDEFkey];
2503 } else {
2504 $fakePA['itemFormElValue']=$fakePA['fieldConf']['config']['default'];
2505 }
2506
2507 $rowCells['formEl']= $this->getSingleField_SW($table,$field,$row,$fakePA);
2508 $rowCells['title']= htmlspecialchars($fakePA['fieldConf']['label']);
2509
2510 if (!in_array('DEF',$rotateLang)) {
2511 $defInfo = '<div class="typo3-TCEforms-originalLanguageValue">'.$this->getLanguageIcon($table,$row,0).$this->previewFieldValue($editData[$key]['vDEF'], $fakePA['fieldConf']).'&nbsp;</div>';
2512 } else {
2513 $defInfo = '';
2514 }
2515
2516 if (!$PA['_noEditDEF']) {
2517 $prLang = $this->getAdditionalPreviewLanguages();
2518 foreach($prLang as $prL) {
2519 $defInfo.= '<div class="typo3-TCEforms-originalLanguageValue">'.$this->getLanguageIcon($table,$row,'v'.$prL['ISOcode']).$this->previewFieldValue($editData[$key]['v'.$prL['ISOcode']], $fakePA['fieldConf']).'&nbsp;</div>';
2520 }
2521 }
2522
2523 // Put row together
2524 $tRows[]='<tr>
2525 <td nowrap="nowrap" valign="top" class="bgColor5">'.($vDEFkey=='vDEF' ? '' : $this->getLanguageIcon($table,$row,$vDEFkey)).$rowCells['title'].'</td>
2526 <td class="bgColor4">'.$rowCells['formEl'].$defInfo.'</td>
2527 </tr>';
2528 }
2529 }
2530 }
2531 }
2532 }
2533 }
2534
2535 return $tRows;
2536 }
2537
2538 /**
2539 * Handler for unknown types.
2540 *
2541 * @param string The table name of the record
2542 * @param string The field name which this element is supposed to edit
2543 * @param array The record data array where the value(s) for the field can be found
2544 * @param array An array with additional configuration options.
2545 * @return string The HTML code for the TCEform field
2546 */
2547 function getSingleField_typeUnknown($table,$field,$row,&$PA) {
2548 $item='Unknown type: '.$PA['fieldConf']['config']['form_type'].'<br />';
2549
2550 return $item;
2551 }
2552
2553 /**
2554 * User defined field type
2555 *
2556 * @param string The table name of the record
2557 * @param string The field name which this element is supposed to edit
2558 * @param array The record data array where the value(s) for the field can be found
2559 * @param array An array with additional configuration options.
2560 * @return string The HTML code for the TCEform field
2561 */
2562 function getSingleField_typeUser($table,$field,$row,&$PA) {
2563 $PA['table']=$table;
2564 $PA['field']=$field;
2565 $PA['row']=$row;
2566
2567 $PA['pObj']=&$this;
2568
2569 return t3lib_div::callUserFunction($PA['fieldConf']['config']['userFunc'],$PA,$this);
2570 }
2571
2572
2573
2574
2575
2576
2577 /************************************************************
2578 *
2579 * Field content processing
2580 *
2581 ************************************************************/
2582
2583 /**
2584 * Format field content of various types if $config['format'] is set to date, filesize, ..., user
2585 * This is primarily for the field type none but can be used for user field types for example
2586 *
2587 * @param array Configuration for the display
2588 * @param string The value to display
2589 * @return string Formatted Field content
2590 */
2591 function formatValue ($config, $itemValue) {
2592 $format = trim($config['format']);
2593 switch($format) {
2594 case 'date':
2595 if ($itemValue) {
2596 $option = trim($config['format.']['option']);
2597 if ($option) {
2598 if ($config['format.']['strftime']) {
2599 $value = strftime($option,$itemValue);
2600 } else {
2601 $value = date($option,$itemValue);
2602 }
2603 } else {
2604 $value = date('d-m-Y',$itemValue);
2605 }
2606 } else {
2607 $value = '';
2608 }
2609 if ($config['format.']['appendAge']) {
2610 $value .= ' ('.t3lib_BEfunc::calcAge((time()-$itemValue), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears')).')';
2611 }
2612 $itemValue = $value;
2613 break;
2614 case 'datetime': // compatibility with "eval" (type "input")
2615 $itemValue = date('H:i d-m-Y',$itemValue);
2616 break;
2617 case 'time': // compatibility with "eval" (type "input")
2618 $itemValue = date('H:i',$itemValue);
2619 break;
2620 case 'timesec': // compatibility with "eval" (type "input")
2621 $itemValue = date('H:i:s',$itemValue);
2622 break;
2623 case 'year': // compatibility with "eval" (type "input")
2624 $itemValue = date('Y',$itemValue);
2625 break;
2626 case 'int':
2627 $baseArr = array('dec'=>'d','hex'=>'x','HEX'=>'X','oct'=>'o','bin'=>'b');
2628 $base = trim($config['format.']['base']);
2629 $format = $baseArr[$base] ? $baseArr[$base] : 'd';
2630 $itemValue = sprintf('%'.$format,$itemValue);
2631 break;
2632 case 'float':
2633 $precision = t3lib_div::intInRange($config['format.']['precision'],1,10,2);
2634 $itemValue = sprintf('%.'.$precision.'f',$itemValue);
2635 break;
2636 case 'number':
2637 $format = trim($config['format.']['option']);
2638 $itemValue = sprintf('%'.$format,$itemValue);
2639 break;
2640 case 'md5':
2641 $itemValue = md5($itemValue);
2642 break;
2643 case 'filesize':
2644 $value = t3lib_div::formatSize(intval($itemValue));
2645 if ($config['format.']['appendByteSize']) {
2646 $value .= ' ('.$itemValue.')';
2647 }
2648 $itemValue = $value;
2649 break;
2650 case 'user':
2651 $func = trim($config['format.']['userFunc']);
2652 if ($func) {
2653 $params = array(
2654 'value' => $itemValue,
2655 'args' => $config['format.']['userFunc'],
2656 'config' => $config,
2657 'pObj' => &$this
2658 );
2659 $itemValue = t3lib_div::callUserFunction($func,$params,$this);
2660 }
2661 break;
2662 default:
2663 break;
2664 }
2665
2666 return $itemValue;
2667 }
2668
2669
2670
2671
2672
2673
2674 /************************************************************
2675 *
2676 * "Configuration" fetching/processing functions
2677 *
2678 ************************************************************/
2679
2680 /**
2681 * Calculate and return the current "types" pointer value for a record
2682 *
2683 * @param string The table name. MUST be in $TCA
2684 * @param array The row from the table, should contain at least the "type" field, if applicable.
2685 * @return string Return the "type" value for this record, ready to pick a "types" configuration from the $TCA array.
2686 */
2687 function getRTypeNum($table,$row) {
2688 global $TCA;
2689 // If there is a "type" field configured...
2690 if ($TCA[$table]['ctrl']['type']) {
2691 $typeFieldName = $TCA[$table]['ctrl']['type'];
2692 $typeNum=$row[$typeFieldName]; // Get value of the row from the record which contains the type value.
2693 if (!strcmp($typeNum,'')) $typeNum=0; // If that value is an empty string, set it to "0" (zero)
2694 } else {
2695 $typeNum = 0; // If no "type" field, then set to "0" (zero)
2696 }
2697
2698 $typeNum = (string)$typeNum; // Force to string. Necessary for eg '-1' to be recognized as a type value.
2699 if (!$TCA[$table]['types'][$typeNum]) { // However, if the type "0" is not found in the "types" array, then default to "1" (for historical reasons)
2700 $typeNum = 1;
2701 }
2702
2703 return $typeNum;
2704 }
2705
2706 /**
2707 * Used to adhoc-rearrange the field order normally set in the [types][showitem] list
2708 *
2709 * @param array A [types][showitem] list of fields, exploded by ","
2710 * @return array Returns rearranged version (keys are changed around as well.)