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