900c08f4e4a8e4980f7e33bef01239276029834e
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Classes / Utility / CompatibilityLayerUtility.php
1 <?php
2 namespace TYPO3\CMS\Form\Utility;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Utility\GeneralUtility;
18 use TYPO3\CMS\Form\Domain\Builder\FormBuilder;
19 use TYPO3\CMS\Form\Domain\Model\Element;
20
21 /**
22 * Compatibility layer.
23 * Used in the scope of one(!) specific form element.
24 */
25 class CompatibilityLayerUtility
26 {
27 /**
28 * @param FormBuilder $formBuilder
29 * @return CompatibilityLayerUtility
30 */
31 public static function create(FormBuilder $formBuilder)
32 {
33 /** @var CompatibilityLayerUtility $compatibilityService */
34 $compatibilityService = \TYPO3\CMS\Form\Utility\FormUtility::getObjectManager()->get(CompatibilityLayerUtility::class);
35 $compatibilityService->setFormBuilder($formBuilder);
36 return $compatibilityService;
37 }
38
39 /**
40 * Layout array from form configuration
41 *
42 * @var array
43 */
44 protected $layout = array();
45
46 /**
47 * @var FormBuilder
48 */
49 protected $formBuilder;
50
51 /**
52 * @var array
53 */
54 protected $registeredFormElements = array(
55 'TEXTLINE',
56 'SUBMIT',
57 'RESET',
58 'RADIO',
59 'PASSWORD',
60 'IMAGEBUTTON',
61 'FILEUPLOAD',
62 'CHECKBOX',
63 'BUTTON',
64 'TEXTAREA',
65 'HIDDEN',
66 'CONTENTELEMENT',
67 'TEXTBLOCK',
68 'SELECT',
69 'FIELDSET',
70 'RADIOGROUP',
71 'CHECKBOXGROUP',
72 );
73
74 /**
75 * @var array
76 */
77 protected $elementsWithoutLabel = array(
78 'HIDDEN',
79 'CONTENTELEMENT',
80 'TEXTBLOCK',
81 'FIELDSET',
82 'RADIOGROUP',
83 'CHECKBOXGROUP',
84 );
85
86 /**
87 * @var array
88 */
89 protected $containerElements = array(
90 'FIELDSET',
91 'RADIOGROUP',
92 'CHECKBOXGROUP',
93 );
94
95 /**
96 * @param FormBuilder $formBuilder
97 */
98 public function setFormBuilder(FormBuilder $formBuilder)
99 {
100 $this->formBuilder = $formBuilder;
101 }
102
103 /**
104 * Set the layout configuration for one or more elements
105 *
106 * @param NULL|array $layout The configuration array
107 * @return void
108 * @deprecated since TYPO3 CMS 7, this function will be removed in TYPO3 CMS 8, as the functionality is now done via fluid
109 */
110 public function setGlobalLayoutConfiguration($layout = array())
111 {
112 GeneralUtility::deprecationLog('EXT:form: Do not use "layout." anymore. Deprecated since TYPO3 CMS 7, this function will be removed in TYPO3 CMS 8.');
113 if (is_array($layout)) {
114 foreach ($layout as $elementType => $elementValue) {
115 $elementType = strtoupper($elementType);
116 $this->layout[$elementType] = $elementValue;
117 }
118 }
119 }
120
121 /**
122 * Get the layout of the object
123 * Looks if there is an assigned layout by configuration of the element
124 * otherwise it will look if there is a layout set in the form configuration.
125 *
126 * @param string $elementType Type of element e.g BUTTON
127 * @return string The element layout
128 * @deprecated since TYPO3 CMS 7, this function will be removed in TYPO3 CMS 8, as the functionality is now done via fluid
129 */
130 public function getGlobalLayoutByElementType($elementType)
131 {
132 GeneralUtility::deprecationLog('EXT:form: Do not use "layout." anymore. Deprecated since TYPO3 CMS 7, this function will be removed in TYPO3 CMS 8.');
133 $layout = '';
134 if (!empty($this->layout[$elementType])) {
135 $layout = $this->layout[$elementType];
136 } else {
137 $action = $this->formBuilder->getControllerAction();
138 switch ($elementType) {
139 case 'FORM':
140 $layout = '<form><containerWrap /></form>';
141 break;
142 case 'CONFIRMATION':
143 $layout = '<containerWrap />';
144 break;
145 case 'HTML':
146 $layout = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body><table cellspacing="0"><containerWrap /></table></body></html>';
147 break;
148 case 'CONTAINERWRAP':
149 if ($action !== 'process') {
150 $layout = '<ol><elements /></ol>';
151 } else {
152 $layout = '<tbody><elements /></tbody>';
153 }
154 break;
155 case 'ELEMENTWRAP':
156 if ($action !== 'process') {
157 $layout = '<li><element /></li>';
158 } else {
159 $layout = '<tr><element /></tr>';
160 }
161 break;
162 case 'LABEL':
163 if ($action === 'show') {
164 $layout = '<label><labelvalue /><mandatory /><error /></label>';
165 } elseif ($action === 'confirmation') {
166 $layout = '<label><labelvalue /></label>';
167 } else {
168 $layout = '<em><labelvalue /></em>';
169 }
170 break;
171 case 'LEGEND':
172 if ($action !== 'process') {
173 $layout = '<legend><legendvalue /></legend>';
174 } else {
175 $layout = '<thead><tr><th colspan="2" align="left"><legendvalue /></th></tr></thead>';
176 }
177 break;
178 case 'MANDATORY':
179 if ($action !== 'process') {
180 $layout = '<em><mandatoryvalue /></em>';
181 } else {
182 $layout = '';
183 }
184 break;
185 case 'ERROR':
186 if ($action !== 'process') {
187 $layout = '<strong><errorvalue /></strong>';
188 } else {
189 $layout = '';
190 }
191 break;
192 case 'RADIOGROUP':
193 case 'CHECKBOXGROUP':
194 case 'FIELDSET':
195 if ($action !== 'process') {
196 $layout = '<fieldset><legend /><containerWrap /></fieldset>';
197 } else {
198 $layout = '<td colspan="2"><table cellspacing="0" style="padding-left: 20px; margin-bottom: 20px;"><legend /><containerWrap /></table></td>';
199 }
200 break;
201 case 'HIDDEN':
202 if ($action !== 'process') {
203 $layout = '<input />';
204 } else {
205 $layout = '';
206 }
207 break;
208 case 'SELECT':
209 if ($action === 'show') {
210 $layout = '<label /><select><elements /></select>';
211 } elseif ($action === 'confirmation') {
212 $layout = '<label /><ol><elements /></ol>';
213 } else {
214 $layout = '<td style="width: 200px;"><label /></td><td><elements /></td>';
215 }
216 break;
217 case 'TEXTAREA':
218 if ($action === 'show') {
219 $layout = '<label /><textarea />';
220 } elseif ($action === 'confirmation') {
221 $layout = '<label /><inputvalue />';
222 } else {
223 $layout = '<td style="width: 200px;" valign="top"><label /></td><td><inputvalue /></td>';
224 }
225 break;
226 case 'BUTTON':
227 case 'IMAGEBUTTON':
228 case 'PASSWORD':
229 case 'RESET':
230 case 'SUBMIT':
231 if ($action !== 'show') {
232 $layout = '';
233 break;
234 }
235 case 'CHECKBOX':
236 case 'FILEUPLOAD':
237 case 'RADIO':
238 case 'TEXTLINE':
239 if ($action === 'show') {
240 $layout = '<label /><input />';
241 } elseif ($action === 'confirmation') {
242 $layout = '<label /><inputvalue />';
243 } else {
244 $layout = '<td style="width: 200px;"><label /></td><td><inputvalue /></td>';
245 }
246 break;
247 }
248 }
249 return $layout;
250 }
251
252 /**
253 * Set the layout for a element
254 * Not supported / ignored: OPTGROUP, OPTION, layout.legend
255 *
256 * @param \TYPO3\CMS\Form\Domain\Model\Element $element
257 * @param array $userConfiguredElementTyposcript The configuration array
258 * @return void
259 * @deprecated since TYPO3 CMS 7, this function will be removed in TYPO3 CMS 8, as the functionality is now done via fluid
260 */
261 public function setElementLayouts(Element $element, array $userConfiguredElementTyposcript = array())
262 {
263 GeneralUtility::deprecationLog('EXT:form: Do not use "layout." anymore. Deprecated since TYPO3 CMS 7, this function will be removed in TYPO3 CMS 8.');
264 if ($element->getElementType() === 'FORM') {
265 $containerWrapReturn = $this->replaceTagWithMarker('elements', 'body', $this->getGlobalLayoutByElementType('CONTAINERWRAP'));
266 if ($this->formBuilder->getControllerAction() === 'show') {
267 $formWrapReturn = $this->replaceTagWithMarker('containerwrap', 'form', $this->getGlobalLayoutByElementType('FORM'));
268 } elseif ($this->formBuilder->getControllerAction() === 'confirmation') {
269 $formWrapReturn = $this->replaceTagWithMarker('containerwrap', 'body', $this->getGlobalLayoutByElementType('CONFIRMATION'));
270 } else {
271 $formWrapReturn = $this->replaceTagWithMarker('containerwrap', 'html', $this->getGlobalLayoutByElementType('HTML'));
272 }
273 $formLayout = str_replace($formWrapReturn['marker'], $containerWrapReturn['html'], $formWrapReturn['html']);
274 $formContainerWrap = explode($containerWrapReturn['marker'], $formLayout);
275 $layout['containerInnerWrap'] = $formContainerWrap;
276 $element->setLayout($layout);
277 $classFromLayout = $this->getElementClassFromLayout('form');
278 if (!empty($classFromLayout)) {
279 if (!empty($element->getAdditionalArgument('class'))) {
280 $classFromLayout .= ' ' . $element->getAdditionalArgument('class');
281 }
282 $element->setAdditionalArgument('class', $classFromLayout);
283 }
284 return;
285 }
286 if (in_array($element->getElementType(), $this->registeredFormElements)) {
287 /* Get the element layout definition or fallback to the global definition (if set) */
288 if (isset($userConfiguredElementTyposcript['layout'])) {
289 $elementLayout = $userConfiguredElementTyposcript['layout'];
290 } else {
291 $elementLayout = $this->getGlobalLayoutByElementType($element->getElementType());
292 }
293 /* if a element layout exist */
294 $elementWrap = null;
295 if ($elementLayout) {
296 $elementWrap = $this->determineElementOuterWraps($element->getElementType(), $elementLayout);
297 if ($elementWrap['html'] !== '') {
298 /* layout.label */
299 if (!in_array($element->getElementType(), $this->elementsWithoutLabel, true)) {
300 $labelLayout = $this->getGlobalLayoutByElementType('LABEL');
301 $mandatoryLayout = '';
302 $errorLayout = '';
303 if ($this->formBuilder->getControllerAction() === 'show') {
304 /* layout.mandatory */
305 $mandatoryMessages = $this->formBuilder->getValidationBuilder()->getMandatoryValidationMessagesByElementName($element->getName());
306 if (!empty($mandatoryMessages)) {
307 $mandatoryLayout = $this->replaceLabelContent('mandatory', $mandatoryMessages);
308 }
309 /* layout.error */
310 $errorMessages = $element->getValidationErrorMessages();
311 if (!empty($errorMessages)) {
312 $errorLayout = $this->replaceLabelContent('error', $errorMessages);
313 }
314 }
315 /* Replace the mandatory and error messages */
316 $mandatoryReturn = $this->replaceTagWithMarker('mandatory', 'body', $labelLayout);
317 $labelContainContent = false;
318 if ($mandatoryReturn['html'] !== '') {
319 if (!empty($mandatoryLayout)) {
320 $labelContainContent = true;
321 }
322 $labelLayout = str_replace($mandatoryReturn['marker'], $mandatoryLayout, $mandatoryReturn['html']);
323 }
324 $errorReturn = $this->replaceTagWithMarker('error', 'body', $labelLayout);
325 if ($errorReturn['html'] !== '') {
326 if (!empty($errorLayout)) {
327 $labelContainContent = true;
328 }
329 $labelLayout = str_replace($errorReturn['marker'], $errorLayout, $errorReturn['html']);
330 }
331 /* Replace the label value */
332 $labelValueReturn = $this->replaceTagWithMarker('labelvalue', 'body', $labelLayout);
333 if ($labelValueReturn['html'] !== '') {
334 if (!empty($element->getAdditionalArgument('label'))) {
335 $labelContainContent = true;
336 }
337 $labelLayout = str_replace($labelValueReturn['marker'], $element->getAdditionalArgument('label'), $labelValueReturn['html']);
338 }
339 if (!$labelContainContent) {
340 $labelLayout = '';
341 } else {
342 $libxmlUseInternalErrors = libxml_use_internal_errors(true);
343 $dom = new \DOMDocument('1.0', 'utf-8');
344 $dom->formatOutput = true;
345 $dom->preserveWhiteSpace = false;
346 if ($dom->loadXML($labelLayout)) {
347 $nodes = $dom->getElementsByTagName('label');
348 if ($nodes->length) {
349 $node = $nodes->item(0);
350 if ($node) {
351 $node->setAttribute('for', $element->getId());
352 $labelLayout = $dom->saveXML($dom->firstChild);
353 }
354 }
355 }
356 libxml_use_internal_errors($libxmlUseInternalErrors);
357 }
358 /* Replace <label />, <error /> and <mandatory /> in the element wrap html */
359 $labelReturn = $this->replaceTagWithMarker('label', 'body', $elementWrap['html']);
360 if ($labelReturn['html'] !== '') {
361 $elementWrap['html'] = str_replace($labelReturn['marker'], $labelLayout, $labelReturn['html']);
362 }
363 $errorReturn = $this->replaceTagWithMarker('error', 'body', $elementWrap['html']);
364 if ($errorReturn['html'] !== '') {
365 $elementWrap['html'] = str_replace($errorReturn['marker'], $errorLayout, $errorReturn['html']);
366 }
367 $mandatoryReturn = $this->replaceTagWithMarker('mandatory', 'body', $elementWrap['html']);
368 if ($mandatoryReturn['html'] !== '') {
369 $elementWrap['html'] = str_replace($mandatoryReturn['marker'], $mandatoryLayout, $mandatoryReturn['html']);
370 }
371 }
372 $elementWrap = explode($elementWrap['marker'], $elementWrap['html']);
373 } else {
374 $elementWrap = null;
375 }
376 }
377 /* Set element outer wraps and set the default classes */
378 $elementOuterWrap = null;
379 if ($this->getGlobalLayoutByElementType('ELEMENTWRAP')) {
380 $libxmlUseInternalErrors = libxml_use_internal_errors(true);
381 $dom = new \DOMDocument('1.0', 'utf-8');
382 $dom->formatOutput = true;
383 $dom->preserveWhiteSpace = false;
384 if ($dom->loadXML($this->getGlobalLayoutByElementType('ELEMENTWRAP'))) {
385 $node = $dom->firstChild;
386 if ($node) {
387 $class = '';
388 if ($node->getAttribute('class') !== '') {
389 $class = $node->getAttribute('class') . ' ';
390 }
391 $class .= 'csc-form-' . $element->getElementCounter() . ' csc-form-element csc-form-element-' . $element->getElementTypeLowerCase();
392 $node->setAttribute('class', $class);
393 $elementOuterWrap = $dom->saveXML($dom->firstChild);
394 $return = $this->replaceTagWithMarker('element', 'body', $elementOuterWrap);
395 if ($return['marker'] !== '') {
396 $elementOuterWrap = explode($return['marker'], $return['html']);
397 if ($element->getElementType() === 'SELECT') {
398 $layout = $element->getLayout();
399 $layout['optionOuterWrap'] = $elementOuterWrap;
400 $element->setLayout($layout);
401 }
402 } else {
403 /* this should never be happen */
404 $elementOuterWrap = null;
405 }
406 }
407 } else {
408 $elementOuterWrap = null;
409 }
410 libxml_use_internal_errors($libxmlUseInternalErrors);
411 }
412
413 if (
414 $elementWrap
415 && !$elementOuterWrap
416 ) {
417 /* If only $elementWrap isset */
418 $layout = $element->getLayout();
419 $layout['elementOuterWrap'] = $elementWrap;
420 $element->setLayout($layout);
421 } elseif (
422 !$elementWrap
423 && $elementOuterWrap
424 ) {
425 /* If only $elementOuterWrap isset */
426 $layout = $element->getLayout();
427 $layout['elementOuterWrap'] = $elementOuterWrap;
428 $element->setLayout($layout);
429 } elseif (
430 $elementWrap
431 && $elementOuterWrap
432 ) {
433 /* If $elementWrap isset and $elementOuterWrap isset */
434 $elementWrap = array(
435 $elementOuterWrap[0] . $elementWrap[0],
436 $elementWrap[1] . $elementOuterWrap[1],
437 );
438 $layout = $element->getLayout();
439 $layout['elementOuterWrap'] = $elementWrap;
440 $element->setLayout($layout);
441 }
442
443 /* Set container inner wraps */
444 if (in_array($element->getElementType(), $this->containerElements)) {
445 $elementWrap = $this->determineElementOuterWraps($element->getElementType(), $elementLayout);
446 /* Replace the legend value */
447 $legendLayout = $this->getGlobalLayoutByElementType('LEGEND');
448 $legendValueReturn = $this->replaceTagWithMarker('legendvalue', 'body', $legendLayout);
449 $legendContainContent = false;
450 if ($legendValueReturn['html'] !== '') {
451 if (!empty($element->getAdditionalArgument('legend'))) {
452 $legendContainContent = true;
453 }
454 $legendLayout = str_replace($legendValueReturn['marker'], $element->getAdditionalArgument('legend'), $legendValueReturn['html']);
455 }
456 /* remove <mandatory /> and <error /> from legend */
457 $mandatoryReturn = $this->replaceTagWithMarker('mandatory', 'body', $legendLayout);
458 if (!empty($mandatoryReturn['html'])) {
459 $legendLayout = str_replace($mandatoryReturn['marker'], '', $mandatoryReturn['html']);
460 }
461 $errorReturn = $this->replaceTagWithMarker('error', 'body', $legendLayout);
462 if (!empty($errorReturn['html'])) {
463 $legendLayout = str_replace($errorReturn['marker'], '', $errorReturn['html']);
464 }
465
466 if (!$legendContainContent) {
467 $legendLayout = '';
468 }
469 /* No fieldset tag exist.
470 * Ignore CONTAINERWRAP
471 * */
472 if ($elementWrap['html'] === '') {
473 $containerWrapReturn = $this->replaceTagWithMarker('elements', 'body', $elementLayout);
474 $legendReturn = $this->replaceTagWithMarker('legend', 'body', $containerWrapReturn['html']);
475
476 if ($legendReturn['html'] !== '') {
477 $containerWrapReturn['html'] = str_replace($legendReturn['marker'], $legendLayout, $legendReturn['html']);
478 }
479 if ($containerWrapReturn['marker'] && $containerWrapReturn['html']) {
480 $containerWrap = explode($containerWrapReturn['marker'], $containerWrapReturn['html']);
481 } else {
482 $containerWrap = array('', '');
483 }
484
485 $layout = $element->getLayout();
486 $layout['containerInnerWrap'] = $containerWrap;
487 $layout['noFieldsetTag'] = true;
488 $element->setLayout($layout);
489 } else {
490 $legendReturn = $this->replaceTagWithMarker('legend', 'body', $elementWrap['html']);
491
492 if ($legendReturn['html'] !== '') {
493 $elementWrap['html'] = str_replace($legendReturn['marker'], $legendLayout, $legendReturn['html']);
494 }
495
496 /* set the wraps */
497 $containerOuterWrap = array('', '');
498 $containerOuterWrap = explode($elementWrap['marker'], $elementWrap['html']);
499 $containerWrapReturn = $this->replaceTagWithMarker('elements', 'body', $this->getGlobalLayoutByElementType('CONTAINERWRAP'));
500 $containerInnerWrap = explode($containerWrapReturn['marker'], $containerWrapReturn['html']);
501
502 $containerWrap = array(
503 $containerOuterWrap[0] . $containerInnerWrap[0],
504 $containerInnerWrap[1] . $containerOuterWrap[1],
505 );
506
507 $layout = $element->getLayout();
508 $layout['containerInnerWrap'] = $containerWrap;
509 $element->setLayout($layout);
510 $classFromLayout = $this->getElementClassFromLayout('fieldset');
511 if (!empty($classFromLayout)) {
512 if (!empty($element->getHtmlAttribute('class'))) {
513 $classFromLayout .= ' ' . $element->getHtmlAttribute('class');
514 }
515 $element->setHtmlAttribute('class', $classFromLayout);
516 }
517 }
518 } else {
519 /* set class attribute for the element tag */
520 if ($this->formBuilder->getControllerAction() === 'show') {
521 if ($elementType === 'TEXTAREA') {
522 $tagName = 'textarea';
523 } elseif ($elementType === 'SELECT') {
524 $tagName = 'select';
525 } else {
526 $tagName = 'input';
527 }
528
529 $classFromLayout = $this->getElementClassFromLayout($element->getElementType(), $tagName);
530 if (!empty($classFromLayout)) {
531 if (!empty($element->getAdditionalArgument('class'))) {
532 $classFromLayout .= ' ' . $element->getAdditionalArgument('class');
533 }
534 $element->setAdditionalArgument('class', $classFromLayout);
535 }
536 }
537 }
538 }
539 }
540
541 /**
542 * Replace the message sections of a label.
543 * The scopes can be mandatory or error.
544 *
545 * @param string $scope
546 * @param array $messages
547 * @return string $html
548 */
549 protected function replaceLabelContent($scope = '', array $messages)
550 {
551 $messages = implode(' - ', $messages);
552 $return = $this->replaceTagWithMarker($scope . 'value', 'body', $this->getGlobalLayoutByElementType(strtoupper($scope)));
553 $html = str_replace($return['marker'], $messages, $return['html']);
554 return $html;
555 }
556
557 /**
558 * Return the class attribute for a element defined by layout.
559 *
560 * @param string $elementType
561 * @param string $tagName
562 * @return string
563 */
564 protected function getElementClassFromLayout($elementType = '', $tagName = '')
565 {
566 $class = '';
567 $libxmlUseInternalErrors = libxml_use_internal_errors(true);
568 $dom = new \DOMDocument('1.0', 'utf-8');
569 $dom->formatOutput = true;
570 $dom->preserveWhiteSpace = false;
571 if ($dom->loadXML($this->getGlobalLayoutByElementType(strtoupper($elementType)))) {
572 if ($tagName === '') {
573 $tagName = $elementType;
574 }
575 $nodes = $dom->getElementsByTagName($tagName);
576 if ($nodes->length) {
577 $node = $nodes->item(0);
578 if ($node && $node->getAttribute('class') !== '') {
579 $class = $node->getAttribute('class');
580 }
581 }
582 }
583 libxml_use_internal_errors($libxmlUseInternalErrors);
584 return $class;
585 }
586
587 /**
588 * Try to explode the element layout into 2 parts to get the
589 * outer wrapping
590 *
591 * @param string $elementType
592 * @param string $elementLayout
593 * @return string
594 * @deprecated since TYPO3 CMS 7, this function will be removed in TYPO3 CMS 8, as the functionality is now done via fluid
595 */
596 protected function determineElementOuterWraps($elementType, $elementLayout = '')
597 {
598 if ($this->formBuilder->getControllerAction() === 'show') {
599 if ($elementType === 'TEXTAREA') {
600 $return = $this->replaceTagWithMarker('textarea', 'body', $elementLayout);
601 } elseif ($elementType === 'CONTENTELEMENT') {
602 $return = $this->replaceTagWithMarker('content', 'body', $elementLayout);
603 } elseif ($elementType === 'SELECT') {
604 $return = $this->replaceTagWithMarker('select', 'body', $elementLayout);
605 } elseif (in_array($elementType, $this->containerElements)) {
606 $return = $this->replaceTagWithMarker('fieldset', 'body', $elementLayout);
607 } else {
608 $return = $this->replaceTagWithMarker('input', 'body', $elementLayout);
609 }
610 } else {
611 if ($elementType === 'CONTENTELEMENT') {
612 $return = $this->replaceTagWithMarker('content', 'body', $elementLayout);
613 } elseif ($elementType === 'SELECT') {
614 $return = $this->replaceTagWithMarker('elements', 'body', $elementLayout);
615 } elseif (in_array($elementType, $this->containerElements)) {
616 if ($this->formBuilder->getControllerAction() === 'confirmation') {
617 $return = $this->replaceTagWithMarker('fieldset', 'body', $elementLayout);
618 } else {
619 $return = $this->replaceTagWithMarker('containerwrap', 'body', $elementLayout);
620 }
621 } else {
622 $return = $this->replaceTagWithMarker('inputvalue', 'body', $elementLayout);
623 }
624 }
625 return $return;
626 }
627
628 /**
629 * Replace a html tag with a unique marker
630 *
631 * @param string $tagName
632 * @param string $stopTag
633 * @param string $html
634 * @return array
635 */
636 protected function replaceTagWithMarker($tagName, $stopTag = 'body', $html = '')
637 {
638 if (
639 $tagName === ''
640 || $html === ''
641 ) {
642 return array(
643 'html' => '',
644 'marker' => ''
645 );
646 }
647 $libxmlUseInternalErrors = libxml_use_internal_errors(true);
648 $dom = new \DOMDocument('1.0', 'utf-8');
649 $dom->preserveWhiteSpace = false;
650 if (!$dom->loadHTML($html)) {
651 libxml_use_internal_errors($libxmlUseInternalErrors);
652 return array(
653 'html' => '',
654 'marker' => ''
655 );
656 }
657 libxml_use_internal_errors($libxmlUseInternalErrors);
658 $nodes = $dom->getElementsByTagName($tagName);
659 if (!$nodes->length) {
660 return array(
661 'html' => '',
662 'marker' => ''
663 );
664 }
665 $nodeToReplace = $nodes->item(0);
666 /* Replace $tagname tag with a unique marker */
667 $marker = '###' . uniqid() . '###';
668 $markerNode = $dom->createTextNode($marker);
669 $replaceNode = $dom->createDocumentFragment();
670 $domNode = $dom->importNode($markerNode, true);
671 $replaceNode->appendChild($domNode);
672 $parentNode = $nodeToReplace->parentNode;
673 $parentNode->insertBefore($replaceNode, $nodeToReplace);
674 $parentNode->removeChild($nodeToReplace);
675 $nextParent = $parentNode;
676 /* Do not save the stop tag */
677 while ($nextParent !== null) {
678 if ($nextParent->tagName === $stopTag) {
679 break;
680 }
681 $nextParent = $nextParent->parentNode;
682 }
683 $html = '';
684 /* if stopTag == html, save the whole html */
685 if ($stopTag === 'html') {
686 $html = $nextParent->ownerDocument->saveHTML($nextParent);
687 } else {
688 /* do not save the stopTag */
689 $children = $nextParent->childNodes;
690 foreach ($children as $child) {
691 $html .= $nextParent->ownerDocument->saveHTML($child);
692 }
693 }
694 return array(
695 'html' => $html,
696 'marker' => $marker
697 );
698 }
699
700 /**
701 * Get new name for some old inconsistent attribute names
702 *
703 * @param string $elementType
704 * @param string $attributeName
705 * @return string
706 * @deprecated since TYPO3 CMS 7, this function will be removed in TYPO3 CMS 8, as the functionality is now done via fluid
707 */
708 public function getNewAttributeName($elementType, $attributeName)
709 {
710 if ($elementType === 'OPTION') {
711 if ($attributeName === 'data') {
712 GeneralUtility::deprecationLog('EXT:form: Deprecated since TYPO3 CMS 7, use text instead of data to configure the OPTION text');
713 $attributeName = 'text';
714 }
715 } elseif ($elementType === 'TEXTAREA') {
716 if ($attributeName === 'data') {
717 GeneralUtility::deprecationLog('EXT:form: Deprecated since TYPO3 CMS 7, use text instead of data to configure the TEXTAREA value');
718 $attributeName = 'text';
719 }
720 } elseif ($elementType === 'TEXTBLOCK') {
721 if ($attributeName === 'content') {
722 GeneralUtility::deprecationLog('EXT:form: Deprecated since TYPO3 CMS 7, use text instead of content to configure the TEXTBLOCK value');
723 $attributeName = 'text';
724 }
725 }
726 return $attributeName;
727 }
728 }