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