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