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