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