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