[BUGFIX] Streamline deprecation messages
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Form / FormDataProvider / DatabaseRowInitializeNew.php
1 <?php
2 namespace TYPO3\CMS\Backend\Form\FormDataProvider;
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\Backend\Form\FormDataProviderInterface;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19 use TYPO3\CMS\Core\Utility\MathUtility;
20
21 /**
22 * On "new" command, initialize new database row with default data
23 */
24 class DatabaseRowInitializeNew implements FormDataProviderInterface
25 {
26 /**
27 * Initialize new row with default values from various sources
28 * There are 4 sources of default values. Mind the order, the last takes precedence.
29 *
30 * @param array $result
31 * @return array
32 * @throws \UnexpectedValueException
33 */
34 public function addData(array $result)
35 {
36 if ($result['command'] !== 'new') {
37 return $result;
38 }
39 if (!is_array($result['databaseRow'])) {
40 throw new \UnexpectedValueException(
41 'databaseRow of table ' . $result['tableName'] . ' is not an array',
42 1444431128
43 );
44 }
45
46 $result = $this->setDefaultsFromUserTsConfig($result);
47 $result = $this->setDefaultsFromPageTsConfig($result);
48 $result = $this->setDefaultsFromNeighborRow($result);
49 $result = $this->setDefaultsFromDefaultValues($result);
50 $result = $this->setDefaultsFromInlineRelations($result);
51 $result = $this->setDefaultsFromInlineParentLanguage($result);
52 $result = $this->setPid($result);
53
54 return $result;
55 }
56
57 /**
58 * Set defaults defined by user ts "TCAdefaults"
59 *
60 * @param array $result Result array
61 * @return array Modified result array
62 */
63 protected function setDefaultsFromUserTsConfig(array $result)
64 {
65 $tableNameWithDot = $result['tableName'] . '.';
66 // Apply default values from user typo script "TCAdefaults" if any
67 if (isset($result['userTsConfig']['TCAdefaults.'][$tableNameWithDot])
68 && is_array($result['userTsConfig']['TCAdefaults.'][$tableNameWithDot])
69 ) {
70 foreach ($result['userTsConfig']['TCAdefaults.'][$tableNameWithDot] as $fieldName => $fieldValue) {
71 if (isset($result['processedTca']['columns'][$fieldName])) {
72 $result['databaseRow'][$fieldName] = $fieldValue;
73 }
74 }
75 }
76 return $result;
77 }
78
79 /**
80 * Set defaults defined by page ts "TCAdefaults"
81 *
82 * @param array $result Result array
83 * @return array Modified result array
84 */
85 protected function setDefaultsFromPageTsConfig(array $result)
86 {
87 $tableNameWithDot = $result['tableName'] . '.';
88 if (isset($result['pageTsConfig']['TCAdefaults.'][$tableNameWithDot])
89 && is_array($result['pageTsConfig']['TCAdefaults.'][$tableNameWithDot])
90 ) {
91 foreach ($result['pageTsConfig']['TCAdefaults.'][$tableNameWithDot] as $fieldName => $fieldValue) {
92 if (isset($result['processedTca']['columns'][$fieldName])) {
93 $result['databaseRow'][$fieldName] = $fieldValue;
94 }
95 }
96 }
97 return $result;
98 }
99
100 /**
101 * If a neighbor row is given (if vanillaUid was negative), field can be initialized with values
102 * from neighbor for fields registered in TCA['ctrl']['useColumnsForDefaultValues'].
103 *
104 * @param array $result Result array
105 * @return array Modified result array
106 */
107 protected function setDefaultsFromNeighborRow(array $result)
108 {
109 if (is_array($result['neighborRow'])
110 && !empty($result['processedTca']['ctrl']['useColumnsForDefaultValues'])
111 ) {
112 $defaultColumns = GeneralUtility::trimExplode(',', $result['processedTca']['ctrl']['useColumnsForDefaultValues'], true);
113 foreach ($defaultColumns as $fieldName) {
114 if (isset($result['processedTca']['columns'][$fieldName])
115 && isset($result['neighborRow'][$fieldName])
116 ) {
117 $result['databaseRow'][$fieldName] = $result['neighborRow'][$fieldName];
118 }
119 }
120 }
121 return $result;
122 }
123
124 /**
125 * Apply default values.
126 * These are typically carried around as "defVals" GET vars and set by controllers
127 * in $result['defaultValues'] array as init values.
128 *
129 * @param array $result Result array
130 * @return array Modified result array
131 */
132 protected function setDefaultsFromDefaultValues(array $result)
133 {
134 $result = $this->setDefaultValuesFromGetPost($result);
135 $tableName = $result['tableName'];
136 $defaultValues = $result['defaultValues'] ?? [];
137 if (isset($defaultValues[$tableName]) && is_array($defaultValues[$tableName])) {
138 foreach ($defaultValues[$tableName] as $fieldName => $fieldValue) {
139 if (isset($result['processedTca']['columns'][$fieldName])) {
140 $result['databaseRow'][$fieldName] = $fieldValue;
141 }
142 }
143 }
144 return $result;
145 }
146
147 /**
148 * @param array $result
149 * @return array
150 * @deprecated since v9 will be removed in v10 - see $result['defaultValues']
151 */
152 protected function setDefaultValuesFromGetPost(array $result)
153 {
154 if (!empty($result['defaultValues'])) {
155 return $result;
156 }
157
158 $defaultValues = GeneralUtility::_GP('defVals');
159 if (!empty($defaultValues)) {
160 trigger_error(
161 'Default values for new database rows should be set from controller context. Applying default values'
162 . ' via GET/POST parameters is deprecated since 9.2 and will be removed in version 10',
163 E_USER_DEPRECATED
164 );
165 $result['defaultValues'] = $defaultValues;
166 }
167
168 return $result;
169 }
170
171 /**
172 * Inline scenario if a new intermediate record to an existing child-child is
173 * compiled. Set "foreign_selector" field of this intermediate row to given
174 * "childChildUid". See TcaDataCompiler array comment of inlineChildChildUid
175 * for more details.
176 *
177 * @param array $result Result array
178 * @return array Modified result array
179 * @throws \UnexpectedValueException
180 */
181 protected function setDefaultsFromInlineRelations(array $result)
182 {
183 if ($result['inlineChildChildUid'] === null) {
184 return $result;
185 }
186 if (!is_int($result['inlineChildChildUid'])) {
187 throw new \UnexpectedValueException(
188 'An inlineChildChildUid is given for table ' . $result['tableName'] . ', but is not an integer',
189 1444434103
190 );
191 }
192 if (!isset($result['inlineParentConfig']['foreign_selector'])) {
193 throw new \UnexpectedValueException(
194 'An inlineChildChildUid is given for table ' . $result['tableName'] . ', but no foreign_selector in inlineParentConfig',
195 1444434102
196 );
197 }
198 $selectorFieldName = $result['inlineParentConfig']['foreign_selector'];
199 if (!isset($result['processedTca']['columns'][$selectorFieldName]['config']['type'])
200 || (
201 $result['processedTca']['columns'][$selectorFieldName]['config']['type'] !== 'select'
202 && $result['processedTca']['columns'][$selectorFieldName]['config']['type'] !== 'group'
203 )
204 ) {
205 throw new \UnexpectedValueException(
206 $selectorFieldName . ' is target type of a foreign_selector field to table ' . $result['tableName'] . ' and must be either a select or group type field',
207 1444434104
208 );
209 }
210
211 if ($result['inlineChildChildUid']) {
212 $result['databaseRow'][$selectorFieldName] = $result['inlineChildChildUid'];
213 }
214
215 return $result;
216 }
217
218 /**
219 * If a new child is created in an inline relation via ajax, and if the parent is a localized record,
220 * the child should have the same sys_language_uid set in the field declared in ['ctrl']['languageField']
221 * if the child is localizable itself.
222 * A localized parent transfers its sys_language_uid via inlineParentConfig['inline']['parentSysLanguageUid'],
223 * use that value as default for the child record languageField.
224 *
225 * @param array $result Result array
226 * @return array Modified result array
227 * @throws \UnexpectedValueException
228 */
229 protected function setDefaultsFromInlineParentLanguage(array $result): array
230 {
231 if (!isset($result['inlineParentConfig']['inline']['parentSysLanguageUid'])
232 || empty($result['processedTca']['ctrl']['languageField'])
233 || empty($result['processedTca']['ctrl']['transOrigPointerField'])
234 ) {
235 return $result;
236 }
237
238 if (!MathUtility::canBeInterpretedAsInteger($result['inlineParentConfig']['inline']['parentSysLanguageUid'])) {
239 throw new \UnexpectedValueException(
240 'A sys_language_uid is set from inline parent config but the value is no integer',
241 1490360772
242 );
243 }
244 $parentSysLanguageUid = (int)$result['inlineParentConfig']['inline']['parentSysLanguageUid'];
245 $languageFieldName = $result['processedTca']['ctrl']['languageField'];
246 $result['databaseRow'][$languageFieldName] = $parentSysLanguageUid;
247
248 return $result;
249 }
250
251 /**
252 * Set the pid. This is either the vanillaUid (see description in FormDataCompiler),
253 * or a pid given by pageTsConfig for inline children.
254 *
255 * @param array $result Result array
256 * @return array Modified result array
257 * @throws \UnexpectedValueException
258 */
259 protected function setPid(array $result)
260 {
261 // Set pid to vanillaUid. This can be a negative value
262 // if the record is added relative to another record.
263 $result['databaseRow']['pid'] = $result['vanillaUid'];
264
265 // In case a new inline record is created, the pid can be set to a different value
266 // by pageTsConfig, but not by userTsConfig. This overrides the above pid selection
267 // and forces the pid of new inline children.
268 $tableNameWithDot = $result['tableName'] . '.';
269 if ($result['isInlineChild'] && isset($result['pageTsConfig']['TCAdefaults.'][$tableNameWithDot]['pid'])) {
270 if (!MathUtility::canBeInterpretedAsInteger($result['pageTsConfig']['TCAdefaults.'][$tableNameWithDot]['pid'])) {
271 throw new \UnexpectedValueException(
272 'page TSConfig setting TCAdefaults.' . $tableNameWithDot . 'pid must be a number, but given string '
273 . $result['pageTsConfig']['TCAdefaults.'][$tableNameWithDot]['pid'] . ' can not be interpreted as integer',
274 1461598332
275 );
276 }
277 $result['databaseRow']['pid'] = (int)$result['pageTsConfig']['TCAdefaults.'][$tableNameWithDot]['pid'];
278 }
279
280 return $result;
281 }
282 }