[!!!][TASK] Drop core 6->7 auto TCA migrations
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Migrations / TcaMigration.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Core\Migrations;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19
20 /**
21 * Migrate TCA from old to new syntax. Used in bootstrap and Flex Form Data Structures.
22 *
23 * @internal Class and API may change any time.
24 */
25 class TcaMigration
26 {
27 /**
28 * Accumulate migration messages
29 *
30 * @var array
31 */
32 protected $messages = [];
33
34 /**
35 * Run some general TCA validations, then migrate old TCA to new TCA.
36 *
37 * This class is typically called within bootstrap with empty caches after all TCA
38 * files from extensions have been loaded. The migration is then applied and
39 * the migrated result is cached.
40 * For flex form TCA, this class is called dynamically if opening a record in the backend.
41 *
42 * See unit tests for details.
43 *
44 * @param array $tca
45 * @return array
46 */
47 public function migrate(array $tca): array
48 {
49 $this->validateTcaType($tca);
50
51 $tca = $this->migrateColumnsConfig($tca);
52 $tca = $this->migrateDefaultExtrasRteTransFormOptions($tca);
53 $tca = $this->migrateSelectTreeOptions($tca);
54 $tca = $this->migrateTSconfigSoftReferences($tca);
55 $tca = $this->migrateShowIfRteOption($tca);
56 $tca = $this->migrateWorkspacesOptions($tca);
57 $tca = $this->migrateTranslationTable($tca);
58 $tca = $this->migrateL10nModeDefinitions($tca);
59 $tca = $this->migratePageLocalizationDefinitions($tca);
60 $tca = $this->migrateInlineLocalizationMode($tca);
61 $tca = $this->migrateRequestUpdate($tca);
62 $tca = $this->migrateInputDateTimeToRenderType($tca);
63 $tca = $this->migrateWizardEnableByTypeConfigToColumnsOverrides($tca);
64 $tca = $this->migrateColorPickerWizardToRenderType($tca);
65 $tca = $this->migrateSelectWizardToValuePicker($tca);
66 $tca = $this->migrateSliderWizardToSliderConfiguration($tca);
67 $tca = $this->migrateLinkWizardToRenderTypeAndFieldControl($tca);
68 $tca = $this->migrateEditWizardToFieldControl($tca);
69 $tca = $this->migrateAddWizardToFieldControl($tca);
70 $tca = $this->migrateListWizardToFieldControl($tca);
71 $tca = $this->migrateLastPiecesOfDefaultExtras($tca);
72 $tca = $this->migrateTableWizardToRenderType($tca);
73 $tca = $this->migrateFullScreenRichtextToFieldControl($tca);
74 $tca = $this->migrateSuggestWizardTypeGroup($tca);
75 $tca = $this->migrateOptionsOfTypeGroup($tca);
76 $tca = $this->migrateSelectShowIconTable($tca);
77 $tca = $this->migrateImageManipulationConfig($tca);
78 $tca = $this->migrateInputDateTimeMax($tca);
79 $tca = $this->migrateInlineOverrideChildTca($tca);
80 $tca = $this->migrateLocalizeChildrenAtParentLocalization($tca);
81 $tca = $this->migratePagesLanguageOverlayRemoval($tca);
82 $tca = $this->deprecateTypeGroupInternalTypeFile($tca);
83 return $tca;
84 }
85
86 /**
87 * Get messages of migrated fields. Can be used for deprecation messages after migrate() was called.
88 *
89 * @return array Migration messages
90 */
91 public function getMessages(): array
92 {
93 return $this->messages;
94 }
95
96 /**
97 * Check for required TCA configuration
98 *
99 * @param array $tca Incoming TCA
100 */
101 protected function validateTcaType(array $tca)
102 {
103 foreach ($tca as $table => $tableDefinition) {
104 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
105 continue;
106 }
107 foreach ($tableDefinition['columns'] as $fieldName => $fieldConfig) {
108 if (isset($fieldConfig['config']) && is_array($fieldConfig['config']) && empty($fieldConfig['config']['type'])) {
109 throw new \UnexpectedValueException(
110 'Missing "type" in TCA of field "[\'' . $table . '\'][\'' . $fieldName . '\'][\'config\']".',
111 1482394401
112 );
113 }
114 }
115 }
116 }
117
118 /**
119 * Find columns fields that don't have a 'config' section at all, add
120 * ['config']['type'] = 'none'; for those to enforce config
121 *
122 * @param array $tca Incoming TCA
123 * @return array
124 */
125 protected function migrateColumnsConfig(array $tca): array
126 {
127 foreach ($tca as $table => &$tableDefinition) {
128 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
129 continue;
130 }
131 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
132 if ((!isset($fieldConfig['config']) || !is_array($fieldConfig['config'])) && !isset($fieldConfig['type'])) {
133 $fieldConfig['config'] = [
134 'type' => 'none',
135 ];
136 $this->messages[] = 'TCA table "' . $table . '" columns field "' . $fieldName . '"'
137 . ' had no mandatory "config" section. This has been added with default type "none":'
138 . ' TCA "' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'type\'] = \'none\'"';
139 }
140 }
141 }
142 return $tca;
143 }
144
145 /**
146 * Migrate defaultExtras "richtext:rte_transform[mode=ts_css]" and similar stuff like
147 * "richtext:rte_transform[mode=ts_css]" to "richtext:rte_transform"
148 *
149 * @param array $tca
150 * @return array Migrated TCA
151 */
152 protected function migrateDefaultExtrasRteTransFormOptions(array $tca): array
153 {
154 foreach ($tca as $table => &$tableDefinition) {
155 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
156 continue;
157 }
158 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
159 if (isset($fieldConfig['defaultExtras'])) {
160 $originalValue = $fieldConfig['defaultExtras'];
161 $defaultExtrasArray = GeneralUtility::trimExplode(':', $originalValue, true);
162 $isRichtextField = false;
163 foreach ($defaultExtrasArray as $defaultExtrasField) {
164 if (strpos($defaultExtrasField, 'richtext') === 0) {
165 $isRichtextField = true;
166 $fieldConfig['config']['enableRichtext'] = true;
167 $fieldConfig['config']['richtextConfiguration'] = 'default';
168 }
169 }
170 if ($isRichtextField) {
171 unset($fieldConfig['defaultExtras']);
172 $this->messages[] = 'RTE configuration via \'defaultExtras\' options are deprecated. String "' . $originalValue . '" in TCA'
173 . ' ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'defaultExtras\'] was changed to'
174 . ' options in ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']';
175 }
176 }
177 }
178 }
179
180 foreach ($tca as $table => &$tableDefinition) {
181 if (!isset($tableDefinition['types']) || !is_array($tableDefinition['types'])) {
182 continue;
183 }
184 foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
185 if (!isset($typeArray['columnsOverrides']) || !is_array($typeArray['columnsOverrides'])) {
186 continue;
187 }
188 foreach ($typeArray['columnsOverrides'] as $fieldName => &$fieldConfig) {
189 if (isset($fieldConfig['defaultExtras'])) {
190 $originalValue = $fieldConfig['defaultExtras'];
191 $defaultExtrasArray = GeneralUtility::trimExplode(':', $originalValue, true);
192 $isRichtextField = false;
193 foreach ($defaultExtrasArray as $defaultExtrasField) {
194 if (strpos($defaultExtrasField, 'richtext') === 0) {
195 $isRichtextField = true;
196 $fieldConfig['config']['enableRichtext'] = true;
197 $fieldConfig['config']['richtextConfiguration'] = 'default';
198 }
199 }
200 if ($isRichtextField) {
201 unset($fieldConfig['defaultExtras']);
202 $this->messages[] = 'RTE configuration via \'defaultExtras\' options are deprecated. String "' . $originalValue . '" in TCA'
203 . ' ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\'][\'defaultExtras\']' .
204 ' was changed to options in ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']';
205 }
206 }
207 }
208 }
209 }
210
211 return $tca;
212 }
213
214 /**
215 * Migrates selectTree fields deprecated options
216 *
217 * @param array $tca Incoming TCA
218 * @return array Migrated TCA
219 */
220 protected function migrateSelectTreeOptions(array $tca): array
221 {
222 foreach ($tca as $table => &$tableDefinition) {
223 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
224 continue;
225 }
226 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
227 if (isset($fieldConfig['config']['renderType']) && $fieldConfig['config']['renderType'] === 'selectTree') {
228 if (isset($fieldConfig['config']['treeConfig']['appearance']['width'])) {
229 $this->messages[] = 'The selectTree field [\'treeConfig\'][\'appearance\'][\'width\'] setting is deprecated'
230 . ' and was removed in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
231 . '[\'treeConfig\'][\'appearance\'][\'width\'] ';
232 unset($fieldConfig['config']['treeConfig']['appearance']['width']);
233 }
234
235 if (isset($fieldConfig['config']['treeConfig']['appearance']['allowRecursiveMode'])) {
236 $this->messages[] = 'The selectTree field [\'treeConfig\'][\'appearance\'][\'allowRecursiveMode\'] setting is deprecated'
237 . ' and was removed in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
238 . '[\'treeConfig\'][\'appearance\'][\'allowRecursiveMode\'] ';
239 unset($fieldConfig['config']['treeConfig']['appearance']['allowRecursiveMode']);
240 }
241
242 if (isset($fieldConfig['config']['autoSizeMax'])) {
243 $this->messages[] = 'The selectTree field [\'autoSizeMax\'] setting is deprecated'
244 . ' and was removed in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'autoSizeMax\'].'
245 . ' The \'size\' value was adapted to the previous autoSizeMax value';
246 $fieldConfig['config']['size'] = $fieldConfig['config']['autoSizeMax'];
247 unset($fieldConfig['config']['autoSizeMax']);
248 }
249 }
250 }
251 }
252 return $tca;
253 }
254
255 /**
256 * Migrates selectTree fields deprecated options
257 *
258 * @param array $tca Incoming TCA
259 * @return array Migrated TCA
260 */
261 protected function migrateTSconfigSoftReferences(array $tca): array
262 {
263 foreach ($tca as $table => &$tableDefinition) {
264 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
265 continue;
266 }
267 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
268 if (isset($fieldConfig['config'])) {
269 if (isset($fieldConfig['config']['softref'])) {
270 $softReferences = array_flip(GeneralUtility::trimExplode(',', $fieldConfig['config']['softref']));
271 $changed = false;
272 if (isset($softReferences['TSconfig'])) {
273 $changed = true;
274 unset($softReferences['TSconfig']);
275 }
276 if (isset($softReferences['TStemplate'])) {
277 $changed = true;
278 unset($softReferences['TStemplate']);
279 }
280 if ($changed) {
281 if (!empty($softReferences)) {
282 $softReferences = array_flip($softReferences);
283 $fieldConfig['config']['softref'] = implode(',', $softReferences);
284 } else {
285 unset($fieldConfig['config']['softref']);
286 }
287 $this->messages[] = 'The soft reference setting using \'TSconfig\' and '
288 . '\'TStemplate\' was removed in TCA ' . $table . '[\'columns\']'
289 . '[\'' . $fieldName . '\'][\'config\'][\'softref\']';
290 }
291 }
292 }
293 }
294 }
295 return $tca;
296 }
297
298 /**
299 * Removes the option "showIfRTE" for TCA type "check"
300 *
301 * @param array $tca Incoming TCA
302 * @return array Migrated TCA
303 */
304 protected function migrateShowIfRteOption(array $tca): array
305 {
306 foreach ($tca as $table => &$tableDefinition) {
307 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
308 continue;
309 }
310 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
311 if (isset($fieldConfig['config']) && $fieldConfig['config']['type'] === 'check') {
312 if (isset($fieldConfig['config']['showIfRTE'])) {
313 unset($fieldConfig['config']['showIfRTE']);
314 $this->messages[] = 'The TCA setting \'showIfRTE\' was removed '
315 . 'in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']';
316 }
317 }
318 }
319 }
320 return $tca;
321 }
322
323 /**
324 * Casts "versioningWS" to bool, and removes "versioning_followPages"
325 *
326 * @param array $tca Incoming TCA
327 * @return array Migrated TCA
328 */
329 protected function migrateWorkspacesOptions(array $tca): array
330 {
331 foreach ($tca as $table => &$tableDefinition) {
332 if (isset($tableDefinition['ctrl']['versioningWS']) && !is_bool($tableDefinition['ctrl']['versioningWS'])) {
333 $tableDefinition['ctrl']['versioningWS'] = (bool)$tableDefinition['ctrl']['versioningWS'];
334 $this->messages[] = 'The TCA setting \'versioningWS\' was set to a boolean value '
335 . 'in TCA ' . $table . '[\'ctrl\'][\'versioningWS\']';
336 }
337 if (isset($tableDefinition['ctrl']['versioning_followPages']) && !empty($tableDefinition['ctrl']['versioning_followPages'])) {
338 unset($tableDefinition['ctrl']['versioning_followPages']);
339 $this->messages[] = 'The TCA setting \'versioning_followPages\' was removed as it is unused '
340 . 'in TCA ' . $table . '[\'ctrl\'][\'versioning_followPages\']';
341 }
342 }
343 return $tca;
344 }
345
346 /**
347 * Removes "transForeignTable" and "transOrigPointerTable" which has been
348 * used for tables "pages" and "pages_languages_overlay" in the core only.
349 *
350 * @param array $tca Incoming TCA
351 * @return array Migrated TCA
352 */
353 protected function migrateTranslationTable(array $tca): array
354 {
355 foreach ($tca as $table => &$tableDefinition) {
356 if (!empty($tableDefinition['ctrl']['transForeignTable'])) {
357 unset($tableDefinition['ctrl']['transForeignTable']);
358 $this->messages[] = 'The TCA setting \'transForeignTable\' was removed '
359 . 'in TCA ' . $table . '[\'ctrl\'][\'transForeignTable\']';
360 }
361 if (!empty($tableDefinition['ctrl']['transOrigPointerTable'])) {
362 unset($tableDefinition['ctrl']['transOrigPointerTable']);
363 $this->messages[] = 'The TCA setting \'transOrigPointerTable\' was removed '
364 . 'in TCA ' . $table . '[\'ctrl\'][\'transOrigPointerTable\']';
365 }
366 }
367 return $tca;
368 }
369
370 /**
371 * Removes "noCopy" from possible settings for "l10n_mode" for each column.
372 *
373 * @param array $tca
374 * @return array Migrated TCA
375 */
376 protected function migrateL10nModeDefinitions(array $tca)
377 {
378 foreach ($tca as $table => &$tableDefinition) {
379 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
380 continue;
381 }
382 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
383 if (empty($fieldConfig['l10n_mode'])) {
384 continue;
385 }
386 if ($fieldConfig['l10n_mode'] === 'noCopy') {
387 unset($fieldConfig['l10n_mode']);
388 $this->messages[] = 'The TCA setting \'noCopy\' was removed '
389 . 'in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'l10n_mode\']';
390 }
391 if (!empty($fieldConfig['l10n_mode']) && $fieldConfig['l10n_mode'] === 'mergeIfNotBlank') {
392 unset($fieldConfig['l10n_mode']);
393 if (empty($fieldConfig['config']['behaviour']['allowLanguageSynchronization'])) {
394 $fieldConfig['config']['behaviour']['allowLanguageSynchronization'] = true;
395 }
396 $this->messages[] = 'The TCA setting \'mergeIfNotBlank\' was removed '
397 . 'in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'l10n_mode\']'
398 . ' and changed to ' . $table . '[\'columns\'][\'' . $fieldName . '\']'
399 . '[\'config\'][\'behaviour\'][\'allowLanguageSynchronization\'] = true';
400 }
401 }
402 }
403 return $tca;
404 }
405
406 /**
407 * Migrates localization definitions such as "allowLanguageSynchronization"
408 * or "l10n_mode" for tables pages and pages_language_overlay.
409 *
410 * @param array $tca
411 * @return array Migrated TCA
412 */
413 protected function migratePageLocalizationDefinitions(array $tca)
414 {
415 if (
416 empty($tca['pages_language_overlay']['columns'])
417 ) {
418 return $tca;
419 }
420
421 // ensure, that localization settings are defined for
422 // pages and not for pages_language_overlay
423 foreach ($tca['pages_language_overlay']['columns'] as $fieldName => &$fieldConfig) {
424 $l10nMode = $fieldConfig['l10n_mode'] ?? null;
425 $allowLanguageSynchronization = $fieldConfig['config']['behaviour']['allowLanguageSynchronization'] ?? null;
426
427 $oppositeFieldConfig = $tca['pages']['columns'][$fieldName] ?? [];
428 $oppositeL10nMode = $oppositeFieldConfig['l10n_mode'] ?? null;
429 $oppositeAllowLanguageSynchronization = $oppositeFieldConfig['config']['behaviour']['allowLanguageSynchronization'] ?? null;
430
431 if ($l10nMode !== null) {
432 if (!empty($oppositeFieldConfig) && $oppositeL10nMode !== 'exclude') {
433 $tca['pages']['columns'][$fieldName]['l10n_mode'] = $l10nMode;
434 $this->messages[] = 'The TCA setting \'l10n_mode\' was migrated '
435 . 'to TCA pages[\'columns\'][\'' . $fieldName . '\'][\'l10n_mode\'] '
436 . 'from TCA pages_language_overlay[\'columns\'][\'' . $fieldName . '\'][\'l10n_mode\']';
437 }
438 }
439
440 if (!empty($allowLanguageSynchronization) && empty($oppositeAllowLanguageSynchronization)) {
441 $tca['pages']['columns'][$fieldName]['config']['behaviour']['allowLanguageSynchronization'] = (bool)$allowLanguageSynchronization;
442 $this->messages[] = 'The TCA setting \'allowLanguageSynchronization\' was migrated '
443 . 'to TCA pages[\'columns\'][\'' . $fieldName . '\']'
444 . '[\'config\'][\'behaviour\'][\'allowLanguageSynchronization\'] '
445 . 'from TCA pages_language_overlay[\'columns\'][\'' . $fieldName . '\']'
446 . '[\'config\'][\'behaviour\'][\'allowLanguageSynchronization\']';
447 }
448 }
449
450 return $tca;
451 }
452
453 /**
454 * Removes "localizationMode" set to "keep" if used in combination with
455 * "allowLanguageSynchronization" - in general "localizationMode" is
456 * deprecated since TYPO3 CMS 8 and will be removed in TYPO3 v9.
457 *
458 * @param array $tca
459 * @return array
460 */
461 protected function migrateInlineLocalizationMode(array $tca)
462 {
463 foreach ($tca as $table => &$tableDefinition) {
464 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
465 continue;
466 }
467 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
468 if (($fieldConfig['config']['type'] ?? null) !== 'inline') {
469 continue;
470 }
471
472 $inlineLocalizationMode = ($fieldConfig['config']['behaviour']['localizationMode'] ?? null);
473 if ($inlineLocalizationMode === null) {
474 continue;
475 }
476
477 $allowLanguageSynchronization = ($fieldConfig['config']['behaviour']['allowLanguageSynchronization'] ?? null);
478 if ($inlineLocalizationMode === 'keep' && $allowLanguageSynchronization) {
479 unset($fieldConfig['config']['behaviour']['localizationMode']);
480 $this->messages[] = 'The TCA setting \'localizationMode\' is counter-productive '
481 . ' if being used in combination with \'allowLanguageSynchronization\' and '
482 . ' thus has been removed from TCA for ' . $table . '[\'columns\']'
483 . '[\'' . $fieldName . '\'][\'config\'][\'behaviour\'][\'localizationMode\']';
484 } else {
485 $this->messages[] = 'The TCA setting \'localizationMode\' is deprecated '
486 . ' and should be removed from TCA for ' . $table . '[\'columns\']'
487 . '[\'' . $fieldName . '\'][\'config\'][\'behaviour\'][\'localizationMode\']';
488 }
489 }
490 }
491 return $tca;
492 }
493
494 /**
495 * Move ['ctrl']['requestUpdate'] to 'onChange => "reload"' of single fields
496 *
497 * @param array $tca Incoming TCA
498 * @return array Migrated TCA
499 */
500 protected function migrateRequestUpdate(array $tca): array
501 {
502 foreach ($tca as $table => &$tableDefinition) {
503 if (!empty($tableDefinition['ctrl']['requestUpdate'])) {
504 $fields = GeneralUtility::trimExplode(',', $tableDefinition['ctrl']['requestUpdate']);
505 foreach ($fields as $field) {
506 if (isset($tableDefinition['columns'][$field])) {
507 $tableDefinition['columns'][$field]['onChange'] = 'reload';
508 }
509 }
510 $this->messages[] = 'The TCA setting [\'ctrl\'][\'requestUpdate\'] was removed from '
511 . ' table ' . $table . '. The column field(s) "' . implode('" and "', $fields) . '" were updated'
512 . ' and contain option "\'onChange\' => \'reload\'" parallel to \'config\' and \'label\' section.';
513 unset($tableDefinition['ctrl']['requestUpdate']);
514 }
515 }
516 return $tca;
517 }
518
519 /**
520 * Move all type=input with eval=date/time configuration to an own renderType
521 *
522 * @param array $tca
523 * @return array Migrated TCA
524 */
525 protected function migrateInputDateTimeToRenderType(array $tca): array
526 {
527 foreach ($tca as $table => &$tableDefinition) {
528 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
529 continue;
530 }
531 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
532 if (isset($fieldConfig['config']['type']) && $fieldConfig['config']['type'] !== 'input') {
533 continue;
534 }
535 $eval = $fieldConfig['config']['eval'] ?? '';
536 $eval = GeneralUtility::trimExplode(',', $eval, true);
537 if (in_array('date', $eval, true)
538 || in_array('datetime', $eval, true)
539 || in_array('time', $eval, true)
540 || in_array('timesec', $eval, true)
541 ) {
542 if (!isset($fieldConfig['config']['renderType'])) {
543 $fieldConfig['config']['renderType'] = 'inputDateTime';
544 $this->messages[] = 'The TCA setting \'renderType\' => \'inputDateTime\' was added '
545 . 'in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']';
546 }
547 }
548 }
549 }
550 return $tca;
551 }
552
553 /**
554 * Wizards configuration may hold "enableByTypeConfig" and are then enabled
555 * for certain types via "defaultExtras".
556 * Find wizards configured like that and migrate them to "columnsOverrides"
557 *
558 * @param array $tca Incoming TCA
559 * @return array Migrated TCA
560 */
561 public function migrateWizardEnableByTypeConfigToColumnsOverrides(array $tca): array
562 {
563 $newTca = $tca;
564 foreach ($tca as $table => $tableDefinition) {
565 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
566 continue;
567 }
568 foreach ($tableDefinition['columns'] as $fieldName => $fieldConfig) {
569 if (
570 !empty($fieldConfig['config']['type']) // type is set
571 && isset($fieldConfig['config']['wizards'])
572 && is_array($fieldConfig['config']['wizards']) // and there are wizards
573 ) {
574 foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
575 if (isset($wizardConfig['enableByTypeConfig']) // and enableByTypeConfig is given
576 && $wizardConfig['enableByTypeConfig'] // and enabled
577 ) { // and enableByTypeConfig is enabled
578 // Remove this "enableByTypeConfig" wizard from columns
579 unset($newTca[$table]['columns'][$fieldName]['config']['wizards'][$wizardName]);
580 if (!isset($tableDefinition['types']) || !is_array($tableDefinition['types'])) {
581 // No type definition at all ... continue directly
582 continue;
583 }
584 foreach ($tableDefinition['types'] as $typeName => $typeArray) {
585 if (empty($typeArray['columnsOverrides'][$fieldName]['defaultExtras'])
586 || strpos($typeArray['columnsOverrides'][$fieldName]['defaultExtras'], $wizardName) === false
587 ) {
588 // Continue directly if this wizard is not enabled for given type
589 continue;
590 }
591 $defaultExtras = $typeArray['columnsOverrides'][$fieldName]['defaultExtras'];
592 $defaultExtrasArray = GeneralUtility::trimExplode(':', $defaultExtras, true);
593 $newDefaultExtrasArray = [];
594 foreach ($defaultExtrasArray as $fieldExtraField) {
595 if (strpos($fieldExtraField, 'wizards[') === 0) {
596 $enabledWizards = substr($fieldExtraField, 8, strlen($fieldExtraField) - 8); // Cut off "wizards[
597 $enabledWizards = substr($enabledWizards, 0, strlen($enabledWizards) - 1);
598 $enabledWizardsArray = GeneralUtility::trimExplode('|', $enabledWizards, true);
599 foreach ($enabledWizardsArray as $enabledWizardName) {
600 if ($enabledWizardName === $wizardName) {
601 // Fill new array
602 unset($newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldName]['defaultExtras']);
603 $newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldName]['config']['wizards'][$enabledWizardName] = $wizardConfig;
604 unset($newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldName]['config']['wizards'][$enabledWizardName]['enableByTypeConfig']);
605 $this->messages[] = 'The wizard with "enableByTypeConfig" set to 1 has been migrated to \'columnsOverrides\'.'
606 . ' It has been migrated from "'
607 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']" to '
608 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\'].';
609 }
610 }
611 } else {
612 $newDefaultExtrasArray[] = $fieldExtraField;
613 }
614 }
615 if ($defaultExtrasArray !== $newDefaultExtrasArray
616 && !empty($newDefaultExtrasArray)
617 ) {
618 $newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldName]['defaultExtras'] = implode(':', $newDefaultExtrasArray);
619 }
620 }
621 } elseif (isset($wizardConfig['enableByTypeConfig'])) {
622 // enableByTypeConfig is set, but not true or 1 or '1', just delete it.
623 unset($newTca[$table]['columns'][$fieldName]['config']['wizards'][$wizardName]['enableByTypeConfig']);
624 }
625 }
626 }
627 }
628 }
629 return $newTca;
630 }
631
632 /**
633 * Migrates fields having a colorpicker wizard to a color field
634 *
635 * @param array $tca Incoming TCA
636 * @return array Migrated TCA
637 */
638 protected function migrateColorPickerWizardToRenderType(array $tca): array
639 {
640 foreach ($tca as $table => &$tableDefinition) {
641 if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
642 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
643 if (isset($fieldConfig['config'])) {
644 // Do not handle field where the render type is set.
645 if (!empty($fieldConfig['config']['renderType'])) {
646 continue;
647 }
648 if ($fieldConfig['config']['type'] === 'input') {
649 if (isset($fieldConfig['config']['wizards']) && is_array($fieldConfig['config']['wizards'])) {
650 foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizard) {
651 if (isset($wizard['type']) && ($wizard['type'] === 'colorbox')) {
652 unset($fieldConfig['config']['wizards'][$wizardName]);
653 if (empty($fieldConfig['config']['wizards'])) {
654 unset($fieldConfig['config']['wizards']);
655 }
656 $fieldConfig['config']['renderType'] = 'colorpicker';
657 $this->messages[] = 'The color-picker wizard using \'colorbox\' is deprecated'
658 . ' in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
659 . '[\'wizards\'][\'' . $wizardName . '\'] and was changed to ' . $table
660 . '[\'columns\'][\'' . $fieldName . '\'][\'config\'] = \'colorpicker\'';
661 }
662 }
663 }
664 if (empty($fieldConfig['config']['wizards'])) {
665 unset($fieldConfig['config']['wizards']);
666 }
667 if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
668 foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
669 if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
670 if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
671 && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
672 ) {
673 foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
674 if (isset($wizard['type']) && ($wizard['type'] === 'colorbox')) {
675 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
676 $typeArray['columnsOverrides'][$fieldName]['config']['type'] = 'input';
677 $typeArray['columnsOverrides'][$fieldName]['config']['renderType'] = 'colorpicker';
678 $this->messages[] = 'The color-picker wizard in columnsOverrides using \'colorbox\' has been migrated to a \'rendertype\' = \'colorpicker\'.'
679 . ' It has been migrated from TCA "' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
680 . '[\'wizards\'][\'' . $wizardName . '\'][\'type\'] = \'colorbox\'"" to "' . $table
681 . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'renderType\'] = \'colorpicker\'"';
682 }
683 }
684 if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
685 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
686 }
687 }
688 }
689 }
690 }
691 }
692 }
693 }
694 }
695 }
696
697 return $tca;
698 }
699
700 /**
701 * Move type=input with select wizard to config['valuePicker']
702 *
703 * @param array $tca
704 * @return array Migrated TCA
705 */
706 protected function migrateSelectWizardToValuePicker(array $tca): array
707 {
708 foreach ($tca as $table => &$tableDefinition) {
709 if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
710 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
711 if (isset($fieldConfig['config']['type']) && ($fieldConfig['config']['type'] === 'input' || $fieldConfig['config']['type'] === 'text')) {
712 if (isset($fieldConfig['config']['wizards']) && is_array($fieldConfig['config']['wizards'])) {
713 foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
714 if (isset($wizardConfig['type'])
715 && $wizardConfig['type'] === 'select'
716 && isset($wizardConfig['items'])
717 && is_array($wizardConfig['items'])
718 ) {
719 $fieldConfig['config']['valuePicker']['items'] = $wizardConfig['items'];
720 if (isset($wizardConfig['mode'])
721 && is_string($wizardConfig['mode'])
722 && in_array($wizardConfig['mode'], ['append', 'prepend', ''])
723 ) {
724 $fieldConfig['config']['valuePicker']['mode'] = $wizardConfig['mode'];
725 }
726 unset($fieldConfig['config']['wizards'][$wizardName]);
727 $this->messages[] = 'The select wizard in TCA '
728 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
729 . ' has been migrated to '
730 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'valuePicker\'].';
731 }
732 }
733 }
734 if (empty($fieldConfig['config']['wizards'])) {
735 unset($fieldConfig['config']['wizards']);
736 }
737 if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
738 foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
739 if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
740 if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
741 && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
742 ) {
743 foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
744 if (isset($wizard['type'])
745 && ($wizard['type'] === 'select')
746 && isset($wizard['items'])
747 && is_array($wizard['items'])
748 ) {
749 $typeArray['columnsOverrides'][$fieldName]['config']['valuePicker'] = $wizard;
750 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
751 unset($typeArray['columnsOverrides'][$fieldName]['config']['valuePicker']['type']);
752 $this->messages[] = 'The select wizard in columnsOverrides using \'type\' = \'select\' has been migrated'
753 . ' from TCA ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
754 . '[\'wizards\'][\'' . $wizardName . '\'] to ' . $table
755 . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'valuePicker\']';
756 }
757 }
758 if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
759 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
760 }
761 }
762 }
763 }
764 }
765 }
766 }
767 }
768 }
769 return $tca;
770 }
771
772 /**
773 * Move type=input with select wizard to config['valuePicker']
774 *
775 * @param array $tca
776 * @return array Migrated TCA
777 */
778 protected function migrateSliderWizardToSliderConfiguration(array $tca): array
779 {
780 foreach ($tca as $table => &$tableDefinition) {
781 if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
782 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
783 if (isset($fieldConfig['config']['type']) && $fieldConfig['config']['type'] === 'input') {
784 if (isset($fieldConfig['config']['wizards'])
785 && is_array($fieldConfig['config']['wizards'])) {
786 foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
787 if (isset($wizardConfig['type']) && $wizardConfig['type'] === 'slider') {
788 $fieldConfig['config']['slider'] = [];
789 if (isset($wizardConfig['width'])) {
790 $fieldConfig['config']['slider']['width'] = $wizardConfig['width'];
791 }
792 if (isset($wizardConfig['step'])) {
793 $fieldConfig['config']['slider']['step'] = $wizardConfig['step'];
794 }
795 unset($fieldConfig['config']['wizards'][$wizardName]);
796 $this->messages[] = 'The slider wizard in TCA '
797 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
798 . ' has been migrated to '
799 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'slider\'].';
800 }
801 }
802 }
803 if (empty($fieldConfig['config']['wizards'])) {
804 unset($fieldConfig['config']['wizards']);
805 }
806 if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
807 foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
808 if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
809 if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
810 && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
811 ) {
812 foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
813 if (isset($wizard['type']) && ($wizard['type'] === 'slider')) {
814 $typeArray['columnsOverrides'][$fieldName]['config']['slider'] = $wizard;
815 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
816 unset($typeArray['columnsOverrides'][$fieldName]['config']['slider']['type']);
817 $this->messages[] = 'The slider wizard in columnsOverrides using \'type\' = \'slider\' has been migrated'
818 . ' from TCA ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
819 . '[\'wizards\'][\'' . $wizardName . '\'] to ' . $table
820 . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'slider\']';
821 }
822 }
823 if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
824 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
825 }
826 }
827 }
828 }
829 }
830 }
831 }
832 }
833 }
834 return $tca;
835 }
836
837 /**
838 * Move type=input fields that have a "link" wizard to an own renderType with fieldControl
839 *
840 * @param array $tca
841 * @return array Modified TCA
842 */
843 protected function migrateLinkWizardToRenderTypeAndFieldControl(array $tca): array
844 {
845 foreach ($tca as $table => &$tableDefinition) {
846 if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
847 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
848 if (isset($fieldConfig['config']['type']) && $fieldConfig['config']['type'] === 'input'
849 && !isset($fieldConfig['config']['renderType'])
850 ) {
851 if (isset($fieldConfig['config']['wizards'])
852 && is_array($fieldConfig['config']['wizards'])) {
853 foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
854 if (isset($wizardConfig['type'])
855 && $wizardConfig['type'] === 'popup'
856 && isset($wizardConfig['module']['name'])
857 && $wizardConfig['module']['name'] === 'wizard_link'
858 ) {
859 $fieldConfig['config']['renderType'] = 'inputLink';
860 if (isset($wizardConfig['title'])) {
861 $fieldConfig['config']['fieldControl']['linkPopup']['options']['title'] = $wizardConfig['title'];
862 }
863 if (isset($wizardConfig['JSopenParams'])) {
864 $fieldConfig['config']['fieldControl']['linkPopup']['options']['windowOpenParameters']
865 = $wizardConfig['JSopenParams'];
866 }
867 if (isset($wizardConfig['params']['blindLinkOptions'])) {
868 $fieldConfig['config']['fieldControl']['linkPopup']['options']['blindLinkOptions']
869 = $wizardConfig['params']['blindLinkOptions'];
870 }
871 if (isset($wizardConfig['params']['blindLinkFields'])) {
872 $fieldConfig['config']['fieldControl']['linkPopup']['options']['blindLinkFields']
873 = $wizardConfig['params']['blindLinkFields'];
874 }
875 if (isset($wizardConfig['params']['allowedExtensions'])) {
876 $fieldConfig['config']['fieldControl']['linkPopup']['options']['allowedExtensions']
877 = $wizardConfig['params']['allowedExtensions'];
878 }
879 unset($fieldConfig['config']['wizards'][$wizardName]);
880 $this->messages[] = 'The link wizard has been migrated to a \'renderType\' => \'inputLink \'. '
881 . 'It has been migrated from TCA table "'
882 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']" to "'
883 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'renderType\'] = \'inputLink\'".';
884 }
885 }
886 }
887 if (empty($fieldConfig['config']['wizards'])) {
888 unset($fieldConfig['config']['wizards']);
889 }
890 if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
891 foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
892 if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
893 if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
894 && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
895 ) {
896 foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
897 if (isset($wizard['type'])
898 && $wizard['type'] === 'popup'
899 && isset($wizard['module']['name'])
900 && $wizard['module']['name'] === 'wizard_link'
901 ) {
902 $typeArray['columnsOverrides'][$fieldName]['config']['renderType'] = 'inputLink';
903 if (isset($wizard['title'])) {
904 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['linkPopup']['options']['title'] = $wizard['title'];
905 }
906 if (isset($wizard['JSopenParams'])) {
907 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['linkPopup']['options']['windowOpenParameters']
908 = $wizard['JSopenParams'];
909 }
910 if (isset($wizard['params']['blindLinkOptions'])) {
911 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['linkPopup']['options']['blindLinkOptions']
912 = $wizard['params']['blindLinkOptions'];
913 }
914 if (isset($wizard['params']['blindLinkFields'])) {
915 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['linkPopup']['options']['blindLinkFields']
916 = $wizard['params']['blindLinkFields'];
917 }
918 if (isset($wizard['params']['allowedExtensions'])) {
919 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['linkPopup']['options']['allowedExtensions']
920 = $wizard['params']['allowedExtensions'];
921 }
922 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
923 $this->messages[] = 'The link wizard in columnsOverrides using \'type\' = \'popup\' has been migrated to a \'renderType\' = \'inputLink\'.'
924 . ' It has been migrated from TCA "' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
925 . '[\'wizards\'][\'' . $wizardName . '\']" to "' . $table
926 . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'renderType\'] = \'inputLink\'"';
927 }
928 }
929 if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
930 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
931 }
932 }
933 }
934 }
935 }
936 }
937 }
938 }
939 }
940
941 return $tca;
942 }
943
944 /**
945 * Find select and group fields with enabled edit wizard and migrate to "fieldControl"
946 *
947 * @param array $tca
948 * @return array
949 */
950 protected function migrateEditWizardToFieldControl(array $tca): array
951 {
952 foreach ($tca as $table => &$tableDefinition) {
953 if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
954 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
955 if (isset($fieldConfig['config']['type']) && ($fieldConfig['config']['type'] === 'group'
956 || $fieldConfig['config']['type'] === 'select')
957 ) {
958 if (isset($fieldConfig['config']['wizards'])
959 && is_array($fieldConfig['config']['wizards'])
960 ) {
961 foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
962 if (isset($wizardConfig['type'])
963 && $wizardConfig['type'] === 'popup'
964 && isset($wizardConfig['module']['name'])
965 && $wizardConfig['module']['name'] === 'wizard_edit'
966 && !isset($fieldConfig['config']['fieldControl']['editPopup'])
967 ) {
968 $fieldConfig['config']['fieldControl']['editPopup']['disabled'] = false;
969 if (isset($wizardConfig['title'])) {
970 $fieldConfig['config']['fieldControl']['editPopup']['options']['title'] = $wizardConfig['title'];
971 }
972 if (isset($wizardConfig['JSopenParams'])) {
973 $fieldConfig['config']['fieldControl']['editPopup']['options']['windowOpenParameters']
974 = $wizardConfig['JSopenParams'];
975 }
976 unset($fieldConfig['config']['wizards'][$wizardName]);
977 $this->messages[] = 'The edit wizard in TCA has been migrated to a \'fieldControl\' = \'editPopup\' element.'
978 . ' It has been migrated from TCA "'
979 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']" to "'
980 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldControl\']=\'editPopup\'".';
981 }
982 }
983 }
984 if (empty($fieldConfig['config']['wizards'])) {
985 unset($fieldConfig['config']['wizards']);
986 }
987 if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
988 foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
989 if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
990 if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
991 && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
992 ) {
993 foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
994 if (isset($wizard['type'])
995 && $wizard['type'] === 'popup'
996 && isset($wizard['module']['name'])
997 && $wizard['module']['name'] === 'wizard_edit'
998 ) {
999 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['editPopup']['disabled'] = false;
1000 if (isset($wizard['title'])) {
1001 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['editPopup']['options']['title']
1002 = $wizard['title'];
1003 }
1004 if (isset($wizard['JSopenParams'])) {
1005 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['editPopup']['options']['windowOpenParameters']
1006 = $wizard['JSopenParams'];
1007 }
1008 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
1009 $this->messages[] = 'The edit wizard in columnsOverrides using \'type\' = \'popup\' has been migrated to a \'fieldControl\' = \'editPopup\' element.'
1010 . ' It has been migrated from TCA "'
1011 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
1012 . '[\'wizards\'][\'' . $wizardName . '\']" , to "'
1013 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'fieldControl\']=\'editPopup\'".';
1014 }
1015 }
1016 if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
1017 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
1018 }
1019 }
1020 }
1021 }
1022 }
1023 }
1024 }
1025 }
1026 }
1027
1028 return $tca;
1029 }
1030
1031 /**
1032 * Find select and group fields with enabled add wizard and migrate to "fieldControl"
1033 *
1034 * @param array $tca
1035 * @return array
1036 */
1037 protected function migrateAddWizardToFieldControl(array $tca): array
1038 {
1039 foreach ($tca as $table => &$tableDefinition) {
1040 if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1041 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1042 if (isset($fieldConfig['config']['type']) && ($fieldConfig['config']['type'] === 'group'
1043 || $fieldConfig['config']['type'] === 'select')
1044 ) {
1045 if (isset($fieldConfig['config']['wizards'])
1046 && is_array($fieldConfig['config']['wizards'])
1047 ) {
1048 foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
1049 if (isset($wizardConfig['type'])
1050 && $wizardConfig['type'] === 'script'
1051 && isset($wizardConfig['module']['name'])
1052 && $wizardConfig['module']['name'] === 'wizard_add'
1053 && !isset($fieldConfig['config']['fieldControl']['addRecord'])
1054 ) {
1055 $fieldConfig['config']['fieldControl']['addRecord']['disabled'] = false;
1056 if (isset($wizardConfig['title'])) {
1057 $fieldConfig['config']['fieldControl']['addRecord']['options']['title'] = $wizardConfig['title'];
1058 }
1059 if (isset($wizardConfig['params']['table'])) {
1060 $fieldConfig['config']['fieldControl']['addRecord']['options']['table']
1061 = $wizardConfig['params']['table'];
1062 }
1063 if (isset($wizardConfig['params']['pid'])) {
1064 $fieldConfig['config']['fieldControl']['addRecord']['options']['pid']
1065 = $wizardConfig['params']['pid'];
1066 }
1067 if (isset($wizardConfig['params']['setValue'])) {
1068 $fieldConfig['config']['fieldControl']['addRecord']['options']['setValue']
1069 = $wizardConfig['params']['setValue'];
1070 }
1071 unset($fieldConfig['config']['wizards'][$wizardName]);
1072 $this->messages[] = 'The add wizard in TCA has been migrated to a \'fieldControl\' = \'addRecord\' element.'
1073 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
1074 . ' It has been migrated from TCA "'
1075 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldControl\']=\'addRecord\'.';
1076 }
1077 }
1078 }
1079 if (empty($fieldConfig['config']['wizards'])) {
1080 unset($fieldConfig['config']['wizards']);
1081 }
1082 if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
1083 foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
1084 if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
1085 if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1086 && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1087 ) {
1088 foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
1089 if (isset($wizard['type'])
1090 && $wizard['type'] === 'script'
1091 && isset($wizard['module']['name'])
1092 && $wizard['module']['name'] === 'wizard_add'
1093 ) {
1094 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['addRecord']['disabled'] = false;
1095 if (isset($wizard['title'])) {
1096 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['addRecord']['options']['title']
1097 = $wizard['title'];
1098 }
1099 if (isset($wizard['params']['table'])) {
1100 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['addRecord']['options']['table']
1101 = $wizard['params']['table'];
1102 }
1103 if (isset($wizard['params']['pid'])) {
1104 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['addRecord']['options']['pid']
1105 = $wizard['params']['pid'];
1106 }
1107 if (isset($wizard['params']['setValue'])) {
1108 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['addRecord']['options']['setValue']
1109 = $wizard['params']['setValue'];
1110 }
1111 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
1112 $this->messages[] = 'The add wizard in columnsOverrides using \'type\' = \'script\' has been migrated to a \'fieldControl\' = \'addRecord\' element.'
1113 . ' It has been migrated from TCA "'
1114 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
1115 . '[\'wizards\'][\'' . $wizardName . '\']" to "'
1116 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'fieldControl\'=\'addRecord\'".';
1117 }
1118 }
1119 if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
1120 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
1121 }
1122 }
1123 }
1124 }
1125 }
1126 }
1127 }
1128 }
1129 }
1130
1131 return $tca;
1132 }
1133
1134 /**
1135 * Find select and group fields with enabled list wizard and migrate to "fieldControl"
1136 *
1137 * @param array $tca
1138 * @return array
1139 */
1140 protected function migrateListWizardToFieldControl(array $tca): array
1141 {
1142 foreach ($tca as $table => &$tableDefinition) {
1143 if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1144 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1145 if (isset($fieldConfig['config']['type']) && ($fieldConfig['config']['type'] === 'group'
1146 || $fieldConfig['config']['type'] === 'select')
1147 ) {
1148 if (isset($fieldConfig['config']['wizards'])
1149 && is_array($fieldConfig['config']['wizards'])
1150 ) {
1151 foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
1152 if (isset($wizardConfig['type'])
1153 && $wizardConfig['type'] === 'script'
1154 && isset($wizardConfig['module']['name'])
1155 && $wizardConfig['module']['name'] === 'wizard_list'
1156 && !isset($fieldConfig['config']['fieldControl']['listModule'])
1157 ) {
1158 $fieldConfig['config']['fieldControl']['listModule']['disabled'] = false;
1159 if (isset($wizardConfig['title'])) {
1160 $fieldConfig['config']['fieldControl']['listModule']['options']['title'] = $wizardConfig['title'];
1161 }
1162 if (isset($wizardConfig['params']['table'])) {
1163 $fieldConfig['config']['fieldControl']['listModule']['options']['table']
1164 = $wizardConfig['params']['table'];
1165 }
1166 if (isset($wizardConfig['params']['pid'])) {
1167 $fieldConfig['config']['fieldControl']['listModule']['options']['pid']
1168 = $wizardConfig['params']['pid'];
1169 }
1170 unset($fieldConfig['config']['wizards'][$wizardName]);
1171 $this->messages[] = 'The list wizard in TCA has been migrated to a \'fieldControl\' = \'listModule\' element.'
1172 . ' It has been migrated from TCA "'
1173 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
1174 . '" to "'
1175 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldControl\'=\'listModule\'".';
1176 }
1177 }
1178 }
1179 if (empty($fieldConfig['config']['wizards'])) {
1180 unset($fieldConfig['config']['wizards']);
1181 }
1182 if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
1183 foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
1184 if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
1185 if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1186 && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1187 ) {
1188 foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
1189 if (isset($wizard['type'])
1190 && $wizard['type'] === 'script'
1191 && isset($wizard['module']['name'])
1192 && $wizard['module']['name'] === 'wizard_list'
1193 ) {
1194 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['listModule']['disabled'] = false;
1195 if (isset($wizard['title'])) {
1196 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['listModule']['options']['title']
1197 = $wizard['title'];
1198 }
1199 if (isset($wizard['params']['table'])) {
1200 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['listModule']['options']['table']
1201 = $wizard['params']['table'];
1202 }
1203 if (isset($wizard['params']['pid'])) {
1204 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['listModule']['options']['pid']
1205 = $wizard['params']['pid'];
1206 }
1207 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
1208 $this->messages[] = 'The list wizard in columnsOverrides using \'type\' = \'script\' has been migrated to a \'fieldControl\' = \'listModule\' element.'
1209 . ' It has been migrated from TCA "'
1210 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
1211 . '[\'wizards\'][\'' . $wizardName . '\']" to "'
1212 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'fieldControl\'=\'listModule\'".';
1213 }
1214 }
1215 if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
1216 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
1217 }
1218 }
1219 }
1220 }
1221 }
1222 }
1223 }
1224 }
1225 }
1226
1227 return $tca;
1228 }
1229
1230 /**
1231 * Migrate defaultExtras "nowrap", "enable-tab", "fixed-font". Then drop all
1232 * remaining "defaultExtras", there shouldn't exist anymore.
1233 *
1234 * @param array $tca
1235 * @return array
1236 */
1237 protected function migrateLastPiecesOfDefaultExtras(array $tca): array
1238 {
1239 foreach ($tca as $table => &$tableDefinition) {
1240 if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1241 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1242 if (isset($fieldConfig['defaultExtras'])) {
1243 $defaultExtrasArray = GeneralUtility::trimExplode(':', $fieldConfig['defaultExtras'], true);
1244 foreach ($defaultExtrasArray as $defaultExtrasSetting) {
1245 if ($defaultExtrasSetting === 'rte_only') {
1246 $this->messages[] = 'The defaultExtras setting \'rte_only\' in TCA table '
1247 . $table . '[\'columns\'][\'' . $fieldName . '\'] has been dropped, the setting'
1248 . ' is no longer supported';
1249 continue;
1250 }
1251 if ($defaultExtrasSetting === 'nowrap') {
1252 $fieldConfig['config']['wrap'] = 'off';
1253 $this->messages[] = 'The defaultExtras setting \'nowrap\' in TCA table '
1254 . $table . '[\'columns\'][\'' . $fieldName . '\'] has been migrated to TCA table '
1255 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wrap\'] = \'off\'';
1256 } elseif ($defaultExtrasSetting === 'enable-tab') {
1257 $fieldConfig['config']['enableTabulator'] = true;
1258 $this->messages[] = 'The defaultExtras setting \'enable-tab\' in TCA table '
1259 . $table . '[\'columns\'][\'' . $fieldName . '\'] has been migrated to TCA table '
1260 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'enableTabulator\'] = true';
1261 } elseif ($defaultExtrasSetting === 'fixed-font') {
1262 $fieldConfig['config']['fixedFont'] = true;
1263 $this->messages[] = 'The defaultExtras setting \'fixed-font\' in TCA table '
1264 . $table . '[\'columns\'][\'' . $fieldName . '\'] has been migrated to TCA table '
1265 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fixedFont\'] = true';
1266 } else {
1267 $this->messages[] = 'The defaultExtras setting \'' . $defaultExtrasSetting . '\' in TCA table '
1268 . $table . '[\'columns\'][\'' . $fieldName . '\'] is unknown and has been dropped.';
1269 }
1270 }
1271 unset($fieldConfig['defaultExtras']);
1272 }
1273 }
1274 }
1275 if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
1276 foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
1277 if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
1278 foreach ($typeArray['columnsOverrides'] as $fieldName => &$overrideConfig) {
1279 if (!isset($overrideConfig['defaultExtras'])) {
1280 continue;
1281 }
1282 $defaultExtrasArray = GeneralUtility::trimExplode(':', $overrideConfig['defaultExtras'], true);
1283 foreach ($defaultExtrasArray as $defaultExtrasSetting) {
1284 if ($defaultExtrasSetting === 'rte_only') {
1285 $this->messages[] = 'The defaultExtras setting \'rte_only\' in TCA table '
1286 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\']'
1287 . ' has been dropped, the setting is no longer supported';
1288 continue;
1289 }
1290 if ($defaultExtrasSetting === 'nowrap') {
1291 $overrideConfig['config']['wrap'] = 'off';
1292 $this->messages[] = 'The defaultExtras setting \'nowrap\' in TCA table '
1293 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\']'
1294 . ' has been migrated to TCA table '
1295 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\'][\'config\'][\'wrap\'] = \'off\'';
1296 } elseif ($defaultExtrasSetting === 'enable-tab') {
1297 $overrideConfig['config']['enableTabulator'] = true;
1298 $this->messages[] = 'The defaultExtras setting \'enable-tab\' in TCA table '
1299 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\']'
1300 . ' has been migrated to TCA table '
1301 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\'][\'config\'][\'enableTabulator\'] = true';
1302 } elseif ($defaultExtrasSetting === 'fixed-font') {
1303 $overrideConfig['config']['fixedFont'] = true;
1304 $this->messages[] = 'The defaultExtras setting \'fixed-font\' in TCA table '
1305 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\']'
1306 . ' has been migrated to TCA table '
1307 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\'][\'config\'][\'fixedFont\'] = true';
1308 } else {
1309 $this->messages[] = 'The defaultExtras setting \'' . $defaultExtrasSetting . '\' in TCA table '
1310 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\']'
1311 . ' is unknown and has been dropped.';
1312 }
1313 }
1314 unset($overrideConfig['defaultExtras']);
1315 }
1316 }
1317 }
1318 }
1319 }
1320
1321 return $tca;
1322 }
1323
1324 /**
1325 * Migrate wizard_table script to renderType="textTable" with options in fieldControl
1326 *
1327 * @param array $tca
1328 * @return array
1329 */
1330 protected function migrateTableWizardToRenderType(array $tca): array
1331 {
1332 foreach ($tca as $table => &$tableDefinition) {
1333 if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1334 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1335 if (isset($fieldConfig['config']['type']) && $fieldConfig['config']['type'] === 'text') {
1336 if (isset($fieldConfig['config']['wizards'])
1337 && is_array($fieldConfig['config']['wizards'])
1338 ) {
1339 foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
1340 if (isset($wizardConfig['type'])
1341 && $wizardConfig['type'] === 'script'
1342 && isset($wizardConfig['module']['name'])
1343 && $wizardConfig['module']['name'] === 'wizard_table'
1344 && !isset($fieldConfig['config']['fieldControl']['tableWizard'])
1345 && !isset($fieldConfig['config']['renderType'])
1346 ) {
1347 $fieldConfig['config']['renderType'] = 'textTable';
1348 if (isset($wizardConfig['title'])) {
1349 $fieldConfig['config']['fieldControl']['tableWizard']['options']['title'] = $wizardConfig['title'];
1350 }
1351 if (isset($wizardConfig['params']['xmlOutput']) && (int)$wizardConfig['params']['xmlOutput'] !== 0) {
1352 $fieldConfig['config']['fieldControl']['tableWizard']['options']['xmlOutput']
1353 = (int)$wizardConfig['params']['xmlOutput'];
1354 }
1355 if (isset($wizardConfig['params']['numNewRows'])) {
1356 $fieldConfig['config']['fieldControl']['tableWizard']['options']['numNewRows']
1357 = $wizardConfig['params']['numNewRows'];
1358 }
1359 unset($fieldConfig['config']['wizards'][$wizardName]);
1360 $this->messages[] = 'The table wizard in TCA has been migrated to a \'renderType\' = \'textTable\'.'
1361 . ' It has been migrated from TCA "'
1362 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
1363 . '" to "'
1364 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'renderType\'] = \'textTable\'".';
1365 }
1366 }
1367 }
1368 if (empty($fieldConfig['config']['wizards'])) {
1369 unset($fieldConfig['config']['wizards']);
1370 }
1371 if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
1372 foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
1373 if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
1374 if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1375 && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1376 ) {
1377 foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
1378 if (isset($wizard['type'])
1379 && $wizard['type'] === 'script'
1380 && isset($wizard['module']['name'])
1381 && $wizard['module']['name'] === 'wizard_table'
1382 && !isset($typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['tableWizard'])
1383 && !isset($typeArray['columnsOverrides'][$fieldName]['config']['renderType'])
1384 ) {
1385 $typeArray['columnsOverrides'][$fieldName]['config']['renderType'] = 'textTable';
1386 if (isset($wizard['title'])) {
1387 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['tableWizard']['options']['title']
1388 = $wizard['title'];
1389 }
1390 if (isset($wizard['params']['xmlOutput']) && (int)$wizard['params']['xmlOutput'] !== 0) {
1391 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['tableWizard']['options']['xmlOutput']
1392 = (int)$wizard['params']['xmlOutput'];
1393 }
1394 if (isset($wizard['params']['numNewRows'])) {
1395 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['tableWizard']['options']['numNewRows']
1396 = $wizard['params']['numNewRows'];
1397 }
1398 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
1399 $this->messages[] = 'The table wizard in columnsOverrides using \'type\' = \'script\' has been migrated to a \'renderType\' = \'textTable\'.'
1400 . ' It has been migrated from TCA "'
1401 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
1402 . '[\'wizards\'][\'' . $wizardName . '\']" to "'
1403 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'renderType\'] = \'textTable\'".';
1404 }
1405 }
1406 if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
1407 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
1408 }
1409 }
1410 }
1411 }
1412 }
1413 }
1414 }
1415 }
1416 }
1417
1418 return $tca;
1419 }
1420
1421 /**
1422 * Migrate "wizard_rte" wizards to rtehtmlarea fieldControl
1423 *
1424 * @param array $tca
1425 * @return array
1426 */
1427 protected function migrateFullScreenRichtextToFieldControl(array $tca): array
1428 {
1429 foreach ($tca as $table => &$tableDefinition) {
1430 if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1431 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1432 if (isset($fieldConfig['config']['type']) && $fieldConfig['config']['type'] === 'text') {
1433 if (isset($fieldConfig['config']['wizards'])
1434 && is_array($fieldConfig['config']['wizards'])
1435 ) {
1436 foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
1437 if (isset($wizardConfig['type'])
1438 && $wizardConfig['type'] === 'script'
1439 && isset($wizardConfig['module']['name'])
1440 && $wizardConfig['module']['name'] === 'wizard_rte'
1441 && !isset($fieldConfig['config']['fieldControl']['fullScreenRichtext'])
1442 && isset($fieldConfig['config']['enableRichtext'])
1443 && (bool)$fieldConfig['config']['enableRichtext'] === true
1444 ) {
1445 // Field is configured for richtext, so enable the full screen wizard
1446 $fieldConfig['config']['fieldControl']['fullScreenRichtext']['disabled'] = false;
1447 if (isset($wizardConfig['title'])) {
1448 $fieldConfig['config']['fieldControl']['fullScreenRichtext']['options']['title'] = $wizardConfig['title'];
1449 }
1450 unset($fieldConfig['config']['wizards'][$wizardName]);
1451 $this->messages[] = 'The RTE fullscreen wizard in TCA has been migrated to a \'fieldControl\' = \'fullScreenRichtext\'.'
1452 . ' It has been migrated from TCA "'
1453 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
1454 . '" to "'
1455 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldControl\']=\'fullScreenRichtext\'".';
1456 } elseif (isset($wizardConfig['type'])
1457 && $wizardConfig['type'] === 'script'
1458 && isset($wizardConfig['module']['name'])
1459 && $wizardConfig['module']['name'] === 'wizard_rte'
1460 && !isset($fieldConfig['config']['fieldControl']['fullScreenRichtext'])
1461 && (
1462 !isset($fieldConfig['config']['enableRichtext'])
1463 || isset($fieldConfig['config']['enableRichtext']) && (bool)$fieldConfig['config']['enableRichtext'] === false
1464 )
1465 ) {
1466 // Wizard is given, but field is not configured for richtext
1467 // Find types that enableRichtext and enable full screen for those types
1468 if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
1469 foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
1470 if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
1471 if (isset($typeArray['columnsOverrides'][$fieldName]['config']['enableRichtext'])
1472 && (bool)$typeArray['columnsOverrides'][$fieldName]['config']['enableRichtext'] === true
1473 ) {
1474 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['fullScreenRichtext']['disabled'] = false;
1475 if (isset($wizardConfig['title'])) {
1476 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['fullScreenRichtext']['options']['title']
1477 = $wizardConfig['title'];
1478 }
1479 $this->messages[] = 'The RTE fullscreen wizard in TCA has been migrated to a \'fieldControl\' = \'fullScreenRichtext\'.'
1480 . ' It has been migrated from TCA "'
1481 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
1482 . '" to "'
1483 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'fieldControl\']=\'fullScreenRichtext\'';
1484 }
1485 }
1486 }
1487 }
1488 unset($fieldConfig['config']['wizards'][$wizardName]);
1489 }
1490 }
1491 }
1492 if (empty($fieldConfig['config']['wizards'])) {
1493 unset($fieldConfig['config']['wizards']);
1494 }
1495 if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
1496 foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
1497 if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
1498 if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1499 && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1500 ) {
1501 foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
1502 if (isset($wizard['type'])
1503 && $wizard['type'] === 'script'
1504 && isset($wizard['module']['name'])
1505 && $wizard['module']['name'] === 'wizard_rte'
1506 && !isset($typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['fullScreenRichtext'])
1507 ) {
1508 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['fullScreenRichtext']['disabled'] = false;
1509 if (isset($wizard['title'])) {
1510 $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['fullScreenRichtext']['options']['title']
1511 = $wizard['title'];
1512 }
1513 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
1514 $this->messages[] = 'The RTE fullscreen wizard in columnsOverrides using \'type\' = \'script\' has been migrated to a \'fieldControl\' = \'fullScreenRichtext\'.'
1515 . ' It has been migrated from TCA "'
1516 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
1517 . '[\'wizards\'][\'' . $wizardName . '\']" to "'
1518 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'fieldControl\']=\'fullScreenRichtext\'".';
1519 }
1520 }
1521 if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
1522 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
1523 }
1524 }
1525 }
1526 }
1527 }
1528 }
1529 }
1530 }
1531 }
1532
1533 return $tca;
1534 }
1535
1536 /**
1537 * Migrate the "suggest" wizard in type=group to "hideSuggest" and "suggestOptions"
1538 *
1539 * @param array $tca Given TCA
1540 * @return array Modified TCA
1541 */
1542 protected function migrateSuggestWizardTypeGroup(array $tca): array
1543 {
1544 foreach ($tca as $table => &$tableDefinition) {
1545 if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1546 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1547 if (isset($fieldConfig['config']['type']) && ($fieldConfig['config']['type'] === 'group'
1548 && isset($fieldConfig['config']['internal_type'])
1549 && $fieldConfig['config']['internal_type'] === 'db')
1550 ) {
1551 if (isset($fieldConfig['config']['hideSuggest'])) {
1552 continue;
1553 }
1554 if (isset($fieldConfig['config']['wizards']) && is_array($fieldConfig['config']['wizards'])) {
1555 foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
1556 if (isset($wizardConfig['type']) && $wizardConfig['type'] === 'suggest') {
1557 unset($wizardConfig['type']);
1558 if (!empty($wizardConfig)) {
1559 $fieldConfig['config']['suggestOptions'] = $wizardConfig;
1560 $this->messages[] = 'The suggest wizard options in TCA '
1561 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
1562 . ' have been migrated to '
1563 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'suggestOptions\'].';
1564 } else {
1565 $this->messages[] = 'The suggest wizard in TCA '
1566 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
1567 . ' is enabled by default and has been removed.';
1568 }
1569 unset($fieldConfig['config']['wizards'][$wizardName]);
1570 }
1571 }
1572 }
1573 if (empty($fieldConfig['config']['wizards'])) {
1574 unset($fieldConfig['config']['wizards']);
1575 }
1576 if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
1577 foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
1578 if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
1579 if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1580 && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1581 ) {
1582 foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
1583 if (isset($wizard['type']) && $wizard['type'] === 'suggest'
1584 ) {
1585 unset($wizard['type']);
1586 $fieldConfig['config']['hideSuggest'] = true;
1587 $typeArray['columnsOverrides'][$fieldName]['config']['hideSuggest'] = false;
1588 if (!empty($wizard)) {
1589 $typeArray['columnsOverrides'][$fieldName]['config']['suggestOptions'] = $wizard;
1590 $this->messages[] = 'The suggest wizard options in columnsOverrides have been migrated'
1591 . ' from TCA ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
1592 . '[\'wizards\'][\'' . $wizardName . '\'] to \'suggestOptions\' in '
1593 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']';
1594 } else {
1595 $this->messages[] = 'The suggest wizard in columnsOverrides has been migrated'
1596 . ' from TCA ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
1597 . '[\'wizards\'][\'' . $wizardName . '\'] to \'hideSuggest\' => false in '
1598 . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'hideSuggest\']';
1599 }
1600 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
1601 }
1602 }
1603 if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
1604 unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
1605 }
1606 }
1607 }
1608 }
1609 }
1610 }
1611 }
1612 }
1613 }
1614
1615 return $tca;
1616 }
1617
1618 /**
1619 * Migrate some detail options of type=group config
1620 *
1621 * @param array $tca Given TCA
1622 * @return array Modified TCA
1623 */
1624 protected function migrateOptionsOfTypeGroup(array $tca): array
1625 {
1626 foreach ($tca as $table => &$tableDefinition) {
1627 if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1628 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1629 if (isset($fieldConfig['config']['type']) && $fieldConfig['config']['type'] === 'group') {
1630 if (isset($fieldConfig['config']['selectedListStyle'])) {
1631 unset($fieldConfig['config']['selectedListStyle']);
1632 $this->messages[] = 'The \'type\' = \'group\' option \'selectedListStyle\' is obsolete and has been dropped'
1633 . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']';
1634 }
1635 if (isset($fieldConfig['config']['show_thumbs'])) {
1636 if ((bool)$fieldConfig['config']['show_thumbs'] === false && $fieldConfig['config']['internal_type'] === 'db') {
1637 $fieldConfig['config']['fieldWizard']['recordsOverview']['disabled'] = true;
1638 $this->messages[] = 'The \'type\' = \'group\' option \'show_thumbs\' = false is obsolete'
1639 . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
1640 . ' and has been migrated to'
1641 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldWizard\'][\'recordsOverview\'][\'disabled\'] = true';
1642 } elseif ((bool)$fieldConfig['config']['show_thumbs'] === false && $fieldConfig['config']['internal_type'] === 'file') {
1643 $fieldConfig['config']['fieldWizard']['fileThumbnails']['disabled'] = true;
1644 $this->messages[] = 'The \'type\' = \'group\' option \'show_thumbs\' = false is obsolete'
1645 . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
1646 . ' and has been migrated to'
1647 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldWizard\'][\'fileThumbnails\'][\'disabled\'] = true';
1648 } else {
1649 $this->messages[] = 'The \'type\' = \'group\' option \'show_thumbs\' is obsolete and has been dropped'
1650 . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']';
1651 }
1652 unset($fieldConfig['config']['show_thumbs']);
1653 }
1654 if (isset($fieldConfig['config']['disable_controls']) && is_string($fieldConfig['config']['disable_controls'])) {
1655 $controls = GeneralUtility::trimExplode(',', $fieldConfig['config']['disable_controls'], true);
1656 foreach ($controls as $control) {
1657 if ($control === 'browser') {
1658 $fieldConfig['config']['fieldControl']['elementBrowser']['disabled'] = true;
1659 $this->messages[] = 'The \'type\' = \'group\' option \'disable_controls\' = \'browser\''
1660 . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
1661 . ' and has been migrated to'
1662 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldControl\'][\'elementBrowser\'][\'disabled\'] = true';
1663 } elseif ($control === 'delete') {
1664 $this->messages[] = 'The \'type\' = \'group\' option \'disable_controls\' = \'delete\''
1665 . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
1666 . ' and has been migrated to'
1667 . $table . '[\'columns\'][\' . $fieldName . \'][\'config\'][\'hideDeleteIcon\'] = true';
1668 $fieldConfig['config']['hideDeleteIcon'] = true;
1669 } elseif ($control === 'allowedTables') {
1670 $fieldConfig['config']['fieldWizard']['tableList']['disabled'] = true;
1671 $this->messages[] = 'The \'type\' = \'group\' option \'disable_controls\' = \'allowedTables\''
1672 . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
1673 . ' and has been migrated to'
1674 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldWizard\'][\'tableList\'][\'disabled\'] = true';
1675 } elseif ($control === 'upload') {
1676 $fieldConfig['config']['fieldWizard']['fileUpload']['disabled'] = true;
1677 $this->messages[] = 'The \'type\' = \'group\' option \'disable_controls\' = \'upload\''
1678 . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
1679 . ' and has been migrated to'
1680 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldWizard\'][\'fileUpload\'][\'disabled\'] = true';
1681 }
1682 }
1683 unset($fieldConfig['config']['disable_controls']);
1684 }
1685 }
1686 }
1687 }
1688 }
1689
1690 return $tca;
1691 }
1692
1693 /**
1694 * Migrate "showIconTable" to a field wizard, drop selicon_cols
1695 *
1696 * @param array $tca Given TCA
1697 * @return array Modified TCA
1698 */
1699 protected function migrateSelectShowIconTable(array $tca): array
1700 {
1701 foreach ($tca as $table => &$tableDefinition) {
1702 if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1703 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1704 if (isset($fieldConfig['config']['type']) && ($fieldConfig['config']['type'] === 'select'
1705 && isset($fieldConfig['config']['renderType'])
1706 && $fieldConfig['config']['renderType'] === 'selectSingle')
1707 ) {
1708 if (isset($fieldConfig['config']['showIconTable'])) {
1709 if ((bool)$fieldConfig['config']['showIconTable'] === true) {
1710 $fieldConfig['config']['fieldWizard']['selectIcons']['disabled'] = false;
1711 $this->messages[] = 'The \'type\' = \'select\' option \'showIconTable\' = true is obsolete'
1712 . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
1713 . ' and has been migrated to'
1714 . ' [\'config\'][\'fieldWizard\'][\'selectIcons\'][\'disabled\'] = false';
1715 } else {
1716 $this->messages[] = 'The \'type\' = \'group\' option \'showIconTable\' = false is obsolete'
1717 . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
1718 . ' and has been removed.';
1719 }
1720 unset($fieldConfig['config']['showIconTable']);
1721 }
1722 if (isset($fieldConfig['config']['selicon_cols'])) {
1723 unset($fieldConfig['config']['selicon_cols']);
1724 $this->messages[] = 'The \'type\' = \'group\' option \'selicon_cols\' = false is obsolete'
1725 . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
1726 . ' and has been removed.';
1727 }
1728 }
1729 }
1730 }
1731 }
1732
1733 return $tca;
1734 }
1735
1736 /**
1737 * Migrate imageManipulation "ratio" config to new "cropVariant" config
1738 *
1739 * @param array $tca
1740 * @return array
1741 */
1742 protected function migrateImageManipulationConfig(array $tca): array
1743 {
1744 foreach ($tca as $table => &$tableDefinition) {
1745 if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1746 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1747 if (isset($fieldConfig['config']['type']) && $fieldConfig['config']['type'] === 'imageManipulation') {
1748 if (isset($fieldConfig['config']['enableZoom'])) {
1749 unset($fieldConfig['config']['enableZoom']);
1750 $this->messages[] = sprintf(
1751 'The config option "enableZoom" has been removed from TCA type "imageManipulation" in table "%s" and field "%s"',
1752 $table,
1753 $fieldName
1754 );
1755 }
1756 if (isset($fieldConfig['config']['ratios'])) {
1757 $legacyRatios = $fieldConfig['config']['ratios'];
1758 unset($fieldConfig['config']['ratios']);
1759 if (isset($fieldConfig['config']['cropVariants'])) {
1760 $this->messages[] = sprintf(
1761 'The config option "ratios" has been deprecated and cannot be used together with the option "cropVariants" in table "%s" and field "%s"',
1762 $table,
1763 $fieldName
1764 );
1765 continue;
1766 }
1767 $fieldConfig['config']['cropVariants']['default'] = [
1768 'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.crop_variant.default',
1769 'allowedAspectRatios' => [],
1770 'cropArea' => [
1771 'x' => 0.0,
1772 'y' => 0.0,
1773 'width' => 1.0,
1774 'height' => 1.0,
1775 ],
1776 ];
1777 foreach ($legacyRatios as $ratio => $ratioLabel) {
1778 $ratio = (float)$ratio;
1779 $ratioId = number_format($ratio, 2);
1780 $fieldConfig['config']['cropVariants']['default']['allowedAspectRatios'][$ratioId] = [
1781 'title' => $ratioLabel,
1782 'value' => $ratio,
1783 ];
1784 }
1785 $this->messages[] = sprintf(
1786 'Migrated config option "ratios" of type "imageManipulation" to option "cropVariants" in table "%s" and field "%s"',
1787 $table,
1788 $fieldName
1789 );
1790 }
1791 }
1792 }
1793 }
1794 }
1795
1796 return $tca;
1797 }
1798
1799 /**
1800 * Migrate 'max' for renderType='inputDateTime'
1801 *
1802 * @param array $tca
1803 * @return array
1804 */
1805 protected function migrateInputDateTimeMax(array $tca): array
1806 {
1807 foreach ($tca as $table => &$tableDefinition) {
1808 if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1809 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1810 if (isset($fieldConfig['config']['renderType']) && $fieldConfig['config']['renderType'] === 'inputDateTime') {
1811 if (isset($fieldConfig['config']['max'])) {
1812 unset($fieldConfig['config']['max']);
1813 $this->messages[] = 'The config option \'max\' has been removed from the TCA for renderType=\'inputDateTime\' in ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'max\']';
1814 }
1815 }
1816 }
1817 }
1818 }
1819
1820 return $tca;
1821 }
1822
1823 /**
1824 * Migrate type='inline' properties 'foreign_types', 'foreign_selector_fieldTcaOverride'
1825 * and 'foreign_record_defaults' to 'overrideChildTca'
1826 *
1827 * @param array $tca
1828 * @return array
1829 */
1830 protected function migrateInlineOverrideChildTca(array $tca): array
1831 {
1832 foreach ($tca as $table => &$tableDefinition) {
1833 if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
1834 foreach ($tableDefinition['types'] as $typeName => &$typeConfig) {
1835 if (!isset($typeConfig['columnsOverrides']) || !is_array($typeConfig['columnsOverrides'])) {
1836 continue;
1837 }
1838 foreach ($typeConfig['columnsOverrides'] as $fieldName => &$fieldConfig) {
1839 if (isset($fieldConfig['config']['overrideChildTca'])
1840 || (isset($fieldConfig['config']['type']) && $fieldConfig['config']['type'] !== 'inline')
1841 || (!isset($fieldConfig['config']['type']) && (empty($tca[$table]['columns'][$fieldName]['config']['type']) || $tca[$table]['columns'][$fieldName]['config']['type'] !== 'inline'))
1842 ) {
1843 // The new config is either set intentionally for compatibility
1844 // or accidentally. In any case we keep the new config and skip the migration.
1845 continue;
1846 }
1847 if (isset($fieldConfig['config']['foreign_types']) && is_array($fieldConfig['config']['foreign_types'])) {
1848 $fieldConfig['config']['overrideChildTca']['types'] = $fieldConfig['config']['foreign_types'];
1849 unset($fieldConfig['config']['foreign_types']);
1850 $this->messages[] = 'The \'foreign_types\' property from TCA ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\'][\'config\'] has been migrated to ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\'][\'config\'][\'overrideChildTca\'][\'types\']';
1851 }
1852 if (isset($fieldConfig['config']['foreign_selector_fieldTcaOverride']) && is_array($fieldConfig['config']['foreign_selector_fieldTcaOverride'])) {
1853 $foreignSelectorFieldName = '';
1854 if (isset($fieldConfig['config']['foreign_selector']) && is_string($fieldConfig['config']['foreign_selector'])) {
1855 $foreignSelectorFieldName = $fieldConfig['config']['foreign_selector'];
1856 } elseif (isset($tca[$table]['columns'][$fieldName]['config']['foreign_selector']) && is_string($tca[$table]['columns'][$fieldName]['config']['foreign_selector'])) {
1857 $foreignSelectorFieldName = $tca[$table]['columns'][$fieldName]['config']['foreign_selector'];
1858 }
1859 if ($foreignSelectorFieldName) {
1860 $fieldConfig['config']['overrideChildTca']['columns'][$foreignSelectorFieldName] = $fieldConfig['config']['foreign_selector_fieldTcaOverride'];
1861 unset($fieldConfig['config']['foreign_selector_fieldTcaOverride']);
1862 $this->messages[] = 'The \'foreign_selector_fieldTcaOverride\' property from TCA ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\'][\'config\'] and has been migrated to ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\'][\'config\'][\'overrideChildTca\'][\'columns\'][\'' . $foreignSelectorFieldName . '\']';
1863 }
1864 }
1865 if (isset($fieldConfig['config']['foreign_record_defaults']) && is_array($fieldConfig['config']['foreign_record_defaults'])) {
1866 foreach ($fieldConfig['config']['foreign_record_defaults'] as $childFieldName => $defaultValue) {
1867 $fieldConfig['config']['overrideChildTca']['columns'][$childFieldName]['config']['default'] = $defaultValue;
1868 $this->messages[] = 'The \'foreign_record_defaults\' property from TCA ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\'][\'config\'][\'' . $childFieldName . '\'] and has been migrated to ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\'][\'config\'][\'overrideChildTca\'][\'columns\'][\'' . $childFieldName . '\'][\'config\'][\'default\']';
1869 }
1870 unset($fieldConfig['config']['foreign_record_defaults']);
1871 }
1872 }
1873 unset($fieldConfig);
1874 }
1875 unset($typeConfig);
1876 }
1877 if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1878 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1879 if (isset($fieldConfig['config']['type']) && $fieldConfig['config']['type'] !== 'inline') {
1880 continue;
1881 }
1882 if (isset($fieldConfig['config']['foreign_types']) && is_array($fieldConfig['config']['foreign_types'])) {
1883 if (isset($fieldConfig['config']['overrideChildTca']['types'])
1884 && is_array($fieldConfig['config']['overrideChildTca']['types'])
1885 ) {
1886 $fieldConfig['config']['overrideChildTca']['types'] = array_replace_recursive(
1887 $fieldConfig['config']['foreign_types'],
1888 $fieldConfig['config']['overrideChildTca']['types']
1889 );
1890 } else {
1891 $fieldConfig['config']['overrideChildTca']['types'] = $fieldConfig['config']['foreign_types'];
1892 }
1893 unset($fieldConfig['config']['foreign_types']);
1894 $this->messages[] = 'The \'foreign_types\' property from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'] and has been migrated to ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'overrideChildTca\'][\'types\']';
1895 }
1896 if (isset($fieldConfig['config']['foreign_selector'], $fieldConfig['config']['foreign_selector_fieldTcaOverride']) && is_string($fieldConfig['config']['foreign_selector']) && is_array($fieldConfig['config']['foreign_selector_fieldTcaOverride'])) {
1897 $foreignSelectorFieldName = $fieldConfig['config']['foreign_selector'];
1898 if (isset($fieldConfig['config']['overrideChildTca']['columns'][$foreignSelectorFieldName])
1899 && is_array($fieldConfig['config']['overrideChildTca']['columns'][$foreignSelectorFieldName])
1900 ) {
1901 $fieldConfig['config']['overrideChildTca']['columns'][$foreignSelectorFieldName] = array_replace_recursive(
1902 $fieldConfig['config']['foreign_selector_fieldTcaOverride'],
1903 $fieldConfig['config']['overrideChildTca']['columns'][$foreignSelectorFieldName]
1904 );
1905 } else {
1906 $fieldConfig['config']['overrideChildTca']['columns'][$foreignSelectorFieldName] = $fieldConfig['config']['foreign_selector_fieldTcaOverride'];
1907 }
1908 unset($fieldConfig['config']['foreign_selector_fieldTcaOverride']);
1909 $this->messages[] = 'The \'foreign_selector_fieldTcaOverride\' property from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'] and has been migrated to ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'overrideChildTca\'][\'columns\'][\'' . $foreignSelectorFieldName . '\']';
1910 }
1911 if (isset($fieldConfig['config']['foreign_record_defaults']) && is_array($fieldConfig['config']['foreign_record_defaults'])) {
1912 foreach ($fieldConfig['config']['foreign_record_defaults'] as $childFieldName => $defaultValue) {
1913 if (!isset($fieldConfig['config']['overrideChildTca']['columns'][$childFieldName]['config']['default'])) {
1914 $fieldConfig['config']['overrideChildTca']['columns'][$childFieldName]['config']['default'] = $defaultValue;
1915 $this->messages[] = 'The \'foreign_record_defaults\' property from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'' . $childFieldName . '\'] and has been migrated to ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'overrideChildTca\'][\'columns\'][\'' . $childFieldName . '\'][\'config\'][\'default\']';
1916 }
1917 }
1918 unset($fieldConfig['config']['foreign_record_defaults']);
1919 }
1920 }
1921 unset($fieldConfig);
1922 }
1923 }
1924
1925 return $tca;
1926 }
1927
1928 /**
1929 * Option $TCA[$table]['columns'][$columnName]['config']['behaviour']['localizeChildrenAtParentLocalization']
1930 * is always on, so this option can be removed.
1931 *
1932 * @param array $tca
1933 * @return array the modified TCA structure
1934 */
1935 protected function migrateLocalizeChildrenAtParentLocalization(array $tca): array
1936 {
1937 foreach ($tca as $table => &$tableDefinition) {
1938 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
1939 continue;
1940 }
1941 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1942 if (($fieldConfig['config']['type'] ?? null) !== 'inline') {
1943 continue;
1944 }
1945
1946 $localizeChildrenAtParentLocalization = ($fieldConfig['config']['behaviour']['localizeChildrenAtParentLocalization'] ?? null);
1947 if ($localizeChildrenAtParentLocalization === null) {
1948 continue;
1949 }
1950
1951 if ($localizeChildrenAtParentLocalization) {
1952 $this->messages[] = 'The TCA setting \'localizeChildrenAtParentLocalization\' is deprecated '
1953 . ' and should be removed from TCA for ' . $table . '[\'columns\']'
1954 . '[\'' . $fieldName . '\'][\'config\'][\'behaviour\'][\'localizeChildrenAtParentLocalization\']';
1955 } else {
1956 $this->messages[] = 'The TCA setting \'localizeChildrenAtParentLocalization\' is deprecated '
1957 . ', as this functionality is always enabled. The option should be removed from TCA for '
1958 . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'behaviour\']'
1959 . '[\'localizeChildrenAtParentLocalization\']';
1960 }
1961 unset($fieldConfig['config']['behaviour']['localizeChildrenAtParentLocalization']);
1962 }
1963 }
1964 return $tca;
1965 }
1966
1967 /**
1968 * Removes $TCA['pages_language_overlay'] if defined.
1969 *
1970 * @param array $tca
1971 * @return array the modified TCA structure
1972 */
1973 protected function migratePagesLanguageOverlayRemoval(array $tca)
1974 {
1975 if (isset($tca['pages_language_overlay'])) {
1976 $this->messages[] = 'The TCA table \'pages_language_overlay\' is'
1977 . ' not used anymore and has been removed automatically in'
1978 . ' order to avoid negative side-effects.';
1979 unset($tca['pages_language_overlay']);
1980 }
1981 return $tca;
1982 }
1983
1984 /**
1985 * type=group with internal_type=file and internal_type=file_reference have
1986 * been deprecated in TYPO3 v9 and will be removed in TYPO3 v10.0. This method scans
1987 * for usages. This methods does not modify TCA.
1988 *
1989 * @param array $tca
1990 * @return array
1991 * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
1992 */
1993 protected function deprecateTypeGroupInternalTypeFile(array $tca): array
1994 {
1995 foreach ($tca as $table => $tableDefinition) {
1996 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
1997 continue;
1998 }
1999 foreach ($tableDefinition['columns'] as $fieldName => $fieldConfig) {
2000 if (isset($fieldConfig['config']['type'], $fieldConfig['config']['internal_type'])
2001 && $fieldConfig['config']['type'] === 'group'
2002 && ($fieldConfig['config']['internal_type'] === 'file' || $fieldConfig['config']['internal_type'] === 'file_reference')
2003 ) {
2004 $this->messages[] = 'The \'internal_type\' = \'' . $fieldConfig['config']['internal_type'] . '\' property value'
2005 . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'] is deprecated. It will continue'
2006 . ' to work is TYPO3 v9, but the functionality will be removed in TYPO3 v10.0. Switch to inline FAL instead.';
2007 }
2008 }
2009 }
2010 return $tca;
2011 }
2012 }