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