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