[TASK] EXT:form - Optimize file upload/ handling of files
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Classes / Hooks / HandleIncomingFormValues.php
1 <?php
2 namespace TYPO3\CMS\Form\Hooks;
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\SingletonInterface;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19 use TYPO3\CMS\Form\Domain\Model\Element;
20 use TYPO3\CMS\Form\Domain\Model\ValidationElement;
21 use TYPO3\CMS\Form\Domain\Builder\FormBuilder;
22
23 /**
24 * Handle the incoming form data
25 */
26 class HandleIncomingFormValues implements SingletonInterface {
27
28 /**
29 * @var \TYPO3\CMS\Form\Utility\SessionUtility
30 */
31 protected $sessionUtility;
32
33 /**
34 * @param \TYPO3\CMS\Form\Utility\SessionUtility $sessionUtility
35 * @return void
36 */
37 public function injectSessionUtility(\TYPO3\CMS\Form\Utility\SessionUtility $sessionUtility) {
38 $this->sessionUtility = $sessionUtility;
39 }
40
41 /**
42 * Handle the incoming form data
43 *
44 * @param Element $element The element
45 * @param ValidationElement $validationElement
46 * @param mixed $modelValue
47 * @param FormBuilder $formBuilder
48 * @return void
49 */
50 public function handleIncomingFormValues(Element $element, ValidationElement $validationElement, $modelValue, FormBuilder $formBuilder) {
51 $elementName = $element->getName();
52
53 if ($element->getElementType() === 'CHECKBOX') {
54 $groupedElement = FALSE;
55 if ($element->getParentElement()->getElementType() === 'CHECKBOXGROUP') {
56 $incomingName = $element->getParentElement()->getName();
57 $groupedElement = TRUE;
58 } else {
59 $incomingName = $elementName;
60 }
61 $incomingData = $formBuilder->getIncomingData()->getIncomingField($incomingName);
62 $checked = FALSE;
63 if (is_array($incomingData)) {
64 if (
65 isset($incomingData[$elementName])
66 && $incomingData[$elementName] !== ''
67 ) {
68 $this->setAttribute($element, 'checked', 'checked');
69 $checked = TRUE;
70 } else {
71 $this->setAttribute($element, 'checked', NULL);
72 }
73 } else {
74 if (
75 (!empty($modelValue) && $incomingData === $modelValue)
76 || $incomingData === $incomingName . '-' . $element->getElementCounter()
77 ) {
78 $this->setAttribute($element, 'checked', 'checked');
79 $checked = TRUE;
80 } else {
81 $this->setAttribute($element, 'checked', NULL);
82 }
83 }
84 if (
85 $groupedElement
86 && $checked
87 ) {
88 $element->getParentElement()->setAdditionalArgument('atLeastOneCheckedChildElement', TRUE);
89 }
90 } elseif ($element->getElementType() === 'RADIO') {
91 $groupedElement = FALSE;
92 if ($element->getParentElement()->getElementType() === 'RADIOGROUP') {
93 $incomingName = $element->getParentElement()->getName();
94 $groupedElement = TRUE;
95 } else {
96 $incomingName = $elementName;
97 }
98 $checked = FALSE;
99 $incomingData = $formBuilder->getIncomingData()->getIncomingField($incomingName);
100 if (
101 (!empty($modelValue) && $incomingData === $modelValue)
102 || $incomingData === $incomingName . '-' . $element->getElementCounter()
103 ) {
104 $this->setAttribute($element, 'checked', 'checked');
105 $checked = TRUE;
106 } else {
107 $this->setAttribute($element, 'checked', NULL);
108 }
109 if (
110 $groupedElement
111 && $checked
112 ) {
113 $element->getParentElement()->setAdditionalArgument('atLeastOneCheckedChildElement', TRUE);
114 }
115 } elseif ($element->getElementType() === 'OPTION') {
116 $modelValue = (string)($element->getAdditionalArgument('value') ?: $element->getElementCounter());
117 if ($element->getParentElement()->getElementType() === 'OPTGROUP') {
118 $parentName = $element->getParentElement()->getParentElement()->getName();
119 } else {
120 $parentName = $element->getParentElement()->getName();
121 }
122 $incomingData = $formBuilder->getIncomingData()->getIncomingField($parentName);
123 /* Multiselect */
124 if (is_array($incomingData)) {
125 if (in_array($modelValue, $incomingData, TRUE)) {
126 $element->setHtmlAttribute('selected', 'selected');
127 } else {
128 $element->setHtmlAttribute('selected', NULL);
129 }
130 } else {
131 if ($modelValue === $incomingData) {
132 $element->setHtmlAttribute('selected', 'selected');
133 } else {
134 $element->setHtmlAttribute('selected', NULL);
135 }
136 }
137 } elseif ($element->getElementType() === 'TEXTAREA') {
138 $incomingData = $formBuilder->getIncomingData()->getIncomingField($elementName);
139 $element->setAdditionalArgument('text', $incomingData);
140 } elseif ($element->getElementType() === 'FILEUPLOAD') {
141 if (
142 $formBuilder->getValidationErrors() == NULL
143 || (
144 $formBuilder->getValidationErrors()
145 && $formBuilder->getValidationErrors()->forProperty($elementName)->hasErrors() !== TRUE
146 )
147 ) {
148 $uploadedFiles = $formBuilder->getIncomingData()->getIncomingField($elementName);
149 if (is_array($uploadedFiles)) {
150 foreach ($uploadedFiles as $key => &$file) {
151 $tempFilename = $this->saveUploadedFile($file['tmp_name']);
152 if (!$tempFilename) {
153 unset($uploadedFiles[$key]);
154 continue;
155 }
156 $file['tempFilename'] = $tempFilename;
157 }
158 $element->setAdditionalArgument('uploadedFiles', $uploadedFiles);
159 $this->setAttribute($element, 'value', '');
160 $this->sessionUtility->setSessionData($elementName, $uploadedFiles);
161 }
162 }
163 }
164 }
165
166 /**
167 * Save a uploaded file
168 *
169 * @param string $uploadedFile
170 * @return NULL|string
171 */
172 public function saveUploadedFile($uploadedFile) {
173 if (is_uploaded_file($uploadedFile)) {
174 $tempFilename = GeneralUtility::upload_to_tempfile($uploadedFile);
175 if (TYPO3_OS === 'WIN') {
176 $tempFilename = GeneralUtility::fixWindowsFilePath($tempFilename);
177 }
178 if ($tempFilename !== '') {
179 return $tempFilename;
180 }
181 }
182 return NULL;
183 }
184
185 /**
186 * Set the value Attribute to the right place
187 *
188 * @param Element $element The element
189 * @param string $key
190 * @param string $value
191 * @return void
192 */
193 public function setAttribute(Element $element, $key, $value = '') {
194 if ($element->getHtmlAttribute($key) !== NULL) {
195 $element->setHtmlAttribute($key, $value);
196 } else {
197 $element->setAdditionalArgument($key, $value);
198 }
199 }
200
201 }