[BUGFIX] IRRE: Selected items remain in selector with foreign_unique
[Packages/TYPO3.CMS.git] / typo3 / sysext / cms / tslib / content / class.tslib_content_form.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2010-2011 Xavier Perseguers <typo3@perseguers.ch>
6 * (c) 2010-2011 Steffen Kamper <steffen@typo3.org>
7 * All rights reserved
8 *
9 * This script is part of the TYPO3 project. The TYPO3 project is
10 * free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * The GNU General Public License can be found at
16 * http://www.gnu.org/copyleft/gpl.html.
17 * A copy is found in the textfile GPL.txt and important notices to the license
18 * from the author is found in LICENSE.txt distributed with these scripts.
19 *
20 *
21 * This script is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * This copyright notice MUST APPEAR in all copies of the script!
27 ***************************************************************/
28
29 /**
30 * Contains FORM class object.
31 *
32 * @author Xavier Perseguers <typo3@perseguers.ch>
33 * @author Steffen Kamper <steffen@typo3.org>
34 */
35 class tslib_content_Form extends tslib_content_Abstract {
36
37 /**
38 * Rendering the cObject, FORM
39 *
40 * Note on $formData:
41 * In the optional $formData array each entry represents a line in the ordinary setup.
42 * In those entries each entry (0,1,2...) represents a space normally divided by the '|' line.
43 *
44 * $formData [] = array('Name:', 'name=input, 25 ', 'Default value....');
45 * $formData [] = array('Email:', 'email=input, 25 ', 'Default value for email....');
46 *
47 * - corresponds to the $conf['data'] value being :
48 * Name:|name=input, 25 |Default value....||Email:|email=input, 25 |Default value for email....
49 *
50 * If $formData is an array the value of $conf['data'] is ignored.
51 *
52 * @param array Array of TypoScript properties
53 * @param array Alternative formdata overriding whatever comes from TypoScript
54 * @return string Output
55 */
56 public function render($conf = array(), $formData = '') {
57 $content = '';
58 if (is_array($formData)) {
59 $dataArray = $formData;
60 } else {
61 $data = isset($conf['data.'])
62 ? $this->cObj->stdWrap($conf['data'], $conf['data.'])
63 : $conf['data'];
64 // Clearing dataArr
65 $dataArray = array();
66 // Getting the original config
67 if (trim($data)) {
68 $data = str_replace(LF, '||', $data);
69 $dataArray = explode('||', $data);
70 }
71 // Adding the new dataArray config form:
72 if (is_array($conf['dataArray.'])) { // dataArray is supplied
73 $sortedKeyArray = t3lib_TStemplate::sortedKeyList($conf['dataArray.'], TRUE);
74 foreach ($sortedKeyArray as $theKey) {
75 $singleKeyArray = $conf['dataArray.'][$theKey . '.'];
76 if (is_array($singleKeyArray)) {
77 $temp = array();
78 $label = isset($singleKeyArray['label.'])
79 ? $this->cObj->stdWrap($singleKeyArray['label'], $singleKeyArray['label.'])
80 : $singleKeyArray['label'];
81 list ($temp[0]) = explode('|', $label);
82 $type = isset($singleKeyArray['type.'])
83 ? $this->cObj->stdWrap($singleKeyArray['type'],$singleKeyArray['type.'])
84 : $singleKeyArray['type'];
85 list ($temp[1]) = explode('|', $type);
86 $required = isset($singleKeyArray['required.'])
87 ? $this->cObj->stdWrap($singleKeyArray['required'], $singleKeyArray['required.'])
88 : $singleKeyArray['required'];
89 if ($required) {
90 $temp[1] = '*' . $temp[1];
91 }
92 $singleValue = isset($singleKeyArray['value.'])
93 ? $this->cObj->stdWrap($singleKeyArray['value'], $singleKeyArray['value.'])
94 : $singleKeyArray['value'];
95 list ($temp[2]) = explode('|', $singleValue);
96 // If value array is set, then implode those values.
97 if (is_array($singleKeyArray['valueArray.'])) {
98 $temp_accumulated = array();
99 foreach ($singleKeyArray['valueArray.'] as $singleKey => $singleKey_valueArray) {
100 if (is_array($singleKey_valueArray) && !strcmp(intval($singleKey) . '.', $singleKey)) {
101 $temp_valueArray = array();
102 $valueArrayLabel = isset($singleKey_valueArray['label.'])
103 ? $this->cObj->stdWrap($singleKey_valueArray['label'], $singleKey_valueArray['label.'])
104 : $singleKey_valueArray['label'];
105 list ($temp_valueArray[0]) = explode('=', $valueArrayLabel);
106 $selected = isset($singleKeyArray['selected.'])
107 ? $this->cObj->stdWrap($singleKeyArray['selected'], $singleKeyArray['selected.'])
108 : $singleKeyArray['selected'];
109 if ($selected) {
110 $temp_valueArray[0] = '*' . $temp_valueArray[0];
111 }
112 $singleKeyValue = isset($singleKey_valueArray['value.'])
113 ? $this->cObj->stdWrap($singleKey_valueArray['value'], $singleKey_valueArray['value.'])
114 : $singleKey_valueArray['value'];
115 list ($temp_valueArray[1]) = explode(',', $singleKeyValue);
116 }
117 $temp_accumulated[] = implode('=', $temp_valueArray);
118 }
119 $temp[2] = implode(',', $temp_accumulated);
120 }
121 $specialEval = isset($singleKeyArray['specialEval.'])
122 ? $this->cObj->stdWrap($singleKeyArray['specialEval'], $singleKeyArray['specialEval.'])
123 : $singleKeyArray['specialEval'];
124 list ($temp[3]) = explode('|', $specialEval);
125
126 // adding the form entry to the dataArray
127 $dataArray[] = implode('|', $temp);
128 }
129 }
130 }
131 }
132
133 $attachmentCounter = '';
134 $hiddenfields = '';
135 $fieldlist = array();
136 $propertyOverride = array();
137 $fieldname_hashArray = array();
138 $counter = 0;
139
140 $xhtmlStrict = t3lib_div::inList('xhtml_strict,xhtml_11,xhtml_2', $GLOBALS['TSFE']->xhtmlDoctype);
141 // Formname
142 $formName = isset($conf['formName.'])
143 ? $this->cObj->stdWrap($conf['formName'], $conf['formName.'])
144 : $conf['formName'];
145 if ($formName) {
146 $formName = $this->cObj->cleanFormName($formName);
147 } else {
148 $formName = 'a' . $GLOBALS['TSFE']->uniqueHash(); // form name has to start with a letter to reach XHTML compliance
149 }
150
151 $fieldPrefix = isset($conf['fieldPrefix.'])
152 ? $this->cObj->stdWrap($conf['fieldPrefix'], $conf['fieldPrefix.'])
153 : $conf['fieldPrefix'];
154 if (isset($conf['fieldPrefix']) || isset($conf['fieldPrefix.'])) {
155 if ($fieldPrefix) {
156 $prefix = $this->cObj->cleanFormName($fieldPrefix);
157 } else {
158 $prefix = '';
159 }
160 } else {
161 $prefix = $formName;
162 }
163
164 foreach ($dataArray as $dataValue) {
165
166 $counter++;
167 $confData = array();
168 if (is_array($formData)) {
169 $parts = $dataValue;
170 $dataValue = 1; // TRUE...
171 } else {
172 $dataValue = trim($dataValue);
173 $parts = explode('|', $dataValue);
174 }
175 if ($dataValue && strcspn($dataValue, '#/')) {
176 // label:
177 $confData['label'] = t3lib_div::removeXSS(trim($parts[0]));
178 // field:
179 $fParts = explode(',', $parts[1]);
180 $fParts[0] = trim($fParts[0]);
181 if (substr($fParts[0], 0, 1) == '*') {
182 $confData['required'] = 1;
183 $fParts[0] = substr($fParts[0], 1);
184 }
185 $typeParts = explode('=', $fParts[0]);
186 $confData['type'] = trim(strtolower(end($typeParts)));
187 if (count($typeParts) == 1) {
188 $confData['fieldname'] = $this->cObj->cleanFormName($parts[0]);
189 if (strtolower(preg_replace('/[^[:alnum:]]/', '', $confData['fieldname'])) == 'email') {
190 $confData['fieldname'] = 'email';
191 }
192 // Duplicate fieldnames resolved
193 if (isset($fieldname_hashArray[md5($confData['fieldname'])])) {
194 $confData['fieldname'] .= '_' . $counter;
195 }
196 $fieldname_hashArray[md5($confData['fieldname'])] = $confData['fieldname'];
197 // Attachment names...
198 if ($confData['type'] == 'file') {
199 $confData['fieldname'] = 'attachment' . $attachmentCounter;
200 $attachmentCounter = intval($attachmentCounter) + 1;
201 }
202 } else {
203 $confData['fieldname'] = str_replace(' ', '_', trim($typeParts[0]));
204 }
205 $confData['fieldname'] = htmlspecialchars($confData['fieldname']);
206 $fieldCode = '';
207
208 $wrapFieldName = isset($conf['wrapFieldName'])
209 ? $this->cObj->stdWrap($conf['wrapFieldName'], $conf['wrapFieldName.'])
210 : $conf['wrapFieldName'];
211 if ($wrapFieldName) {
212 $confData['fieldname'] = $this->cObj->wrap($confData['fieldname'], $wrapFieldName);
213 }
214
215 // Set field name as current:
216 $this->cObj->setCurrentVal($confData['fieldname']);
217
218 // Additional parameters
219 if (trim($confData['type'])) {
220 if (isset($conf['params.'][$confData['type']])) {
221 $addParams = isset($conf['params.'][$confData['type'] . '.'])
222 ? trim($this->cObj->stdWrap($conf['params.'][$confData['type']], $conf['params.'][$confData['type'] . '.']))
223 : trim($conf['params.'][$confData['type']]);
224 } else {
225 $addParams = isset($conf['params.'])
226 ? trim($this->cObj->stdWrap($conf['params'], $conf['params.']))
227 : trim($conf['params']);
228 }
229 if (strcmp('', $addParams)) {
230 $addParams = ' ' . $addParams;
231 }
232 } else
233 $addParams = '';
234
235 $dontMd5FieldNames = isset($conf['dontMd5FieldNames.'])
236 ? $this->cObj->stdWrap($conf['dontMd5FieldNames'], $conf['dontMd5FieldNames.'])
237 : $conf['dontMd5FieldNames'];
238 if ($dontMd5FieldNames) {
239 $fName = $confData['fieldname'];
240 } else {
241 $fName = md5($confData['fieldname']);
242 }
243
244 // Accessibility: Set id = fieldname attribute:
245 $accessibility = isset($conf['accessibility.'])
246 ? $this->cObj->stdWrap($conf['accessibility'], $conf['accessibility.'])
247 : $conf['accessibility'];
248 if ($accessibility || $xhtmlStrict) {
249 $elementIdAttribute = ' id="' . $prefix . $fName . '"';
250 } else {
251 $elementIdAttribute = '';
252 }
253
254 // Create form field based on configuration/type:
255 switch ($confData['type']) {
256 case 'textarea' :
257 $cols = trim($fParts[1]) ? intval($fParts[1]) : 20;
258 $compensateFieldWidth = isset($conf['compensateFieldWidth.'])
259 ? $this->cObj->stdWrap($conf['compensateFieldWidth'], $conf['compensateFieldWidth.'])
260 : $conf['compensateFieldWidth'];
261 $compWidth = doubleval($compensateFieldWidth
262 ? $compensateFieldWidth
263 : $GLOBALS['TSFE']->compensateFieldWidth
264 );
265 $compWidth = $compWidth ? $compWidth : 1;
266 $cols = t3lib_utility_Math::forceIntegerInRange($cols * $compWidth, 1, 120);
267
268 $rows = trim($fParts[2]) ? t3lib_utility_Math::forceIntegerInRange($fParts[2], 1, 30) : 5;
269 $wrap = trim($fParts[3]);
270 $noWrapAttr = isset($conf['noWrapAttr.'])
271 ? $this->cObj->stdWrap($conf['noWrapAttr'], $conf['noWrapAttr.'])
272 : $conf['noWrapAttr'];
273 if ($noWrapAttr || $wrap === 'disabled') {
274 $wrap = '';
275 } else {
276 $wrap = $wrap ? ' wrap="' . $wrap . '"' : ' wrap="virtual"';
277 }
278 $noValueInsert = isset($conf['noValueInsert.'])
279 ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.'])
280 : $conf['noValueInsert'];
281 $default = $this->cObj->getFieldDefaultValue(
282 $noValueInsert,
283 $confData['fieldname'],
284 str_replace('\n', LF, trim($parts[2]))
285 );
286 $fieldCode = sprintf(
287 '<textarea name="%s"%s cols="%s" rows="%s"%s%s>%s</textarea>',
288 $confData['fieldname'],
289 $elementIdAttribute,
290 $cols,
291 $rows,
292 $wrap,
293 $addParams,
294 t3lib_div::formatForTextarea($default)
295 );
296 break;
297 case 'input' :
298 case 'password' :
299 $size = trim($fParts[1]) ? intval($fParts[1]) : 20;
300 $compensateFieldWidth = isset($conf['compensateFieldWidth.'])
301 ? $this->cObj->stdWrap($conf['compensateFieldWidth'], $conf['compensateFieldWidth.'])
302 : $conf['compensateFieldWidth'];
303 $compWidth = doubleval($compensateFieldWidth
304 ? $compensateFieldWidth
305 : $GLOBALS['TSFE']->compensateFieldWidth
306 );
307 $compWidth = $compWidth ? $compWidth : 1;
308 $size = t3lib_utility_Math::forceIntegerInRange($size * $compWidth, 1, 120);
309 $noValueInsert = isset($conf['noValueInsert.'])
310 ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.'])
311 : $conf['noValueInsert'];
312 $default = $this->cObj->getFieldDefaultValue(
313 $noValueInsert,
314 $confData['fieldname'],
315 trim($parts[2])
316 );
317
318 if ($confData['type'] == 'password') {
319 $default = '';
320 }
321
322 $max = trim($fParts[2]) ? ' maxlength="' . t3lib_utility_Math::forceIntegerInRange($fParts[2], 1, 1000) . '"' : "";
323 $theType = $confData['type'] == 'input' ? 'text' : 'password';
324
325 $fieldCode = sprintf(
326 '<input type="%s" name="%s"%s size="%s"%s value="%s"%s />',
327 $theType,
328 $confData['fieldname'],
329 $elementIdAttribute,
330 $size,
331 $max,
332 htmlspecialchars($default),
333 $addParams
334 );
335
336 break;
337 case 'file' :
338 $size = trim($fParts[1]) ? t3lib_utility_Math::forceIntegerInRange($fParts[1], 1, 60) : 20;
339 $fieldCode = sprintf(
340 '<input type="file" name="%s"%s size="%s"%s />',
341 $confData['fieldname'],
342 $elementIdAttribute,
343 $size,
344 $addParams
345 );
346 break;
347 case 'check' :
348 // alternative default value:
349 $noValueInsert = isset($conf['noValueInsert.'])
350 ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.'])
351 : $conf['noValueInsert'];
352 $default = $this->cObj->getFieldDefaultValue(
353 $noValueInsert,
354 $confData['fieldname'],
355 trim($parts[2])
356 );
357 $checked = $default ? ' checked="checked"' : '';
358 $fieldCode = sprintf(
359 '<input type="checkbox" value="%s" name="%s"%s%s%s />',
360 1,
361 $confData['fieldname'],
362 $elementIdAttribute,
363 $checked,
364 $addParams
365 );
366 break;
367 case 'select' :
368 $option = '';
369 $valueParts = explode(',', $parts[2]);
370 // size
371 if (strtolower(trim($fParts[1])) == 'auto') {
372 $fParts[1] = count($valueParts);
373 } // Auto size set here. Max 20
374 $size = trim($fParts[1]) ? t3lib_utility_Math::forceIntegerInRange($fParts[1], 1, 20) : 1;
375 // multiple
376 $multiple = strtolower(trim($fParts[2])) == 'm' ? ' multiple="multiple"' : '';
377
378 $items = array(); // Where the items will be
379 $defaults = array(); //RTF
380 $pCount = count($valueParts);
381 for ($a = 0; $a < $pCount; $a++) {
382 $valueParts[$a] = trim($valueParts[$a]);
383 if (substr($valueParts[$a], 0, 1) == '*') { // Finding default value
384 $sel = 'selected';
385 $valueParts[$a] = substr($valueParts[$a], 1);
386 } else
387 $sel = '';
388 // Get value/label
389 $subParts = explode('=', $valueParts[$a]);
390 $subParts[1] = (isset($subParts[1]) ? trim($subParts[1]) : trim($subParts[0])); // Sets the value
391 $items[] = $subParts; // Adds the value/label pair to the items-array
392 if ($sel) {
393 $defaults[] = $subParts[1];
394 } // Sets the default value if value/label pair is marked as default.
395 }
396 // alternative default value:
397 $noValueInsert = isset($conf['noValueInsert.'])
398 ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.'])
399 : $conf['noValueInsert'];
400 $default = $this->cObj->getFieldDefaultValue(
401 $noValueInsert,
402 $confData['fieldname'],
403 $defaults
404 );
405 if (!is_array($default)) {
406 $defaults = array();
407 $defaults[] = $default;
408 } else {
409 $defaults = $default;
410 }
411 // Create the select-box:
412 $iCount = count($items);
413 for ($a = 0; $a < $iCount; $a++) {
414 $option .= '<option value="' . $items[$a][1] . '"' . (in_array($items[$a][1], $defaults) ? ' selected="selected"' : '') . '>' . trim($items[$a][0]) . '</option>'; //RTF
415 }
416
417 if ($multiple) {
418 // The fieldname must be prepended '[]' if multiple select. And the reason why it's prepended is, because the required-field list later must also have [] prepended.
419 $confData['fieldname'] .= '[]';
420 }
421 $fieldCode = sprintf(
422 '<select name="%s"%s size="%s"%s%s>%s</select>',
423 $confData['fieldname'],
424 $elementIdAttribute,
425 $size,
426 $multiple,
427 $addParams,
428 $option
429 ); //RTF
430 break;
431 case 'radio' :
432 $option = '';
433
434 $valueParts = explode(',', $parts[2]);
435 $items = array(); // Where the items will be
436 $default = '';
437 $pCount = count($valueParts);
438 for ($a = 0; $a < $pCount; $a++) {
439 $valueParts[$a] = trim($valueParts[$a]);
440 if (substr($valueParts[$a], 0, 1) == '*') {
441 $sel = 'checked';
442 $valueParts[$a] = substr($valueParts[$a], 1);
443 } else
444 $sel = '';
445 // Get value/label
446 $subParts = explode('=', $valueParts[$a]);
447 $subParts[1] = (isset($subParts[1]) ? trim($subParts[1]) : trim($subParts[0])); // Sets the value
448 $items[] = $subParts; // Adds the value/label pair to the items-array
449 if ($sel) {
450 $default = $subParts[1];
451 } // Sets the default value if value/label pair is marked as default.
452 }
453 // alternative default value:
454 $noValueInsert = isset($conf['noValueInsert.'])
455 ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.'])
456 : $conf['noValueInsert'];
457 $default = $this->cObj->getFieldDefaultValue(
458 $noValueInsert,
459 $confData['fieldname'],
460 $default
461 );
462 // Create the select-box:
463 $iCount = count($items);
464 for ($a = 0; $a < $iCount; $a++) {
465 $optionParts = '';
466 $radioId = $prefix . $fName . $this->cObj->cleanFormName($items[$a][0]);
467 if ($accessibility) {
468 $radioLabelIdAttribute = ' id="' . $radioId . '"';
469 } else {
470 $radioLabelIdAttribute = '';
471 }
472 $optionParts .= '<input type="radio" name="' . $confData['fieldname'] . '"' .
473 $radioLabelIdAttribute . ' value="' . $items[$a][1] . '"' .
474 (!strcmp($items[$a][1], $default) ? ' checked="checked"' : '') . $addParams . ' />';
475 if ($accessibility) {
476 $label = isset($conf['radioWrap.'])
477 ? $this->cObj->stdWrap(trim($items[$a][0]), $conf['radioWrap.'])
478 : trim($items[$a][0]);
479 $optionParts .= '<label for="' . $radioId . '">' . $label . '</label>';
480 } else {
481 $optionParts .= isset($conf['radioWrap.'])
482 ? $this->cObj->stdWrap(trim($items[$a][0]), $conf['radioWrap.'])
483 : trim($items[$a][0]);
484 }
485 $option .= isset($conf['radioInputWrap.'])
486 ? $this->cObj->stdWrap($optionParts, $conf['radioInputWrap.'])
487 : $optionParts;
488 }
489
490 if ($accessibility) {
491 $accessibilityWrap = isset($conf['radioWrap.']['accessibilityWrap.'])
492 ? $this->cObj->stdWrap($conf['radioWrap.']['accessibilityWrap'], $conf['radioWrap.']['accessibilityWrap.'])
493 : $conf['radioWrap.']['accessibilityWrap.'];
494
495 if($accessibilityWrap) {
496 $search = array(
497 '###RADIO_FIELD_ID###', '###RADIO_GROUP_LABEL###'
498 );
499 $replace = array(
500 $elementIdAttribute, $confData['label']
501 );
502 $accessibilityWrap = str_replace($search, $replace, $accessibilityWrap);
503
504 $option = $this->cObj->wrap($option, $accessibilityWrap);
505 }
506 }
507
508 $fieldCode = $option;
509 break;
510 case 'hidden' :
511 $value = trim($parts[2]);
512
513 // If this form includes an auto responder message, include a HMAC checksum field
514 // in order to verify potential abuse of this feature.
515 if (strlen($value) && t3lib_div::inList($confData['fieldname'], 'auto_respond_msg')) {
516 $hmacChecksum = t3lib_div::hmac($value);
517 $hiddenfields .= sprintf(
518 '<input type="hidden" name="auto_respond_checksum" id="%sauto_respond_checksum" value="%s" />',
519 $prefix,
520 $hmacChecksum
521 );
522 }
523
524 if (strlen($value) && t3lib_div::inList('recipient_copy,recipient',
525 $confData['fieldname']) && $GLOBALS['TYPO3_CONF_VARS']['FE']['secureFormmail']) {
526 break;
527 }
528 if (strlen($value) && t3lib_div::inList('recipient_copy,recipient', $confData['fieldname'])) {
529 $value = $GLOBALS['TSFE']->codeString($value);
530 }
531 $hiddenfields .= sprintf(
532 '<input type="hidden" name="%s"%s value="%s" />',
533 $confData['fieldname'],
534 $elementIdAttribute,
535 htmlspecialchars($value)
536 );
537 break;
538 case 'property' :
539 if (t3lib_div::inList('type,locationData,goodMess,badMess,emailMess', $confData['fieldname'])) {
540 $value = trim($parts[2]);
541 $propertyOverride[$confData['fieldname']] = $value;
542 $conf[$confData['fieldname']] = $value;
543 }
544 break;
545 case 'submit' :
546 $value = trim($parts[2]);
547 if ($conf['image.']) {
548 $this->cObj->data[$this->cObj->currentValKey] = $value;
549 $image = $this->cObj->IMG_RESOURCE($conf['image.']);
550 $params = $conf['image.']['params'] ? ' ' . $conf['image.']['params'] : '';
551 $params .= $this->cObj->getAltParam($conf['image.'], FALSE);
552 $params .= $addParams;
553 } else {
554 $image = '';
555 }
556 if ($image) {
557 $fieldCode = sprintf(
558 '<input type="image" name="%s"%s src="%s"%s />',
559 $confData['fieldname'],
560 $elementIdAttribute,
561 $image,
562 $params
563 );
564 } else {
565 $fieldCode = sprintf(
566 '<input type="submit" name="%s"%s value="%s"%s />',
567 $confData['fieldname'],
568 $elementIdAttribute,
569 t3lib_div::deHSCentities(htmlspecialchars($value)),
570 $addParams
571 );
572 }
573 break;
574 case 'reset' :
575 $value = trim($parts[2]);
576 $fieldCode = sprintf(
577 '<input type="reset" name="%s"%s value="%s"%s />',
578 $confData['fieldname'],
579 $elementIdAttribute,
580 t3lib_div::deHSCentities(htmlspecialchars($value)),
581 $addParams
582 );
583 break;
584 case 'label' :
585 $fieldCode = nl2br(htmlspecialchars(trim($parts[2])));
586 break;
587 default :
588 $confData['type'] = 'comment';
589 $fieldCode = trim($parts[2]) . '&nbsp;';
590 break;
591 }
592 if ($fieldCode) {
593
594 // Checking for special evaluation modes:
595 if (t3lib_div::inList('textarea,input,password', $confData['type']) && strlen(trim($parts[3]))) {
596 $modeParameters = t3lib_div::trimExplode(':', $parts[3]);
597 } else {
598 $modeParameters = array();
599 }
600
601 // Adding evaluation based on settings:
602 switch ((string) $modeParameters[0]) {
603 case 'EREG' :
604 $fieldlist[] = '_EREG';
605 $fieldlist[] = $modeParameters[1];
606 $fieldlist[] = $modeParameters[2];
607 $fieldlist[] = $confData['fieldname'];
608 $fieldlist[] = $confData['label'];
609 $confData['required'] = 1; // Setting this so "required" layout is used.
610 break;
611 case 'EMAIL' :
612 $fieldlist[] = '_EMAIL';
613 $fieldlist[] = $confData['fieldname'];
614 $fieldlist[] = $confData['label'];
615 $confData['required'] = 1; // Setting this so "required" layout is used.
616 break;
617 default :
618 if ($confData['required']) {
619 $fieldlist[] = $confData['fieldname'];
620 $fieldlist[] = $confData['label'];
621 }
622 break;
623 }
624
625 // Field:
626 $fieldLabel = $confData['label'];
627 if ($accessibility && trim($fieldLabel) && !preg_match('/^(label|hidden|comment)$/', $confData['type'])) {
628 $fieldLabel = '<label for="' . $prefix . $fName . '">' . $fieldLabel . '</label>';
629 }
630
631 // Getting template code:
632 if(isset($conf['fieldWrap.'])) {
633 $fieldCode = $this->cObj->stdWrap($fieldCode, $conf['fieldWrap.']);
634 }
635 $labelCode = isset($conf['labelWrap.'])
636 ? $this->cObj->stdWrap($fieldLabel, $conf['labelWrap.'])
637 : $fieldLabel;
638 $commentCode = isset($conf['commentWrap.'])
639 ? $this->cObj->stdWrap($confData['label'], $conf['commentWrap.']) // RTF
640 : $confData['label'];
641 $result = $conf['layout'];
642 $req = isset($conf['REQ.'])
643 ? $this->cObj->stdWrap($conf['REQ'], $conf['REQ.'])
644 : $conf['REQ'];
645 if ($req && $confData['required']) {
646 if (isset($conf['REQ.']['fieldWrap.'])) {
647 $fieldCode = $this->cObj->stdWrap($fieldCode, $conf['REQ.']['fieldWrap.']);
648 }
649 if (isset($conf['REQ.']['labelWrap.'])) {
650 $labelCode = $this->cObj->stdWrap($fieldLabel, $conf['REQ.']['labelWrap.']);
651 }
652 $reqLayout = isset($conf['REQ.']['layout.'])
653 ? $this->cObj->stdWrap($conf['REQ.']['layout'], $conf['REQ.']['layout.'])
654 : $conf['REQ.']['layout'];
655 if ($reqLayout) {
656 $result = $reqLayout;
657 }
658 }
659 if ($confData['type'] == 'comment') {
660 $commentLayout = isset($conf['COMMENT.']['layout.'])
661 ? $this->cObj->stdWrap($conf['COMMENT.']['layout'], $conf['COMMENT.']['layout.'])
662 : $conf['COMMENT.']['layout'];
663 if ($commentLayout) {
664 $result = $commentLayout;
665 }
666 }
667 if ($confData['type'] == 'check') {
668 $checkLayout = isset($conf['CHECK.']['layout.'])
669 ? $this->cObj->stdWrap($conf['CHECK.']['layout'], $conf['CHECK.']['layout.'])
670 : $conf['CHECK.']['layout'];
671 if ($checkLayout) {
672 $result = $checkLayout;
673 }
674 }
675 if ($confData['type'] == 'radio') {
676 $radioLayout = isset($conf['RADIO.']['layout.'])
677 ? $this->cObj->stdWrap($conf['RADIO.']['layout'], $conf['RADIO.']['layout.'])
678 : $conf['RADIO.']['layout'];
679 if ($radioLayout) {
680 $result = $radioLayout;
681 }
682 }
683 if ($confData['type'] == 'label') {
684 $labelLayout = isset($conf['LABEL.']['layout.'])
685 ? $this->cObj->stdWrap($conf['LABEL.']['layout'], $conf['LABEL.']['layout.'])
686 : $conf['LABEL.']['layout'];
687 if ($labelLayout) {
688 $result = $labelLayout;
689 }
690 }
691 $result = str_replace('###FIELD###', $fieldCode, $result);
692 $result = str_replace('###LABEL###', $labelCode, $result);
693 $result = str_replace('###COMMENT###', $commentCode, $result); //RTF
694 $content .= $result;
695 }
696 }
697 }
698 if (isset($conf['stdWrap.'])) {
699 $content = $this->cObj->stdWrap($content, $conf['stdWrap.']);
700 }
701
702
703 // redirect (external: where to go afterwards. internal: where to submit to)
704 $theRedirect = isset($conf['redirect.'])
705 ? $this->cObj->stdWrap($conf['redirect'], $conf['redirect.'])
706 : $conf['redirect']; // redirect should be set to the page to redirect to after an external script has been used. If internal scripts is used, and if no 'type' is set that dictates otherwise, redirect is used as the url to jump to as long as it's an integer (page)
707 $target = isset($conf['target.'])
708 ? $this->cObj->stdWrap($conf['target'], $conf['target.'])
709 : $conf['target']; // redirect should be set to the page to redirect to after an external script has been used. If internal scripts is used, and if no 'type' is set that dictates otherwise, redirect is used as the url to jump to as long as it's an integer (page)
710 $noCache = isset($conf['no_cache.'])
711 ? $this->cObj->stdWrap($conf['no_cache'], $conf['no_cache.'])
712 : $conf['no_cache']; // redirect should be set to the page to redirect to after an external script has been used. If internal scripts is used, and if no 'type' is set that dictates otherwise, redirect is used as the url to jump to as long as it's an integer (page)
713 $page = $GLOBALS['TSFE']->page;
714 if (!$theRedirect) { // Internal: Just submit to current page
715 $LD = $GLOBALS['TSFE']->tmpl->linkData(
716 $page,
717 $target,
718 $noCache,
719 'index.php',
720 '',
721 $this->cObj->getClosestMPvalueForPage($page['uid'])
722 );
723 } elseif (t3lib_utility_Math::canBeInterpretedAsInteger($theRedirect)) { // Internal: Submit to page with ID $theRedirect
724 $page = $GLOBALS['TSFE']->sys_page->getPage_noCheck($theRedirect);
725 $LD = $GLOBALS['TSFE']->tmpl->linkData(
726 $page,
727 $target,
728 $noCache,
729 'index.php',
730 '',
731 $this->cObj->getClosestMPvalueForPage($page['uid'])
732 );
733 } else { // External URL, redirect-hidden field is rendered!
734 $LD = $GLOBALS['TSFE']->tmpl->linkData(
735 $page,
736 $target,
737 $noCache,
738 '',
739 '',
740 $this->cObj->getClosestMPvalueForPage($page['uid'])
741 );
742 $LD['totalURL'] = $theRedirect;
743 $hiddenfields .= '<input type="hidden" name="redirect" value="' . htmlspecialchars($LD['totalURL']) . '" />'; // 18-09-00 added
744 }
745
746 // Formtype (where to submit to!):
747 if($propertyOverride['type']) {
748 $formtype = $propertyOverride['type'];
749 } else {
750 $formtype = isset($conf['type.'])
751 ? $this->cObj->stdWrap($conf['type'], $conf['type.'])
752 : $conf['type'];
753 }
754 if (t3lib_utility_Math::canBeInterpretedAsInteger($formtype)) { // Submit to a specific page
755 $page = $GLOBALS['TSFE']->sys_page->getPage_noCheck($formtype);
756 $LD_A = $GLOBALS['TSFE']->tmpl->linkData(
757 $page,
758 $target,
759 $noCache,
760 '',
761 '',
762 $this->cObj->getClosestMPvalueForPage($page['uid'])
763 );
764 $action = $LD_A['totalURL'];
765 } elseif ($formtype) { // Submit to external script
766 $LD_A = $LD;
767 $action = $formtype;
768 } elseif (t3lib_utility_Math::canBeInterpretedAsInteger($theRedirect)) {
769 $LD_A = $LD;
770 $action = $LD_A['totalURL'];
771 } else { // Submit to "nothing" - which is current page
772 $LD_A = $GLOBALS['TSFE']->tmpl->linkData(
773 $GLOBALS['TSFE']->page,
774 $target,
775 $noCache,
776 '',
777 '',
778 $this->cObj->getClosestMPvalueForPage($page['uid'])
779 );
780 $action = $LD_A['totalURL'];
781 }
782
783 // Recipient:
784 $theEmail = isset($conf['recipient.'])
785 ? $this->cObj->stdWrap($conf['recipient'], $conf['recipient.'])
786 : $conf['recipient'];
787 if ($theEmail && !$GLOBALS['TYPO3_CONF_VARS']['FE']['secureFormmail']) {
788 $theEmail = $GLOBALS['TSFE']->codeString($theEmail);
789 $hiddenfields .= '<input type="hidden" name="recipient" value="' . htmlspecialchars($theEmail) . '" />';
790 }
791
792 // location data:
793 $location = isset($conf['locationData.'])
794 ? $this->cObj->stdWrap($conf['locationData'], $conf['locationData.'])
795 : $conf['locationData'];
796 if ($location) {
797 if ($location == 'HTTP_POST_VARS' && isset($_POST['locationData'])) {
798 $locationData = t3lib_div::_POST('locationData');
799 } else {
800 // locationData is [hte page id]:[tablename]:[uid of record]. Indicates on which page the record (from tablename with uid) is shown. Used to check access.
801 $locationData = $GLOBALS['TSFE']->id . ':' . $this->cObj->currentRecord;
802 }
803 $hiddenfields .= '<input type="hidden" name="locationData" value="' . htmlspecialchars($locationData) . '" />';
804 }
805
806 // hidden fields:
807 if (is_array($conf['hiddenFields.'])) {
808 foreach ($conf['hiddenFields.'] as $hF_key => $hF_conf) {
809 if (substr($hF_key, -1) != '.') {
810 $hF_value = $this->cObj->cObjGetSingle($hF_conf, $conf['hiddenFields.'][$hF_key . '.'], 'hiddenfields');
811 if (strlen($hF_value) && t3lib_div::inList('recipient_copy,recipient', $hF_key)) {
812 if ($GLOBALS['TYPO3_CONF_VARS']['FE']['secureFormmail']) {
813 continue;
814 }
815 $hF_value = $GLOBALS['TSFE']->codeString($hF_value);
816 }
817 $hiddenfields .= '<input type="hidden" name="' . $hF_key . '" value="' . htmlspecialchars($hF_value) . '" />';
818 }
819 }
820 }
821
822 // Wrap all hidden fields in a div tag (see http://bugs.typo3.org/view.php?id=678)
823 $hiddenfields = isset($conf['hiddenFields.']['stdWrap.'])
824 ? $this->cObj->stdWrap($hiddenfields, $conf['hiddenFields.']['stdWrap.'])
825 : '<div style="display:none;">' . $hiddenfields . '</div>';
826
827 if ($conf['REQ']) {
828 $goodMess = isset($conf['goodMess.'])
829 ? $this->cObj->stdWrap($conf['goodMess'], $conf['goodMess.'])
830 : $conf['goodMess'];
831 $badMess = isset($conf['badMess.'])
832 ? $this->cObj->stdWrap($conf['badMess'], $conf['badMess.'])
833 : $conf['badMess'];
834 $emailMess = isset($conf['emailMess.'])
835 ? $this->cObj->stdWrap($conf['emailMess'], $conf['emailMess.'])
836 : $conf['emailMess'];
837 $validateForm = ' onsubmit="return validateForm(\'' . $formName . '\',\'' . implode(',', $fieldlist)
838 . '\',' . t3lib_div::quoteJSvalue($goodMess) . ',' .
839 t3lib_div::quoteJSvalue($badMess) . ',' .
840 t3lib_div::quoteJSvalue($emailMess) . ')"';
841 $GLOBALS['TSFE']->additionalHeaderData['JSFormValidate'] = '<script type="text/javascript" src="' .
842 t3lib_div::createVersionNumberedFilename($GLOBALS['TSFE']->absRefPrefix .
843 't3lib/jsfunc.validateform.js') . '"></script>';
844 } else {
845 $validateForm = '';
846 }
847
848 // Create form tag:
849 $theTarget = ($theRedirect ? $LD['target'] : $LD_A['target']);
850 $method = isset($conf['method.'])
851 ? $this->cObj->stdWrap($conf['method'], $conf['method.'])
852 : $conf['method'];
853 $content = array(
854 '<form' . ' action="' . htmlspecialchars($action) . '"' . ' id="' .
855 $formName . '"' . ($xhtmlStrict ? '' : ' name="' . $formName . '"') .
856 ' enctype="' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'] . '"' .
857 ' method="' . ($method ? $method : 'post') . '"' .
858 ($theTarget ? ' target="' . $theTarget . '"' : '') .
859 $validateForm . '>', $hiddenfields . $content,
860 '</form>'
861 );
862
863 $arrayReturnMode = isset($conf['arrayReturnMode.'])
864 ? $this->cObj->stdWrap($conf['arrayReturnMode'], $conf['arrayReturnMode.'])
865 : $conf['arrayReturnMode'];
866 if ($arrayReturnMode) {
867 $content['validateForm'] = $validateForm;
868 $content['formname'] = $formName;
869 return $content;
870 } else {
871 return implode('', $content);
872 }
873 }
874
875 }
876
877
878 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['tslib/content/class.tslib_content_form.php'])) {
879 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['tslib/content/class.tslib_content_form.php']);
880 }
881
882 ?>