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