Passed
Branch master (6c65a4)
by Christian
16:31
created

TcaMigration   F

Complexity

Total Complexity 756

Size/Duplication

Total Lines 2550
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 2550
rs 0.6314
c 0
b 0
f 0
wmc 756

45 Methods

Rating   Name   Duplication   Size   Complexity  
A migrate() 0 47 1
C migrateSelectFieldRenderType() 0 52 13
C migrateExtAndSysextPathToEXTPath() 0 38 14
C migratePageLocalizationDefinitions() 0 38 8
B validateTcaType() 0 11 8
B migrateIconfileRelativePathOrFilenameOnlyToExtReference() 0 20 7
D migrateSelectTreeOptions() 0 33 10
F migrateLinkWizardToRenderTypeAndFieldControl() 0 99 38
C migrateIconsForFormFieldWizardToNewLocation() 0 51 12
C migrateSelectWizardToValuePicker() 0 64 31
A getMessages() 0 3 1
C migrateInputDateTimeToRenderType() 0 26 11
D migrateT3editorWizardToRenderTypeT3editorIfNotEnabledByTypeConfig() 0 44 17
C migrateSuggestWizardTypeGroup() 0 74 28
D migrateAddWizardToFieldControl() 0 95 37
B migrateWorkspacesOptions() 0 15 6
D migrateL10nModeDefinitions() 0 28 9
C migrateSelectFieldIconTable() 0 37 12
C migrateTSconfigSoftReferences() 0 35 11
D migrateListWizardToFieldControl() 0 88 35
B migrateRequestUpdate() 0 17 5
A migratePagesLanguageOverlayRemoval() 0 9 2
B migrateColumnsConfig() 0 18 8
D migrateFullScreenRichtextToFieldControl() 0 107 49
D migrateEditWizardToFieldControl() 0 79 33
C migrateImageManipulationConfig() 0 55 10
C migrateElementBrowserWizardToLinkHandler() 0 24 10
C migrateColorPickerWizardToRenderType() 0 60 26
B migrateIconsInOptionTags() 0 17 6
B migrateShowIfRteOption() 0 17 8
C migrateShowItemAdditionalPaletteToOwnPalette() 0 46 12
C migrateSelectShowIconTable() 0 35 11
C migrateLocalizeChildrenAtParentLocalization() 0 30 8
C migrateSliderWizardToSliderConfiguration() 0 57 25
A migrateTranslationTable() 0 15 4
D migrateInlineOverrideChildTca() 0 96 42
C migrateWizardEnableByTypeConfigToColumnsOverrides() 0 69 23
B migrateinputDateTimeMax() 0 18 8
D migrateTableWizardToRenderType() 0 89 39
D migrateT3editorWizardWithEnabledByTypeConfigToColumnsOverrides() 0 86 26
D migrateLastPiecesOfDefaultExtras() 0 85 23
C migrateDefaultExtrasRteTransFormOptions() 0 60 20
C migrateOptionsOfTypeGroup() 0 67 19
C migrateSpecialConfigurationAndRemoveShowItemStylePointerConfig() 0 68 21
D migrateInlineLocalizationMode() 0 31 9

How to fix   Complexity   

Complex Class

Complex classes like TcaMigration often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use TcaMigration, and based on these observations, apply Extract Interface, too.

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->migrateT3editorWizardToRenderTypeT3editorIfNotEnabledByTypeConfig($tca);
53
        $tca = $this->migrateSpecialConfigurationAndRemoveShowItemStylePointerConfig($tca);
54
        $tca = $this->migrateT3editorWizardWithEnabledByTypeConfigToColumnsOverrides($tca);
55
        $tca = $this->migrateShowItemAdditionalPaletteToOwnPalette($tca);
56
        $tca = $this->migrateIconsForFormFieldWizardToNewLocation($tca);
57
        $tca = $this->migrateExtAndSysextPathToEXTPath($tca);
58
        $tca = $this->migrateIconsInOptionTags($tca);
59
        $tca = $this->migrateIconfileRelativePathOrFilenameOnlyToExtReference($tca);
60
        $tca = $this->migrateSelectFieldRenderType($tca);
61
        $tca = $this->migrateSelectFieldIconTable($tca);
62
        $tca = $this->migrateElementBrowserWizardToLinkHandler($tca);
63
        $tca = $this->migrateDefaultExtrasRteTransFormOptions($tca);
64
        $tca = $this->migrateSelectTreeOptions($tca);
65
        $tca = $this->migrateTSconfigSoftReferences($tca);
66
        $tca = $this->migrateShowIfRteOption($tca);
67
        $tca = $this->migrateWorkspacesOptions($tca);
68
        $tca = $this->migrateTranslationTable($tca);
69
        $tca = $this->migrateL10nModeDefinitions($tca);
70
        $tca = $this->migratePageLocalizationDefinitions($tca);
71
        $tca = $this->migrateInlineLocalizationMode($tca);
72
        $tca = $this->migrateRequestUpdate($tca);
73
        $tca = $this->migrateInputDateTimeToRenderType($tca);
74
        $tca = $this->migrateWizardEnableByTypeConfigToColumnsOverrides($tca);
75
        $tca = $this->migrateColorPickerWizardToRenderType($tca);
76
        $tca = $this->migrateSelectWizardToValuePicker($tca);
77
        $tca = $this->migrateSliderWizardToSliderConfiguration($tca);
78
        $tca = $this->migrateLinkWizardToRenderTypeAndFieldControl($tca);
79
        $tca = $this->migrateEditWizardToFieldControl($tca);
80
        $tca = $this->migrateAddWizardToFieldControl($tca);
81
        $tca = $this->migrateListWizardToFieldControl($tca);
82
        $tca = $this->migrateLastPiecesOfDefaultExtras($tca);
83
        $tca = $this->migrateTableWizardToRenderType($tca);
84
        $tca = $this->migrateFullScreenRichtextToFieldControl($tca);
85
        $tca = $this->migrateSuggestWizardTypeGroup($tca);
86
        $tca = $this->migrateOptionsOfTypeGroup($tca);
87
        $tca = $this->migrateSelectShowIconTable($tca);
88
        $tca = $this->migrateImageManipulationConfig($tca);
89
        $tca = $this->migrateinputDateTimeMax($tca);
90
        $tca = $this->migrateInlineOverrideChildTca($tca);
91
        $tca = $this->migrateLocalizeChildrenAtParentLocalization($tca);
92
        $tca = $this->migratePagesLanguageOverlayRemoval($tca);
93
        return $tca;
94
    }
95
96
    /**
97
     * Get messages of migrated fields. Can be used for deprecation messages after migrate() was called.
98
     *
99
     * @return array Migration messages
100
     */
101
    public function getMessages(): array
102
    {
103
        return $this->messages;
104
    }
105
106
    /**
107
     * Check for required TCA configuration
108
     *
109
     * @param array $tca Incoming TCA
110
     */
111
    protected function validateTcaType(array $tca)
112
    {
113
        foreach ($tca as $table => $tableDefinition) {
114
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
115
                continue;
116
            }
117
            foreach ($tableDefinition['columns'] as $fieldName => $fieldConfig) {
118
                if (isset($fieldConfig['config']) && is_array($fieldConfig['config']) && empty($fieldConfig['config']['type'])) {
119
                    throw new \UnexpectedValueException(
120
                        'Missing "type" in TCA of field "[\'' . $table . '\'][\'' . $fieldName . '\'][\'config\']".',
121
                        1482394401
122
                    );
123
                }
124
            }
125
        }
126
    }
127
128
    /**
129
     * Find columns fields that don't have a 'config' section at all, add
130
     * ['config']['type'] = 'none'; for those to enforce config
131
     *
132
     * @param array $tca Incoming TCA
133
     * @return array
134
     */
135
    protected function migrateColumnsConfig(array $tca): array
136
    {
137
        foreach ($tca as $table => &$tableDefinition) {
138
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
139
                continue;
140
            }
141
            foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
142
                if ((!isset($fieldConfig['config']) || !is_array($fieldConfig['config'])) && !isset($fieldConfig['type'])) {
143
                    $fieldConfig['config'] = [
144
                        'type' => 'none',
145
                    ];
146
                    $this->messages[] = 'TCA table "' . $table . '" columns field "' . $fieldName . '"'
147
                        . ' had no mandatory "config" section. This has been added with default type "none":'
148
                        . ' TCA "' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'type\'] = \'none\'"';
149
                }
150
            }
151
        }
152
        return $tca;
153
    }
154
155
    /**
156
     * Migrate type=text field with t3editor wizard to renderType=t3editor without this wizard
157
     *
158
     * @param array $tca Incoming TCA
159
     * @return array Migrated TCA
160
     */
161
    protected function migrateT3editorWizardToRenderTypeT3editorIfNotEnabledByTypeConfig(array $tca): array
162
    {
163
        $newTca = $tca;
164
        foreach ($tca as $table => $tableDefinition) {
165
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
166
                continue;
167
            }
168
            foreach ($tableDefinition['columns'] as $fieldName => $fieldConfig) {
169
                if (
170
                    !empty($fieldConfig['config']['type']) // type is set
171
                    && trim($fieldConfig['config']['type']) === 'text' // to "text"
172
                    && isset($fieldConfig['config']['wizards'])
173
                    && is_array($fieldConfig['config']['wizards']) // and there are wizards
174
                ) {
175
                    foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
176
                        if (
177
                            !empty($wizardConfig['userFunc']) // a userFunc is defined
178
                            && trim($wizardConfig['userFunc']) === 'TYPO3\\CMS\\T3editor\\FormWizard->main' // and set to FormWizard
179
                            && (
180
                                !isset($wizardConfig['enableByTypeConfig']) // and enableByTypeConfig is not set
181
                                || (isset($wizardConfig['enableByTypeConfig']) && !$wizardConfig['enableByTypeConfig'])  // or set, but not enabled
182
                            )
183
                        ) {
184
                            // Set renderType from text to t3editor
185
                            $newTca[$table]['columns'][$fieldName]['config']['renderType'] = 't3editor';
186
                            // Unset this wizard definition
187
                            unset($newTca[$table]['columns'][$fieldName]['config']['wizards'][$wizardName]);
188
                            // Move format parameter
189
                            if (!empty($wizardConfig['params']['format'])) {
190
                                $newTca[$table]['columns'][$fieldName]['config']['format'] = $wizardConfig['params']['format'];
191
                            }
192
                            $this->messages[] = 'The t3editor wizard using \'type\' = \'text\' has been migrated to a \'renderType\' = \'t3editor\' definition.'
193
                            . 'It has been migrated from TCA "' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'t3editor\']"'
194
                            . 'to "' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'renderType\'] = \'t3editor\'"';
195
                        }
196
                    }
197
                    // If no wizard is left after migration, unset the whole sub array
198
                    if (empty($newTca[$table]['columns'][$fieldName]['config']['wizards'])) {
199
                        unset($newTca[$table]['columns'][$fieldName]['config']['wizards']);
200
                    }
201
                }
202
            }
203
        }
204
        return $newTca;
205
    }
206
207
    /**
208
     * Remove "style pointer", the 5th parameter from "types" "showitem" configuration.
209
     * Move "specConf", 4th parameter from "types" "showitem" to "types" "columnsOverrides".
210
     *
211
     * @param array $tca Incoming TCA
212
     * @return array Modified TCA
213
     */
214
    protected function migrateSpecialConfigurationAndRemoveShowItemStylePointerConfig(array $tca): array
215
    {
216
        $newTca = $tca;
217
        foreach ($tca as $table => $tableDefinition) {
218
            if (!isset($tableDefinition['types']) || !is_array($tableDefinition['types'])) {
219
                continue;
220
            }
221
            foreach ($tableDefinition['types'] as $typeName => $typeArray) {
222
                if (!isset($typeArray['showitem']) || !is_string($typeArray['showitem']) || strpos($typeArray['showitem'], ';') === false) {
223
                    // Continue directly if no semicolon is found
224
                    continue;
225
                }
226
                $itemList = GeneralUtility::trimExplode(',', $typeArray['showitem'], true);
227
                $newFieldStrings = [];
228
                foreach ($itemList as $fieldString) {
229
                    $fieldString = rtrim($fieldString, ';');
230
                    // Unpack the field definition, migrate and remove as much as possible
231
                    // Keep empty parameters in trimExplode here (third parameter FALSE), so position is not changed
232
                    $fieldArray = GeneralUtility::trimExplode(';', $fieldString);
233
                    $fieldArray = [
234
                        'fieldName' => $fieldArray[0] ?? '',
235
                        'fieldLabel' => $fieldArray[1] ?? null,
236
                        'paletteName' => $fieldArray[2] ?? null,
237
                        'fieldExtra' => $fieldArray[3] ?? null,
238
                    ];
239
                    if (!empty($fieldArray['fieldExtra'])) {
240
                        // Move fieldExtra "specConf" to columnsOverrides "defaultExtras"
241
                        if (!isset($newTca[$table]['types'][$typeName]['columnsOverrides'])) {
242
                            $newTca[$table]['types'][$typeName]['columnsOverrides'] = [];
243
                        }
244
                        if (!isset($newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldArray['fieldName']])) {
245
                            $newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldArray['fieldName']] = [];
246
                        }
247
                        // Merge with given defaultExtras from columns.
248
                        // They will be the first part of the string, so if "specConf" from types changes the same settings,
249
                        // those will override settings from defaultExtras of columns
250
                        $newDefaultExtras = [];
251
                        if (!empty($tca[$table]['columns'][$fieldArray['fieldName']]['defaultExtras'])) {
252
                            $newDefaultExtras[] = $tca[$table]['columns'][$fieldArray['fieldName']]['defaultExtras'];
253
                        }
254
                        $newDefaultExtras[] = $fieldArray['fieldExtra'];
255
                        $newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldArray['fieldName']]['defaultExtras'] = implode(':', $newDefaultExtras);
256
                    }
257
                    unset($fieldArray['fieldExtra']);
258
                    if (count($fieldArray) === 3 && empty($fieldArray['paletteName'])) {
259
                        unset($fieldArray['paletteName']);
260
                    }
261
                    if (count($fieldArray) === 2 && empty($fieldArray['fieldLabel'])) {
262
                        unset($fieldArray['fieldLabel']);
263
                    }
264
                    if (count($fieldArray) === 1 && empty($fieldArray['fieldName'])) {
265
                        // The field may vanish if nothing is left
266
                        unset($fieldArray['fieldName']);
267
                    }
268
                    $newFieldString = implode(';', $fieldArray);
269
                    if ($newFieldString !== $fieldString) {
270
                        $this->messages[] = 'The 4th parameter \'specConf\' of the field \'showitem\' with fieldName = \'' . $fieldArray['fieldName'] . '\' has been migrated, from TCA table "'
271
                            . $table . '[\'types\'][\'' . $typeName . '\'][\'showitem\']"' . 'to "'
272
                            . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldArray['fieldName'] . '\'][\'defaultExtras\']".';
273
                    }
274
                    if (!empty($newFieldString)) {
275
                        $newFieldStrings[] = $newFieldString;
276
                    }
277
                }
278
                $newTca[$table]['types'][$typeName]['showitem'] = implode(',', $newFieldStrings);
279
            }
280
        }
281
        return $newTca;
282
    }
283
284
    /**
285
     * Migrate type=text field with t3editor wizard that is "enableByTypeConfig" to columnsOverrides
286
     * with renderType=t3editor
287
     *
288
     * @param array $tca Incoming TCA
289
     * @return array Migrated TCA
290
     */
291
    protected function migrateT3editorWizardWithEnabledByTypeConfigToColumnsOverrides(array $tca): array
292
    {
293
        $newTca = $tca;
294
        foreach ($tca as $table => $tableDefinition) {
295
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
296
                continue;
297
            }
298
            foreach ($tableDefinition['columns'] as $fieldName => $fieldConfig) {
299
                if (
300
                    !empty($fieldConfig['config']['type']) // type is set
301
                    && trim($fieldConfig['config']['type']) === 'text' // to "text"
302
                    && isset($fieldConfig['config']['wizards'])
303
                    && is_array($fieldConfig['config']['wizards']) // and there are wizards
304
                ) {
305
                    foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
306
                        if (
307
                            !empty($wizardConfig['userFunc']) // a userFunc is defined
308
                            && trim($wizardConfig['userFunc']) === 'TYPO3\CMS\T3editor\FormWizard->main' // and set to FormWizard
309
                            && !empty($wizardConfig['enableByTypeConfig']) // and enableByTypeConfig is enabled
310
                        ) {
311
                            // Remove this wizard
312
                            unset($newTca[$table]['columns'][$fieldName]['config']['wizards'][$wizardName]);
313
                            // Find configured types that use this wizard
314
                            if (!isset($tableDefinition['types']) || !is_array($tableDefinition['types'])) {
315
                                // No type definition at all ... continue directly
316
                                continue;
317
                            }
318
                            foreach ($tableDefinition['types'] as $typeName => $typeArray) {
319
                                if (
320
                                    empty($typeArray['columnsOverrides'][$fieldName]['defaultExtras'])
321
                                    || strpos($typeArray['columnsOverrides'][$fieldName]['defaultExtras'], $wizardName) === false
322
                                ) {
323
                                    // Continue directly if this wizard is not enabled for given type
324
                                    continue;
325
                                }
326
                                $defaultExtras = $typeArray['columnsOverrides'][$fieldName]['defaultExtras'];
327
                                $defaultExtrasArray = GeneralUtility::trimExplode(':', $defaultExtras, true);
328
                                $newDefaultExtrasArray = [];
329
                                foreach ($defaultExtrasArray as $fieldExtraField) {
330
                                    // There might be multiple enabled wizards separated by | ... split them
331
                                    if (substr($fieldExtraField, 0, 8) === 'wizards[') {
332
                                        $enabledWizards = substr($fieldExtraField, 8, strlen($fieldExtraField) - 8); // Cut off "wizards[
333
                                        $enabledWizards = substr($enabledWizards, 0, strlen($enabledWizards) - 1);
334
                                        $enabledWizardsArray = GeneralUtility::trimExplode('|', $enabledWizards, true);
335
                                        $newEnabledWizardsArray = [];
336
                                        foreach ($enabledWizardsArray as $enabledWizardName) {
337
                                            if ($enabledWizardName === $wizardName) {
338
                                                // Found a columnsOverrides configuration that has this wizard enabled
339
                                                // Force renderType = t3editor
340
                                                $newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldName]['config']['renderType'] = 't3editor';
341
                                                // Transfer format option if given
342
                                                if (!empty($wizardConfig['params']['format'])) {
343
                                                    $newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldName]['config']['format'] = $wizardConfig['params']['format'];
344
                                                }
345
                                                $this->messages[] = 'The t3editor wizard using \'type\' = \'text\', with the "enableByTypeConfig" wizard set to 1,'
346
                                                . 'has been migrated to the \'renderType\' = \'t3editor\' definition.'
347
                                                . 'It has been migrated from TCA "' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'t3editor\']"'
348
                                                . 'to "' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'renderType\'] = \'t3editor\'"';
349
                                            } else {
350
                                                // Some other enabled wizard
351
                                                $newEnabledWizardsArray[] = $enabledWizardName;
352
                                            }
353
                                        }
354
                                        if (!empty($newEnabledWizardsArray)) {
355
                                            $newDefaultExtrasArray[] = 'wizards[' . implode('|', $newEnabledWizardsArray) . ']';
356
                                        }
357
                                    } else {
358
                                        $newDefaultExtrasArray[] = $fieldExtraField;
359
                                    }
360
                                }
361
                                if (!empty($newDefaultExtrasArray)) {
362
                                    $newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldName]['defaultExtras'] = implode(':', $newDefaultExtrasArray);
363
                                } else {
364
                                    unset($newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldName]['defaultExtras']);
365
                                }
366
                            }
367
                        }
368
                    }
369
                    // If no wizard is left after migration, unset the whole sub array
370
                    if (empty($newTca[$table]['columns'][$fieldName]['config']['wizards'])) {
371
                        unset($newTca[$table]['columns'][$fieldName]['config']['wizards']);
372
                    }
373
                }
374
            }
375
        }
376
        return $newTca;
377
    }
378
379
    /**
380
     * Migrate types showitem 'aField;aLabel;aPalette' to 'afield;aLabel, --palette--;;aPalette'
381
     *
382
     * Old showitem can have a syntax like:
383
     * fieldName;aLabel;aPalette
384
     * This way, the palette with name "aPalette" is rendered after fieldName.
385
     * The migration parses this to a syntax like:
386
     * fieldName;aLabel, --palette--;;paletteName
387
     *
388
     * @param array $tca Incoming TCA
389
     * @return array Migrated TCA
390
     */
391
    protected function migrateShowItemAdditionalPaletteToOwnPalette(array $tca): array
392
    {
393
        $newTca = $tca;
394
        foreach ($tca as $table => $tableDefinition) {
395
            if (!isset($tableDefinition['types']) || !is_array($tableDefinition['types'])) {
396
                continue;
397
            }
398
            foreach ($tableDefinition['types'] as $typeName => $typeArray) {
399
                if (
400
                    !isset($typeArray['showitem'])
401
                    || !is_string($typeArray['showitem'])
402
                    || strpos($typeArray['showitem'], ';') === false // no field parameters
403
                ) {
404
                    continue;
405
                }
406
                $itemList = GeneralUtility::trimExplode(',', $typeArray['showitem'], true);
407
                $newFieldStrings = [];
408
                foreach ($itemList as $fieldString) {
409
                    $fieldArray = GeneralUtility::trimExplode(';', $fieldString);
410
                    $fieldArray = [
411
                        'fieldName' => $fieldArray[0] ?? '',
412
                        'fieldLabel' => $fieldArray[1] ?? null,
413
                        'paletteName' => $fieldArray[2] ?? null,
414
                    ];
415
                    if ($fieldArray['fieldName'] !== '--palette--' && $fieldArray['paletteName'] !== null) {
416
                        if ($fieldArray['fieldLabel']) {
417
                            $fieldString = $fieldArray['fieldName'] . ';' . $fieldArray['fieldLabel'];
418
                        } else {
419
                            $fieldString = $fieldArray['fieldName'];
420
                        }
421
                        $paletteString = '--palette--;;' . $fieldArray['paletteName'];
422
                        $this->messages[] = 'Migrated \'showitem\' field from TCA table '
423
                            . $table . '[\'types\'][\'' . $typeName . '\']" : Moved additional palette'
424
                            . ' with name "' . $table . '[\'types\'][\'' . $typeName . '\'][\'' . $fieldArray['paletteName'] . '\']" as 3rd argument of field "'
425
                            . $table . '[\'types\'][\'' . $typeName . '\'][\'' . $fieldArray['fieldName'] . '\']"'
426
                            . 'to an own palette. The result of this part is: "' . $fieldString . ', ' . $paletteString . '"';
427
                        $newFieldStrings[] = $fieldString;
428
                        $newFieldStrings[] = $paletteString;
429
                    } else {
430
                        $newFieldStrings[] = $fieldString;
431
                    }
432
                }
433
                $newTca[$table]['types'][$typeName]['showitem'] = implode(',', $newFieldStrings);
434
            }
435
        }
436
        return $newTca;
437
    }
438
439
    /**
440
     * Migrate core icons for form field wizard to new location
441
     *
442
     * @param array $tca Incoming TCA
443
     * @return array Migrated TCA
444
     */
445
    protected function migrateIconsForFormFieldWizardToNewLocation(array $tca): array
446
    {
447
        $newTca = $tca;
448
449
        $newFileLocations = [
450
            'add.gif' => 'actions-add',
451
            'link_popup.gif' => 'actions-wizard-link',
452
            'wizard_rte2.gif' => 'actions-wizard-rte',
453
            'wizard_table.gif' => 'content-table',
454
            'edit2.gif' => 'actions-open',
455
            'list.gif' => 'actions-system-list-open',
456
            'wizard_forms.gif' => 'EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_forms.gif',
457
            'EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_add.gif' => 'actions-add',
458
            'EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_table.gif' => 'content-table',
459
            'EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_edit.gif' => 'actions-open',
460
            'EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_list.gif' => 'actions-system-list-open',
461
            'EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_link.gif' => 'actions-wizard-link',
462
            'EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_rte.gif' => 'actions-wizard-rte'
463
        ];
464
        $oldFileNames = array_keys($newFileLocations);
465
466
        foreach ($tca as $table => $tableDefinition) {
467
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
468
                continue;
469
            }
470
            foreach ($tableDefinition['columns'] as $fieldName => $fieldConfig) {
471
                if (
472
                    isset($fieldConfig['config']['wizards'])
473
                    && is_array($fieldConfig['config']['wizards']) // and there are wizards
474
                ) {
475
                    foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
476
                        if (!is_array($wizardConfig)) {
477
                            continue;
478
                        }
479
480
                        foreach ($wizardConfig as $option => $value) {
481
                            if ($option === 'icon' && in_array($value, $oldFileNames, true)) {
482
                                $newTca[$table]['columns'][$fieldName]['config']['wizards'][$wizardName]['icon'] = $newFileLocations[$value];
483
                                $this->messages[] = 'The icon path of wizard "' . $wizardName
484
                                    . '" from TCA table "'
485
                                    . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\'][\'icon\']"'
486
                                    . 'has been migrated to '
487
                                    . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\'][\'icon\']" = \'' . $newFileLocations[$value] . '\'.';
488
                            }
489
                        }
490
                    }
491
                }
492
            }
493
        }
494
495
        return $newTca;
496
    }
497
498
    /**
499
     * Migrate file reference which starts with ext/ or sysext/ to EXT:
500
     *
501
     * @param array $tca Incoming TCA
502
     * @return array Migrated TCA
503
     */
504
    protected function migrateExtAndSysextPathToEXTPath(array $tca): array
505
    {
506
        foreach ($tca as $table => &$tableDefinition) {
507
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
508
                continue;
509
            }
510
            foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
511
                if (
512
                    !empty($fieldConfig['config']['type']) // type is set
513
                    && trim($fieldConfig['config']['type']) === 'select' // to "select"
514
                    && isset($fieldConfig['config']['items'])
515
                    && is_array($fieldConfig['config']['items']) // and there are items
516
                ) {
517
                    foreach ($fieldConfig['config']['items'] as &$itemConfig) {
518
                        // more then two values? then the third entry is the image path
519
                        if (!empty($itemConfig[2])) {
520
                            $tcaPath = implode('.', [$table, 'columns', $fieldName, 'config', 'items']);
521
                            $pathParts = GeneralUtility::trimExplode('/', $itemConfig[2]);
522
                            // remove first element (ext or sysext)
523
                            array_shift($pathParts);
524
                            $path = implode('/', $pathParts);
525
                            // If the path starts with ext/ or sysext/ migrate it
526
                            if (
527
                                strpos($itemConfig[2], 'ext/') === 0
528
                                || strpos($itemConfig[2], 'sysext/') === 0
529
                            ) {
530
                                $this->messages[] = '[' . $tcaPath . '] ext/ or sysext/ within the path (' . $path . ') in items array is deprecated, use EXT: reference';
531
                                $itemConfig[2] = 'EXT:' . $path;
532
                            } elseif (strpos($itemConfig[2], 'i/') === 0) {
533
                                $this->messages[] = '[' . $tcaPath . '] i/ within the path (' . $path . ') in items array is deprecated, use EXT: reference';
534
                                $itemConfig[2] = 'EXT:backend/Resources/Public/Images/' . substr($itemConfig[2], 2);
535
                            }
536
                        }
537
                    }
538
                }
539
            }
540
        }
541
        return $tca;
542
    }
543
544
    /**
545
     * Migrate "iconsInOptionTags" for "select" TCA fields
546
     *
547
     * @param array $tca Incoming TCA
548
     * @return array Migrated TCA
549
     */
550
    protected function migrateIconsInOptionTags(array $tca): array
551
    {
552
        $newTca = $tca;
553
554
        foreach ($newTca as $table => &$tableDefinition) {
555
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
556
                continue;
557
            }
558
            foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
559
                if (isset($fieldConfig['config']['iconsInOptionTags'])) {
560
                    unset($fieldConfig['config']['iconsInOptionTags']);
561
                    $this->messages[] = 'Configuration option \'iconsInOptionTags\' was removed from field "' . $fieldName . '" in TCA table "' . $table . '[\'config\']"';
562
                }
563
            }
564
        }
565
566
        return $newTca;
567
    }
568
569
    /**
570
     * Migrate "iconfile" references which starts with ../ to EXT: and consisting of filename only to absolute paths in EXT:t3skin
571
     *
572
     * @param array $tca Incoming TCA
573
     * @return array Migrated TCA
574
     */
575
    protected function migrateIconfileRelativePathOrFilenameOnlyToExtReference(array $tca): array
576
    {
577
        foreach ($tca as $table => &$tableDefinition) {
578
            if (!isset($tableDefinition['ctrl']) || !is_array($tableDefinition['ctrl'])) {
579
                continue;
580
            }
581
            if (!isset($tableDefinition['ctrl']['iconfile'])) {
582
                continue;
583
            }
584
            if (strpos($tableDefinition['ctrl']['iconfile'], '../typo3conf/ext/') === 0) {
585
                $tableDefinition['ctrl']['iconfile'] = str_replace('../typo3conf/ext/', 'EXT:', $tableDefinition['ctrl']['iconfile']);
586
                $tcaPath = implode('.', [$table, 'ctrl', 'iconfile']);
587
                $this->messages[] = '[' . $tcaPath . '] relative path to ../typo3conf/ext/ is deprecated, use EXT: instead';
588
            } elseif (strpos($tableDefinition['ctrl']['iconfile'], '/') === false) {
589
                $tableDefinition['ctrl']['iconfile'] = 'EXT:backend/Resources/Public/Images/' . $tableDefinition['ctrl']['iconfile'];
590
                $tcaPath = implode('.', [$table, 'ctrl', 'iconfile']);
591
                $this->messages[] = '[' . $tcaPath . '] filename only is deprecated, use EXT: or absolute reference instead';
592
            }
593
        }
594
        return $tca;
595
    }
596
597
    /**
598
     * Migrate "type=select" with "renderMode=[tree|singlebox|checkbox]" to "renderType=[selectTree|selectSingleBox|selectCheckBox]".
599
     * This migration also take care of "maxitems" settings and set "renderType=[selectSingle|selectMultipleSideBySide]" if no other
600
     * renderType is already set.
601
     *
602
     * @param array $tca
603
     * @return array
604
     */
605
    public function migrateSelectFieldRenderType(array $tca): array
606
    {
607
        $newTca = $tca;
608
609
        foreach ($newTca as $table => &$tableDefinition) {
610
            if (empty($tableDefinition['columns'])) {
611
                continue;
612
            }
613
614
            foreach ($tableDefinition['columns'] as $columnName => &$columnDefinition) {
615
                // Only handle select fields.
616
                if (empty($columnDefinition['config']['type']) || $columnDefinition['config']['type'] !== 'select') {
617
                    continue;
618
                }
619
                // Do not handle field where the render type is set.
620
                if (!empty($columnDefinition['config']['renderType'])) {
621
                    continue;
622
                }
623
624
                $tableColumnInfo = 'table "' . $table . '[\'columns\'][\'' . $columnName . '\']"';
625
                $this->messages[] = 'Using the \'type\' = \'select\' field in "' . $table . '[\'columns\'][\'' . $columnName . '\'][\'config\'][\'type\'] = \'select\'" without the "renderType" setting in "'
626
                    . $table . '[\'columns\'][\'' . $columnName . '\'][\'config\'][\'renderType\']" is deprecated.';
627
628
                $columnConfig = &$columnDefinition['config'];
629
                if (!empty($columnConfig['renderMode'])) {
630
                    $this->messages[] = 'The "renderMode" setting for select fields is deprecated. Please use "renderType" instead in ' . $tableColumnInfo;
631
                    switch ($columnConfig['renderMode']) {
632
                        case 'tree':
633
                            $columnConfig['renderType'] = 'selectTree';
634
                            break;
635
                        case 'singlebox':
636
                            $columnConfig['renderType'] = 'selectSingleBox';
637
                            break;
638
                        case 'checkbox':
639
                            $columnConfig['renderType'] = 'selectCheckBox';
640
                            break;
641
                        default:
642
                            $this->messages[] = 'The render mode ' . $columnConfig['renderMode'] . ' is invalid for the select field in ' . $tableColumnInfo;
643
                    }
644
                    continue;
645
                }
646
647
                $maxItems = !empty($columnConfig['maxitems']) ? (int)$columnConfig['maxitems'] : 1;
648
                if ($maxItems <= 1) {
649
                    $columnConfig['renderType'] = 'selectSingle';
650
                } else {
651
                    $columnConfig['renderType'] = 'selectMultipleSideBySide';
652
                }
653
            }
654
        }
655
656
        return $newTca;
657
    }
658
659
    /**
660
     * Migrate the visibility of the icon table for fields with "renderType=selectSingle"
661
     *
662
     * @param array $tca
663
     * @return array Migrated TCA
664
     */
665
    public function migrateSelectFieldIconTable(array $tca): array
666
    {
667
        foreach ($tca as $table => &$tableDefinition) {
668
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
669
                continue;
670
            }
671
            foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
672
                if (empty($fieldConfig['config']['renderType']) || $fieldConfig['config']['renderType'] !== 'selectSingle') {
673
                    continue;
674
                }
675
                if (array_key_exists('noIconsBelowSelect', $fieldConfig['config'])) {
676
                    $this->messages[] = 'The "noIconsBelowSelect" setting for select fields in table "'
677
                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']" was removed. Please define the setting "showIconTable" in table "'
678
                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'showIconTable\']"';
679
                    if (!$fieldConfig['config']['noIconsBelowSelect']) {
680
                        // If old setting was explicitly false, enable icon table if not defined yet
681
                        if (!array_key_exists('showIconTable', $fieldConfig['config'])) {
682
                            $fieldConfig['config']['showIconTable'] = true;
683
                        }
684
                    }
685
                    unset($fieldConfig['config']['noIconsBelowSelect']);
686
                }
687
                if (array_key_exists('suppress_icons', $fieldConfig['config'])) {
688
                    $this->messages[] = 'The "suppress_icons" setting for select fields in table "'
689
                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']" was removed. Please define the setting "showIconTable" for table "'
690
                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'showIconTable\']"';
691
                    unset($fieldConfig['config']['suppress_icons']);
692
                }
693
                if (array_key_exists('foreign_table_loadIcons', $fieldConfig['config'])) {
694
                    $this->messages[] = 'The "foreign_table_loadIcons" setting for select fields in table "'
695
                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']" was removed. Please define the setting "showIconTable" for table "'
696
                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'showIconTable\']"';
697
                    unset($fieldConfig['config']['foreign_table_loadIcons']);
698
                }
699
            }
700
        }
701
        return $tca;
702
    }
703
704
    /**
705
     * Migrate wizard "wizard_element_browser" used in mode "wizard" to use the "wizard_link" instead
706
     *
707
     * @param array $tca
708
     * @return array Migrated TCA
709
     */
710
    protected function migrateElementBrowserWizardToLinkHandler(array $tca): array
711
    {
712
        foreach ($tca as $table => &$tableDefinition) {
713
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
714
                continue;
715
            }
716
            foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
717
                if (
718
                    isset($fieldConfig['config']['wizards']['link']['module']['name']) && $fieldConfig['config']['wizards']['link']['module']['name'] === 'wizard_element_browser'
719
                    && isset($fieldConfig['config']['wizards']['link']['module']['urlParameters']['mode']) && $fieldConfig['config']['wizards']['link']['module']['urlParameters']['mode'] === 'wizard'
720
                ) {
721
                    $fieldConfig['config']['wizards']['link']['module']['name'] = 'wizard_link';
722
                    unset($fieldConfig['config']['wizards']['link']['module']['urlParameters']['mode']);
723
                    if (empty($fieldConfig['config']['wizards']['link']['module']['urlParameters'])) {
724
                        unset($fieldConfig['config']['wizards']['link']['module']['urlParameters']);
725
                    }
726
                    $this->messages[] = 'Reference to "wizard_element_browser" was migrated from"'
727
                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'link\'][\'module\'][\'name\'] === \'wizard_element_browser\'"'
728
                        . 'to new "wizard_link", "'
729
                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'link\'][\'module\'][\'name\'] = \'wizard_link\' "';
730
                }
731
            }
732
        }
733
        return $tca;
734
    }
735
736
    /**
737
     * Migrate defaultExtras "richtext:rte_transform[mode=ts_css]" and similar stuff like
738
     * "richtext:rte_transform[mode=ts_css]" to "richtext:rte_transform"
739
     *
740
     * @param array $tca
741
     * @return array Migrated TCA
742
     */
743
    protected function migrateDefaultExtrasRteTransFormOptions(array $tca): array
744
    {
745
        foreach ($tca as $table => &$tableDefinition) {
746
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
747
                continue;
748
            }
749
            foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
750
                if (isset($fieldConfig['defaultExtras'])) {
751
                    $originalValue = $fieldConfig['defaultExtras'];
752
                    $defaultExtrasArray = GeneralUtility::trimExplode(':', $originalValue, true);
753
                    $isRichtextField = false;
754
                    foreach ($defaultExtrasArray as $defaultExtrasField) {
755
                        if (substr($defaultExtrasField, 0, 8) === 'richtext') {
756
                            $isRichtextField = true;
757
                            $fieldConfig['config']['enableRichtext'] = true;
758
                            $fieldConfig['config']['richtextConfiguration'] = 'default';
759
                        }
760
                    }
761
                    if ($isRichtextField) {
762
                        unset($fieldConfig['defaultExtras']);
763
                        $this->messages[] = 'RTE configuration via \'defaultExtras\' options are deprecated. String "' . $originalValue . '" in TCA'
764
                            . ' ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'defaultExtras\'] was changed to'
765
                            . ' options in ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']';
766
                    }
767
                }
768
            }
769
        }
770
771
        foreach ($tca as $table => &$tableDefinition) {
772
            if (!isset($tableDefinition['types']) || !is_array($tableDefinition['types'])) {
773
                continue;
774
            }
775
            foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
776
                if (!isset($typeArray['columnsOverrides']) || !is_array($typeArray['columnsOverrides'])) {
777
                    continue;
778
                }
779
                foreach ($typeArray['columnsOverrides'] as $fieldName => &$fieldConfig) {
780
                    if (isset($fieldConfig['defaultExtras'])) {
781
                        $originalValue = $fieldConfig['defaultExtras'];
782
                        $defaultExtrasArray = GeneralUtility::trimExplode(':', $originalValue, true);
783
                        $isRichtextField = false;
784
                        foreach ($defaultExtrasArray as $defaultExtrasField) {
785
                            if (substr($defaultExtrasField, 0, 8) === 'richtext') {
786
                                $isRichtextField = true;
787
                                $fieldConfig['config']['enableRichtext'] = true;
788
                                $fieldConfig['config']['richtextConfiguration'] = 'default';
789
                            }
790
                        }
791
                        if ($isRichtextField) {
792
                            unset($fieldConfig['defaultExtras']);
793
                            $this->messages[] = 'RTE configuration via \'defaultExtras\' options are deprecated. String "' . $originalValue . '" in TCA'
794
                                . ' ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\'][\'defaultExtras\']' .
795
                                ' was changed to options in ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']';
796
                        }
797
                    }
798
                }
799
            }
800
        }
801
802
        return $tca;
803
    }
804
805
    /**
806
     * Migrates selectTree fields deprecated options
807
     *
808
     * @param array $tca Incoming TCA
809
     * @return array Migrated TCA
810
     */
811
    protected function migrateSelectTreeOptions(array $tca): array
812
    {
813
        foreach ($tca as $table => &$tableDefinition) {
814
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
815
                continue;
816
            }
817
            foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
818
                if (isset($fieldConfig['config']['renderType']) && $fieldConfig['config']['renderType'] === 'selectTree') {
819
                    if (isset($fieldConfig['config']['treeConfig']['appearance']['width'])) {
820
                        $this->messages[] = 'The selectTree field [\'treeConfig\'][\'appearance\'][\'width\'] setting is deprecated'
821
                                    . ' and was removed in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
822
                                    . '[\'treeConfig\'][\'appearance\'][\'width\'] ';
823
                        unset($fieldConfig['config']['treeConfig']['appearance']['width']);
824
                    }
825
826
                    if (isset($fieldConfig['config']['treeConfig']['appearance']['allowRecursiveMode'])) {
827
                        $this->messages[] = 'The selectTree field [\'treeConfig\'][\'appearance\'][\'allowRecursiveMode\'] setting is deprecated'
828
                                    . ' and was removed in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
829
                                    . '[\'treeConfig\'][\'appearance\'][\'allowRecursiveMode\'] ';
830
                        unset($fieldConfig['config']['treeConfig']['appearance']['allowRecursiveMode']);
831
                    }
832
833
                    if (isset($fieldConfig['config']['autoSizeMax'])) {
834
                        $this->messages[] = 'The selectTree field [\'autoSizeMax\'] setting is deprecated'
835
                                    . ' and was removed in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'autoSizeMax\'].'
836
                                    . ' The \'size\' value was adapted to the previous autoSizeMax value';
837
                        $fieldConfig['config']['size'] = $fieldConfig['config']['autoSizeMax'];
838
                        unset($fieldConfig['config']['autoSizeMax']);
839
                    }
840
                }
841
            }
842
        }
843
        return $tca;
844
    }
845
846
    /**
847
     * Migrates selectTree fields deprecated options
848
     *
849
     * @param array $tca Incoming TCA
850
     * @return array Migrated TCA
851
     */
852
    protected function migrateTSconfigSoftReferences(array $tca): array
853
    {
854
        foreach ($tca as $table => &$tableDefinition) {
855
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
856
                continue;
857
            }
858
            foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
859
                if (isset($fieldConfig['config'])) {
860
                    if (isset($fieldConfig['config']['softref'])) {
861
                        $softReferences = array_flip(GeneralUtility::trimExplode(',', $fieldConfig['config']['softref']));
862
                        $changed = false;
863
                        if (isset($softReferences['TSconfig'])) {
864
                            $changed = true;
865
                            unset($softReferences['TSconfig']);
866
                        }
867
                        if (isset($softReferences['TStemplate'])) {
868
                            $changed = true;
869
                            unset($softReferences['TStemplate']);
870
                        }
871
                        if ($changed) {
872
                            if (!empty($softReferences)) {
873
                                $softReferences = array_flip($softReferences);
874
                                $fieldConfig['config']['softref'] = implode(',', $softReferences);
875
                            } else {
876
                                unset($fieldConfig['config']['softref']);
877
                            }
878
                            $this->messages[] = 'The soft reference setting using \'TSconfig\' and '
879
                                . '\'TStemplate\' was removed in TCA ' . $table . '[\'columns\']'
880
                                . '[\'' . $fieldName . '\'][\'config\'][\'softref\']';
881
                        }
882
                    }
883
                }
884
            }
885
        }
886
        return $tca;
887
    }
888
889
    /**
890
     * Removes the option "showIfRTE" for TCA type "check"
891
     *
892
     * @param array $tca Incoming TCA
893
     * @return array Migrated TCA
894
     */
895
    protected function migrateShowIfRteOption(array $tca): array
896
    {
897
        foreach ($tca as $table => &$tableDefinition) {
898
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
899
                continue;
900
            }
901
            foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
902
                if (isset($fieldConfig['config']) && $fieldConfig['config']['type'] === 'check') {
903
                    if (isset($fieldConfig['config']['showIfRTE'])) {
904
                        unset($fieldConfig['config']['showIfRTE']);
905
                        $this->messages[] = 'The TCA setting \'showIfRTE\' was removed '
906
                            . 'in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']';
907
                    }
908
                }
909
            }
910
        }
911
        return $tca;
912
    }
913
914
    /**
915
     * Casts "versioningWS" to bool, and removes "versioning_followPages"
916
     *
917
     * @param array $tca Incoming TCA
918
     * @return array Migrated TCA
919
     */
920
    protected function migrateWorkspacesOptions(array $tca): array
921
    {
922
        foreach ($tca as $table => &$tableDefinition) {
923
            if (isset($tableDefinition['ctrl']['versioningWS']) && !is_bool($tableDefinition['ctrl']['versioningWS'])) {
924
                $tableDefinition['ctrl']['versioningWS'] = (bool)$tableDefinition['ctrl']['versioningWS'];
925
                $this->messages[] = 'The TCA setting \'versioningWS\' was set to a boolean value '
926
                    . 'in TCA ' . $table . '[\'ctrl\'][\'versioningWS\']';
927
            }
928
            if (isset($tableDefinition['ctrl']['versioning_followPages']) && !empty($tableDefinition['ctrl']['versioning_followPages'])) {
929
                unset($tableDefinition['ctrl']['versioning_followPages']);
930
                $this->messages[] = 'The TCA setting \'versioning_followPages\' was removed as it is unused '
931
                    . 'in TCA ' . $table . '[\'ctrl\'][\'versioning_followPages\']';
932
            }
933
        }
934
        return $tca;
935
    }
936
937
    /**
938
     * Removes "transForeignTable" and "transOrigPointerTable" which has been
939
     * used for tables "pages" and "pages_languages_overlay" in the core only.
940
     *
941
     * @param array $tca Incoming TCA
942
     * @return array Migrated TCA
943
     */
944
    protected function migrateTranslationTable(array $tca): array
945
    {
946
        foreach ($tca as $table => &$tableDefinition) {
947
            if (!empty($tableDefinition['ctrl']['transForeignTable'])) {
948
                unset($tableDefinition['ctrl']['transForeignTable']);
949
                $this->messages[] = 'The TCA setting \'transForeignTable\' was removed '
950
                    . 'in TCA ' . $table . '[\'ctrl\'][\'transForeignTable\']';
951
            }
952
            if (!empty($tableDefinition['ctrl']['transOrigPointerTable'])) {
953
                unset($tableDefinition['ctrl']['transOrigPointerTable']);
954
                $this->messages[] = 'The TCA setting \'transOrigPointerTable\' was removed '
955
                    . 'in TCA ' . $table . '[\'ctrl\'][\'transOrigPointerTable\']';
956
            }
957
        }
958
        return $tca;
959
    }
960
961
    /**
962
     * Removes "noCopy" from possible settings for "l10n_mode" for each column.
963
     *
964
     * @param array $tca
965
     * @return array Migrated TCA
966
     */
967
    protected function migrateL10nModeDefinitions(array $tca)
968
    {
969
        foreach ($tca as $table => &$tableDefinition) {
970
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
971
                continue;
972
            }
973
            foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
974
                if (empty($fieldConfig['l10n_mode'])) {
975
                    continue;
976
                }
977
                if ($fieldConfig['l10n_mode'] === 'noCopy') {
978
                    unset($fieldConfig['l10n_mode']);
979
                    $this->messages[] = 'The TCA setting \'noCopy\' was removed '
980
                        . 'in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'l10n_mode\']';
981
                }
982
                if ($fieldConfig['l10n_mode'] === 'mergeIfNotBlank') {
983
                    unset($fieldConfig['l10n_mode']);
984
                    if (empty($fieldConfig['config']['behaviour']['allowLanguageSynchronization'])) {
985
                        $fieldConfig['config']['behaviour']['allowLanguageSynchronization'] = true;
986
                    }
987
                    $this->messages[] = 'The TCA setting \'mergeIfNotBlank\' was removed '
988
                        . 'in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'l10n_mode\']'
989
                        . ' and changed to ' . $table . '[\'columns\'][\'' . $fieldName . '\']'
990
                        . '[\'config\'][\'behaviour\'][\'allowLanguageSynchronization\'] = true';
991
                }
992
            }
993
        }
994
        return $tca;
995
    }
996
997
    /**
998
     * Migrates localization definitions such as "allowLanguageSynchronization"
999
     * or "l10n_mode" for tables pages and pages_language_overlay.
1000
     *
1001
     * @param array $tca
1002
     * @return array Migrated TCA
1003
     */
1004
    protected function migratePageLocalizationDefinitions(array $tca)
1005
    {
1006
        if (
1007
            empty($tca['pages_language_overlay']['columns'])
1008
        ) {
1009
            return $tca;
1010
        }
1011
1012
        // ensure, that localization settings are defined for
1013
        // pages and not for pages_language_overlay
1014
        foreach ($tca['pages_language_overlay']['columns'] as $fieldName => &$fieldConfig) {
1015
            $l10nMode = $fieldConfig['l10n_mode'] ?? null;
1016
            $allowLanguageSynchronization = $fieldConfig['config']['behaviour']['allowLanguageSynchronization'] ?? null;
1017
1018
            $oppositeFieldConfig = $tca['pages']['columns'][$fieldName] ?? [];
1019
            $oppositeL10nMode = $oppositeFieldConfig['l10n_mode'] ?? null;
1020
            $oppositeAllowLanguageSynchronization = $oppositeFieldConfig['config']['behaviour']['allowLanguageSynchronization'] ?? null;
1021
1022
            if ($l10nMode !== null) {
1023
                if (!empty($oppositeFieldConfig) && $oppositeL10nMode !== 'exclude') {
1024
                    $tca['pages']['columns'][$fieldName]['l10n_mode'] = $l10nMode;
1025
                    $this->messages[] = 'The TCA setting \'l10n_mode\' was migrated '
1026
                        . 'to TCA pages[\'columns\'][\'' . $fieldName . '\'][\'l10n_mode\'] '
1027
                        . 'from TCA pages_language_overlay[\'columns\'][\'' . $fieldName . '\'][\'l10n_mode\']';
1028
                }
1029
            }
1030
1031
            if (!empty($allowLanguageSynchronization) && empty($oppositeAllowLanguageSynchronization)) {
1032
                $tca['pages']['columns'][$fieldName]['config']['behaviour']['allowLanguageSynchronization'] = (bool)$allowLanguageSynchronization;
1033
                $this->messages[] = 'The TCA setting \'allowLanguageSynchronization\' was migrated '
1034
                    . 'to TCA pages[\'columns\'][\'' . $fieldName . '\']'
1035
                    . '[\'config\'][\'behaviour\'][\'allowLanguageSynchronization\'] '
1036
                    . 'from TCA pages_language_overlay[\'columns\'][\'' . $fieldName . '\']'
1037
                    . '[\'config\'][\'behaviour\'][\'allowLanguageSynchronization\']';
1038
            }
1039
        }
1040
1041
        return $tca;
1042
    }
1043
1044
    /**
1045
     * Removes "localizationMode" set to "keep" if used in combination with
1046
     * "allowLanguageSynchronization" - in general "localizationMode" is
1047
     * deprecated since TYPO3 CMS 8 and will be removed in TYPO3 CMS 9.
1048
     *
1049
     * @param array $tca
1050
     * @return array
1051
     */
1052
    protected function migrateInlineLocalizationMode(array $tca)
1053
    {
1054
        foreach ($tca as $table => &$tableDefinition) {
1055
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
1056
                continue;
1057
            }
1058
            foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1059
                if (($fieldConfig['config']['type'] ?? null) !== 'inline') {
1060
                    continue;
1061
                }
1062
1063
                $inlineLocalizationMode = ($fieldConfig['config']['behaviour']['localizationMode'] ?? null);
1064
                if ($inlineLocalizationMode === null) {
1065
                    continue;
1066
                }
1067
1068
                $allowLanguageSynchronization = ($fieldConfig['config']['behaviour']['allowLanguageSynchronization'] ?? null);
1069
                if ($inlineLocalizationMode === 'keep' && $allowLanguageSynchronization) {
1070
                    unset($fieldConfig['config']['behaviour']['localizationMode']);
1071
                    $this->messages[] = 'The TCA setting \'localizationMode\' is counter-productive '
1072
                        . ' if being used in combination with \'allowLanguageSynchronization\' and '
1073
                        . ' thus has been removed from TCA for ' . $table . '[\'columns\']'
1074
                        . '[\'' . $fieldName . '\'][\'config\'][\'behaviour\'][\'localizationMode\']';
1075
                } else {
1076
                    $this->messages[] = 'The TCA setting \'localizationMode\' is deprecated '
1077
                        . ' and should be removed from TCA for ' . $table . '[\'columns\']'
1078
                        . '[\'' . $fieldName . '\'][\'config\'][\'behaviour\'][\'localizationMode\']';
1079
                }
1080
            }
1081
        }
1082
        return $tca;
1083
    }
1084
1085
    /**
1086
     * Move ['ctrl']['requestUpdate'] to 'onChange => "reload"' of single fields
1087
     *
1088
     * @param array $tca Incoming TCA
1089
     * @return array Migrated TCA
1090
     */
1091
    protected function migrateRequestUpdate(array $tca): array
1092
    {
1093
        foreach ($tca as $table => &$tableDefinition) {
1094
            if (!empty($tableDefinition['ctrl']['requestUpdate'])) {
1095
                $fields = GeneralUtility::trimExplode(',', $tableDefinition['ctrl']['requestUpdate']);
1096
                foreach ($fields as $field) {
1097
                    if (isset($tableDefinition['columns'][$field])) {
1098
                        $tableDefinition['columns'][$field]['onChange'] = 'reload';
1099
                    }
1100
                }
1101
                $this->messages[] = 'The TCA setting [\'ctrl\'][\'requestUpdate\'] was removed from '
1102
                    . ' table ' . $table . '. The column field(s) "' . implode('" and "', $fields) . '" were updated'
1103
                    . ' and contain option "\'onChange\' => \'reload\'" parallel to \'config\' and \'label\' section.';
1104
                unset($tableDefinition['ctrl']['requestUpdate']);
1105
            }
1106
        }
1107
        return $tca;
1108
    }
1109
1110
    /**
1111
     * Move all type=input with eval=date/time configuration to an own renderType
1112
     *
1113
     * @param array $tca
1114
     * @return array Migrated TCA
1115
     */
1116
    protected function migrateInputDateTimeToRenderType(array $tca): array
1117
    {
1118
        foreach ($tca as $table => &$tableDefinition) {
1119
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
1120
                continue;
1121
            }
1122
            foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1123
                if ($fieldConfig['config']['type'] !== 'input') {
1124
                    continue;
1125
                }
1126
                $eval = $fieldConfig['config']['eval'] ?? '';
1127
                $eval = GeneralUtility::trimExplode(',', $eval, true);
1128
                if (in_array('date', $eval, true)
1129
                    || in_array('datetime', $eval, true)
1130
                    || in_array('time', $eval, true)
1131
                    || in_array('timesec', $eval, true)
1132
                ) {
1133
                    if (!isset($fieldConfig['config']['renderType'])) {
1134
                        $fieldConfig['config']['renderType'] = 'inputDateTime';
1135
                        $this->messages[] = 'The TCA setting \'renderType\' => \'inputDateTime\' was added '
1136
                            . 'in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']';
1137
                    }
1138
                }
1139
            }
1140
        }
1141
        return $tca;
1142
    }
1143
1144
    /**
1145
     * Wizards configuration may hold "enableByTypeConfig" and are then enabled
1146
     * for certain types via "defaultExtras".
1147
     * Find wizards configured like that and migrate them to "columnsOverrides"
1148
     *
1149
     * @param array $tca Incoming TCA
1150
     * @return array Migrated TCA
1151
     */
1152
    public function migrateWizardEnableByTypeConfigToColumnsOverrides(array $tca): array
1153
    {
1154
        $newTca = $tca;
1155
        foreach ($tca as $table => $tableDefinition) {
1156
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
1157
                continue;
1158
            }
1159
            foreach ($tableDefinition['columns'] as $fieldName => $fieldConfig) {
1160
                if (
1161
                    !empty($fieldConfig['config']['type']) // type is set
1162
                    && isset($fieldConfig['config']['wizards'])
1163
                    && is_array($fieldConfig['config']['wizards']) // and there are wizards
1164
                ) {
1165
                    foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
1166
                        if (isset($wizardConfig['enableByTypeConfig']) // and enableByTypeConfig is given
1167
                            && $wizardConfig['enableByTypeConfig'] // and enabled
1168
                        ) { // and enableByTypeConfig is enabled
1169
                            // Remove this "enableByTypeConfig" wizard from columns
1170
                            unset($newTca[$table]['columns'][$fieldName]['config']['wizards'][$wizardName]);
1171
                            if (!isset($tableDefinition['types']) || !is_array($tableDefinition['types'])) {
1172
                                // No type definition at all ... continue directly
1173
                                continue;
1174
                            }
1175
                            foreach ($tableDefinition['types'] as $typeName => $typeArray) {
1176
                                if (empty($typeArray['columnsOverrides'][$fieldName]['defaultExtras'])
1177
                                    || strpos($typeArray['columnsOverrides'][$fieldName]['defaultExtras'], $wizardName) === false
1178
                                ) {
1179
                                    // Continue directly if this wizard is not enabled for given type
1180
                                    continue;
1181
                                }
1182
                                $defaultExtras = $typeArray['columnsOverrides'][$fieldName]['defaultExtras'];
1183
                                $defaultExtrasArray = GeneralUtility::trimExplode(':', $defaultExtras, true);
1184
                                $newDefaultExtrasArray = [];
1185
                                foreach ($defaultExtrasArray as $fieldExtraField) {
1186
                                    if (substr($fieldExtraField, 0, 8) === 'wizards[') {
1187
                                        $enabledWizards = substr($fieldExtraField, 8, strlen($fieldExtraField) - 8); // Cut off "wizards[
1188
                                        $enabledWizards = substr($enabledWizards, 0, strlen($enabledWizards) - 1);
1189
                                        $enabledWizardsArray = GeneralUtility::trimExplode('|', $enabledWizards, true);
1190
                                        foreach ($enabledWizardsArray as $enabledWizardName) {
1191
                                            if ($enabledWizardName === $wizardName) {
1192
                                                // Fill new array
1193
                                                unset($newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldName]['defaultExtras']);
1194
                                                $newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldName]['config']['wizards'][$enabledWizardName] = $wizardConfig;
1195
                                                unset($newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldName]['config']['wizards'][$enabledWizardName]['enableByTypeConfig']);
1196
                                                $this->messages[] = 'The wizard with "enableByTypeConfig" set to 1 has been migrated to \'columnsOverrides\'.'
1197
                                                    . ' It has been migrated from "'
1198
                                                . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']" to '
1199
                                                . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\'].';
1200
                                            }
1201
                                        }
1202
                                    } else {
1203
                                        $newDefaultExtrasArray[] = $fieldExtraField;
1204
                                    }
1205
                                }
1206
                                if ($defaultExtrasArray !== $newDefaultExtrasArray
1207
                                    && !empty($newDefaultExtrasArray)
1208
                                ) {
1209
                                    $newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldName]['defaultExtras'] = implode(':', $newDefaultExtrasArray);
1210
                                }
1211
                            }
1212
                        } elseif (isset($wizardConfig['enableByTypeConfig'])) {
1213
                            // enableByTypeConfig is set, but not true or 1 or '1', just delete it.
1214
                            unset($newTca[$table]['columns'][$fieldName]['config']['wizards'][$wizardName]['enableByTypeConfig']);
1215
                        }
1216
                    }
1217
                }
1218
            }
1219
        }
1220
        return $newTca;
1221
    }
1222
1223
    /**
1224
     * Migrates fields having a colorpicker wizard to a color field
1225
     *
1226
     * @param array $tca Incoming TCA
1227
     * @return array Migrated TCA
1228
     */
1229
    protected function migrateColorPickerWizardToRenderType(array $tca): array
1230
    {
1231
        foreach ($tca as $table => &$tableDefinition) {
1232
            if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1233
                foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1234
                    if (isset($fieldConfig['config'])) {
1235
                        // Do not handle field where the render type is set.
1236
                        if (!empty($fieldConfig['config']['renderType'])) {
1237
                            continue;
1238
                        }
1239
                        if ($fieldConfig['config']['type'] === 'input') {
1240
                            if (isset($fieldConfig['config']['wizards']) && is_array($fieldConfig['config']['wizards'])) {
1241
                                foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizard) {
1242
                                    if (isset($wizard['type']) && ($wizard['type'] === 'colorbox')) {
1243
                                        unset($fieldConfig['config']['wizards'][$wizardName]);
1244
                                        if (empty($fieldConfig['config']['wizards'])) {
1245
                                            unset($fieldConfig['config']['wizards']);
1246
                                        }
1247
                                        $fieldConfig['config']['renderType'] = 'colorpicker';
1248
                                        $this->messages[] = 'The color-picker wizard using \'colorbox\' is deprecated'
1249
                                            . ' in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
1250
                                            . '[\'wizards\'][\'' . $wizardName . '\'] and was changed to ' . $table
1251
                                            . '[\'columns\'][\'' . $fieldName . '\'][\'config\'] = \'colorpicker\'';
1252
                                    }
1253
                                }
1254
                            }
1255
                            if (empty($fieldConfig['config']['wizards'])) {
1256
                                unset($fieldConfig['config']['wizards']);
1257
                            }
1258
                            if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
1259
                                foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
1260
                                    if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
1261
                                        if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1262
                                            && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1263
                                        ) {
1264
                                            foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
1265
                                                if (isset($wizard['type']) && ($wizard['type'] === 'colorbox')) {
1266
                                                    unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
1267
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['type'] = 'input';
1268
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['renderType'] = 'colorpicker';
1269
                                                    $this->messages[] = 'The color-picker wizard in columnsOverrides using \'colorbox\' has been migrated to a \'rendertype\' = \'colorpicker\'.'
1270
                                                        . ' It has been migrated from TCA "' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
1271
                                                        . '[\'wizards\'][\'' . $wizardName . '\'][\'type\'] = \'colorbox\'"" to "' . $table
1272
                                                        . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'renderType\'] = \'colorpicker\'"';
1273
                                                }
1274
                                            }
1275
                                            if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
1276
                                                unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
1277
                                            }
1278
                                        }
1279
                                    }
1280
                                }
1281
                            }
1282
                        }
1283
                    }
1284
                }
1285
            }
1286
        }
1287
1288
        return $tca;
1289
    }
1290
1291
    /**
1292
     * Move type=input with select wizard to config['valuePicker']
1293
     *
1294
     * @param array $tca
1295
     * @return array Migrated TCA
1296
     */
1297
    protected function migrateSelectWizardToValuePicker(array $tca): array
1298
    {
1299
        foreach ($tca as $table => &$tableDefinition) {
1300
            if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1301
                foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1302
                    if ($fieldConfig['config']['type'] === 'input' || $fieldConfig['config']['type'] === 'text') {
1303
                        if (isset($fieldConfig['config']['wizards']) && is_array($fieldConfig['config']['wizards'])) {
1304
                            foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
1305
                                if (isset($wizardConfig['type'])
1306
                                    && $wizardConfig['type'] === 'select'
1307
                                    && isset($wizardConfig['items'])
1308
                                    && is_array($wizardConfig['items'])
1309
                                ) {
1310
                                    $fieldConfig['config']['valuePicker']['items'] = $wizardConfig['items'];
1311
                                    if (isset($wizardConfig['mode'])
1312
                                        && is_string($wizardConfig['mode'])
1313
                                        && in_array($wizardConfig['mode'], ['append', 'prepend', ''])
1314
                                    ) {
1315
                                        $fieldConfig['config']['valuePicker']['mode'] = $wizardConfig['mode'];
1316
                                    }
1317
                                    unset($fieldConfig['config']['wizards'][$wizardName]);
1318
                                    $this->messages[] = 'The select wizard in TCA '
1319
                                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
1320
                                        . ' has been migrated to '
1321
                                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'valuePicker\'].';
1322
                                }
1323
                            }
1324
                        }
1325
                        if (empty($fieldConfig['config']['wizards'])) {
1326
                            unset($fieldConfig['config']['wizards']);
1327
                        }
1328
                        if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
1329
                            foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
1330
                                if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
1331
                                    if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1332
                                        && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1333
                                    ) {
1334
                                        foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
1335
                                            if (isset($wizard['type'])
1336
                                                && ($wizard['type'] === 'select')
1337
                                                && isset($wizard['items'])
1338
                                                && is_array($wizard['items'])
1339
                                            ) {
1340
                                                $typeArray['columnsOverrides'][$fieldName]['config']['valuePicker'] = $wizard;
1341
                                                unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
1342
                                                unset($typeArray['columnsOverrides'][$fieldName]['config']['valuePicker']['type']);
1343
                                                $this->messages[] = 'The select wizard in columnsOverrides using \'type\' = \'select\' has been migrated'
1344
                                                    . ' from TCA ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
1345
                                                    . '[\'wizards\'][\'' . $wizardName . '\'] to ' . $table
1346
                                                    . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'valuePicker\']';
1347
                                            }
1348
                                        }
1349
                                        if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
1350
                                            unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
1351
                                        }
1352
                                    }
1353
                                }
1354
                            }
1355
                        }
1356
                    }
1357
                }
1358
            }
1359
        }
1360
        return $tca;
1361
    }
1362
1363
    /**
1364
     * Move type=input with select wizard to config['valuePicker']
1365
     *
1366
     * @param array $tca
1367
     * @return array Migrated TCA
1368
     */
1369
    protected function migrateSliderWizardToSliderConfiguration(array $tca): array
1370
    {
1371
        foreach ($tca as $table => &$tableDefinition) {
1372
            if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1373
                foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1374
                    if ($fieldConfig['config']['type'] === 'input') {
1375
                        if (isset($fieldConfig['config']['wizards'])
1376
                            && is_array($fieldConfig['config']['wizards'])) {
1377
                            foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
1378
                                if (isset($wizardConfig['type']) && $wizardConfig['type'] === 'slider') {
1379
                                    $fieldConfig['config']['slider'] = [];
1380
                                    if (isset($wizardConfig['width'])) {
1381
                                        $fieldConfig['config']['slider']['width'] = $wizardConfig['width'];
1382
                                    }
1383
                                    if (isset($wizardConfig['step'])) {
1384
                                        $fieldConfig['config']['slider']['step'] = $wizardConfig['step'];
1385
                                    }
1386
                                    unset($fieldConfig['config']['wizards'][$wizardName]);
1387
                                    $this->messages[] = 'The slider wizard in TCA '
1388
                                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
1389
                                        . ' has been migrated to '
1390
                                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'slider\'].';
1391
                                }
1392
                            }
1393
                        }
1394
                        if (empty($fieldConfig['config']['wizards'])) {
1395
                            unset($fieldConfig['config']['wizards']);
1396
                        }
1397
                        if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
1398
                            foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
1399
                                if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
1400
                                    if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1401
                                        && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1402
                                    ) {
1403
                                        foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
1404
                                            if (isset($wizard['type']) && ($wizard['type'] === 'slider')) {
1405
                                                $typeArray['columnsOverrides'][$fieldName]['config']['slider'] = $wizard;
1406
                                                unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
1407
                                                unset($typeArray['columnsOverrides'][$fieldName]['config']['slider']['type']);
1408
                                                $this->messages[] = 'The slider wizard in columnsOverrides using \'type\' = \'slider\' has been migrated'
1409
                                                    . ' from TCA ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
1410
                                                    . '[\'wizards\'][\'' . $wizardName . '\'] to ' . $table
1411
                                                    . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'slider\']';
1412
                                            }
1413
                                        }
1414
                                        if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
1415
                                            unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
1416
                                        }
1417
                                    }
1418
                                }
1419
                            }
1420
                        }
1421
                    }
1422
                }
1423
            }
1424
        }
1425
        return $tca;
1426
    }
1427
1428
    /**
1429
     * Move type=input fields that have a "link" wizard to an own renderType with fieldControl
1430
     *
1431
     * @param array $tca
1432
     * @return array Modified TCA
1433
     */
1434
    protected function migrateLinkWizardToRenderTypeAndFieldControl(array $tca): array
1435
    {
1436
        foreach ($tca as $table => &$tableDefinition) {
1437
            if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1438
                foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1439
                    if ($fieldConfig['config']['type'] === 'input'
1440
                        && !isset($fieldConfig['config']['renderType'])
1441
                    ) {
1442
                        if (isset($fieldConfig['config']['wizards'])
1443
                            && is_array($fieldConfig['config']['wizards'])) {
1444
                            foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
1445
                                if (isset($wizardConfig['type'])
1446
                                    && $wizardConfig['type'] === 'popup'
1447
                                    && isset($wizardConfig['module']['name'])
1448
                                    && $wizardConfig['module']['name'] === 'wizard_link'
1449
                                ) {
1450
                                    $fieldConfig['config']['renderType'] = 'inputLink';
1451
                                    if (isset($wizardConfig['title'])) {
1452
                                        $fieldConfig['config']['fieldControl']['linkPopup']['options']['title'] = $wizardConfig['title'];
1453
                                    }
1454
                                    if (isset($wizardConfig['JSopenParams'])) {
1455
                                        $fieldConfig['config']['fieldControl']['linkPopup']['options']['windowOpenParameters']
1456
                                            = $wizardConfig['JSopenParams'];
1457
                                    }
1458
                                    if (isset($wizardConfig['params']['blindLinkOptions'])) {
1459
                                        $fieldConfig['config']['fieldControl']['linkPopup']['options']['blindLinkOptions']
1460
                                            = $wizardConfig['params']['blindLinkOptions'];
1461
                                    }
1462
                                    if (isset($wizardConfig['params']['blindLinkFields'])) {
1463
                                        $fieldConfig['config']['fieldControl']['linkPopup']['options']['blindLinkFields']
1464
                                            = $wizardConfig['params']['blindLinkFields'];
1465
                                    }
1466
                                    if (isset($wizardConfig['params']['allowedExtensions'])) {
1467
                                        $fieldConfig['config']['fieldControl']['linkPopup']['options']['allowedExtensions']
1468
                                            = $wizardConfig['params']['allowedExtensions'];
1469
                                    }
1470
                                    unset($fieldConfig['config']['wizards'][$wizardName]);
1471
                                    $this->messages[] = 'The link wizard has been migrated to a \'renderType\' => \'inputLink \'. '
1472
                                        . 'It has been migrated from TCA table "'
1473
                                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']" to "'
1474
                                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'renderType\'] = \'inputLink\'".';
1475
                                }
1476
                            }
1477
                        }
1478
                        if (empty($fieldConfig['config']['wizards'])) {
1479
                            unset($fieldConfig['config']['wizards']);
1480
                        }
1481
                        if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
1482
                            foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
1483
                                if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
1484
                                    if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1485
                                        && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1486
                                    ) {
1487
                                        foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
1488
                                            if (isset($wizard['type'])
1489
                                                && $wizard['type'] === 'popup'
1490
                                                && isset($wizard['module']['name'])
1491
                                                && $wizard['module']['name'] === 'wizard_link'
1492
                                            ) {
1493
                                                $typeArray['columnsOverrides'][$fieldName]['config']['renderType'] = 'inputLink';
1494
                                                if (isset($wizard['title'])) {
1495
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['linkPopup']['options']['title'] = $wizard['title'];
1496
                                                }
1497
                                                if (isset($wizard['JSopenParams'])) {
1498
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['linkPopup']['options']['windowOpenParameters']
1499
                                                        = $wizard['JSopenParams'];
1500
                                                }
1501
                                                if (isset($wizard['params']['blindLinkOptions'])) {
1502
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['linkPopup']['options']['blindLinkOptions']
1503
                                                        = $wizard['params']['blindLinkOptions'];
1504
                                                }
1505
                                                if (isset($wizard['params']['blindLinkFields'])) {
1506
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['linkPopup']['options']['blindLinkFields']
1507
                                                        = $wizard['params']['blindLinkFields'];
1508
                                                }
1509
                                                if (isset($wizard['params']['allowedExtensions'])) {
1510
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['linkPopup']['options']['allowedExtensions']
1511
                                                        = $wizard['params']['allowedExtensions'];
1512
                                                }
1513
                                                unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
1514
                                                $this->messages[] = 'The link wizard in columnsOverrides using \'type\' = \'popup\' has been migrated to a \'renderType\' = \'inputLink\'.'
1515
                                                    . ' It has been migrated from TCA "' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
1516
                                                    . '[\'wizards\'][\'' . $wizardName . '\']" to "' . $table
1517
                                                    . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'renderType\'] = \'inputLink\'"';
1518
                                            }
1519
                                        }
1520
                                        if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
1521
                                            unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
1522
                                        }
1523
                                    }
1524
                                }
1525
                            }
1526
                        }
1527
                    }
1528
                }
1529
            }
1530
        }
1531
1532
        return $tca;
1533
    }
1534
1535
    /**
1536
     * Find select and group fields with enabled edit wizard and migrate to "fieldControl"
1537
     *
1538
     * @param array $tca
1539
     * @return array
1540
     */
1541
    protected function migrateEditWizardToFieldControl(array $tca): array
1542
    {
1543
        foreach ($tca as $table => &$tableDefinition) {
1544
            if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1545
                foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1546
                    if ($fieldConfig['config']['type'] === 'group'
1547
                        || $fieldConfig['config']['type'] === 'select'
1548
                    ) {
1549
                        if (isset($fieldConfig['config']['wizards'])
1550
                            && is_array($fieldConfig['config']['wizards'])
1551
                        ) {
1552
                            foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
1553
                                if (isset($wizardConfig['type'])
1554
                                    && $wizardConfig['type'] === 'popup'
1555
                                    && isset($wizardConfig['module']['name'])
1556
                                    && $wizardConfig['module']['name'] === 'wizard_edit'
1557
                                    && !isset($fieldConfig['config']['fieldControl']['editPopup'])
1558
                                ) {
1559
                                    $fieldConfig['config']['fieldControl']['editPopup']['disabled'] = false;
1560
                                    if (isset($wizardConfig['title'])) {
1561
                                        $fieldConfig['config']['fieldControl']['editPopup']['options']['title'] = $wizardConfig['title'];
1562
                                    }
1563
                                    if (isset($wizardConfig['JSopenParams'])) {
1564
                                        $fieldConfig['config']['fieldControl']['editPopup']['options']['windowOpenParameters']
1565
                                            = $wizardConfig['JSopenParams'];
1566
                                    }
1567
                                    unset($fieldConfig['config']['wizards'][$wizardName]);
1568
                                    $this->messages[] = 'The edit wizard in TCA  has been migrated to a \'fieldControl\' = \'editPopup\' element.'
1569
                                        . ' It has been migrated from TCA "'
1570
                                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']" to "'
1571
                                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldControl\']=\'editPopup\'".';
1572
                                }
1573
                            }
1574
                        }
1575
                        if (empty($fieldConfig['config']['wizards'])) {
1576
                            unset($fieldConfig['config']['wizards']);
1577
                        }
1578
                        if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
1579
                            foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
1580
                                if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
1581
                                    if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1582
                                        && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1583
                                    ) {
1584
                                        foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
1585
                                            if (isset($wizard['type'])
1586
                                                && $wizard['type'] === 'popup'
1587
                                                && isset($wizard['module']['name'])
1588
                                                && $wizard['module']['name'] === 'wizard_edit'
1589
                                            ) {
1590
                                                $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['editPopup']['disabled'] = false;
1591
                                                if (isset($wizard['title'])) {
1592
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['editPopup']['options']['title']
1593
                                                        = $wizard['title'];
1594
                                                }
1595
                                                if (isset($wizard['JSopenParams'])) {
1596
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['editPopup']['options']['windowOpenParameters']
1597
                                                        = $wizard['JSopenParams'];
1598
                                                }
1599
                                                unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
1600
                                                $this->messages[] = 'The edit wizard in columnsOverrides using \'type\' = \'popup\' has been migrated to a \'fieldControl\' = \'editPopup\' element.'
1601
                                                    . ' It has been migrated from TCA "'
1602
                                                    . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
1603
                                                    . '[\'wizards\'][\'' . $wizardName . '\']" , to "'
1604
                                                    . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'fieldControl\']=\'editPopup\'".';
1605
                                            }
1606
                                        }
1607
                                        if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
1608
                                            unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
1609
                                        }
1610
                                    }
1611
                                }
1612
                            }
1613
                        }
1614
                    }
1615
                }
1616
            }
1617
        }
1618
1619
        return $tca;
1620
    }
1621
1622
    /**
1623
     * Find select and group fields with enabled add wizard and migrate to "fieldControl"
1624
     *
1625
     * @param array $tca
1626
     * @return array
1627
     */
1628
    protected function migrateAddWizardToFieldControl(array $tca): array
1629
    {
1630
        foreach ($tca as $table => &$tableDefinition) {
1631
            if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1632
                foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1633
                    if ($fieldConfig['config']['type'] === 'group'
1634
                        || $fieldConfig['config']['type'] === 'select'
1635
                    ) {
1636
                        if (isset($fieldConfig['config']['wizards'])
1637
                            && is_array($fieldConfig['config']['wizards'])
1638
                        ) {
1639
                            foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
1640
                                if (isset($wizardConfig['type'])
1641
                                    && $wizardConfig['type'] === 'script'
1642
                                    && isset($wizardConfig['module']['name'])
1643
                                    && $wizardConfig['module']['name'] === 'wizard_add'
1644
                                    && !isset($fieldConfig['config']['fieldControl']['addRecord'])
1645
                                ) {
1646
                                    $fieldConfig['config']['fieldControl']['addRecord']['disabled'] = false;
1647
                                    if (isset($wizardConfig['title'])) {
1648
                                        $fieldConfig['config']['fieldControl']['addRecord']['options']['title'] = $wizardConfig['title'];
1649
                                    }
1650
                                    if (isset($wizardConfig['params']['table'])) {
1651
                                        $fieldConfig['config']['fieldControl']['addRecord']['options']['table']
1652
                                            = $wizardConfig['params']['table'];
1653
                                    }
1654
                                    if (isset($wizardConfig['params']['pid'])) {
1655
                                        $fieldConfig['config']['fieldControl']['addRecord']['options']['pid']
1656
                                            = $wizardConfig['params']['pid'];
1657
                                    }
1658
                                    if (isset($wizardConfig['params']['setValue'])) {
1659
                                        $fieldConfig['config']['fieldControl']['addRecord']['options']['setValue']
1660
                                            = $wizardConfig['params']['setValue'];
1661
                                    }
1662
                                    unset($fieldConfig['config']['wizards'][$wizardName]);
1663
                                    $this->messages[] = 'The add wizard in TCA has been migrated to a \'fieldControl\' = \'addRecord\' element.'
1664
                                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
1665
                                        . ' It has been migrated from TCA "'
1666
                                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldControl\']=\'addRecord\'.';
1667
                                }
1668
                            }
1669
                        }
1670
                        if (empty($fieldConfig['config']['wizards'])) {
1671
                            unset($fieldConfig['config']['wizards']);
1672
                        }
1673
                        if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
1674
                            foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
1675
                                if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
1676
                                    if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1677
                                        && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1678
                                    ) {
1679
                                        foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
1680
                                            if (isset($wizard['type'])
1681
                                                && $wizard['type'] === 'script'
1682
                                                && isset($wizard['module']['name'])
1683
                                                && $wizard['module']['name'] === 'wizard_add'
1684
                                            ) {
1685
                                                $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['addRecord']['disabled'] = false;
1686
                                                if (isset($wizard['title'])) {
1687
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['addRecord']['options']['title']
1688
                                                        = $wizard['title'];
1689
                                                }
1690
                                                if (isset($wizard['params']['table'])) {
1691
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['addRecord']['options']['table']
1692
                                                        = $wizard['params']['table'];
1693
                                                }
1694
                                                if (isset($wizard['params']['pid'])) {
1695
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['addRecord']['options']['pid']
1696
                                                        = $wizard['params']['pid'];
1697
                                                }
1698
                                                if (isset($wizard['params']['setValue'])) {
1699
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['addRecord']['options']['setValue']
1700
                                                        = $wizard['params']['setValue'];
1701
                                                }
1702
                                                unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
1703
                                                $this->messages[] = 'The add wizard in columnsOverrides using \'type\' = \'script\' has been migrated to a \'fieldControl\' = \'addRecord\' element.'
1704
                                                    . ' It has been migrated from TCA "'
1705
                                                    . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
1706
                                                    . '[\'wizards\'][\'' . $wizardName . '\']"  to "'
1707
                                                    . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'fieldControl\'=\'addRecord\'".';
1708
                                            }
1709
                                        }
1710
                                        if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
1711
                                            unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
1712
                                        }
1713
                                    }
1714
                                }
1715
                            }
1716
                        }
1717
                    }
1718
                }
1719
            }
1720
        }
1721
1722
        return $tca;
1723
    }
1724
1725
    /**
1726
     * Find select and group fields with enabled list wizard and migrate to "fieldControl"
1727
     *
1728
     * @param array $tca
1729
     * @return array
1730
     */
1731
    protected function migrateListWizardToFieldControl(array $tca): array
1732
    {
1733
        foreach ($tca as $table => &$tableDefinition) {
1734
            if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1735
                foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1736
                    if ($fieldConfig['config']['type'] === 'group'
1737
                        || $fieldConfig['config']['type'] === 'select'
1738
                    ) {
1739
                        if (isset($fieldConfig['config']['wizards'])
1740
                            && is_array($fieldConfig['config']['wizards'])
1741
                        ) {
1742
                            foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
1743
                                if (isset($wizardConfig['type'])
1744
                                    && $wizardConfig['type'] === 'script'
1745
                                    && isset($wizardConfig['module']['name'])
1746
                                    && $wizardConfig['module']['name'] === 'wizard_list'
1747
                                    && !isset($fieldConfig['config']['fieldControl']['listModule'])
1748
                                ) {
1749
                                    $fieldConfig['config']['fieldControl']['listModule']['disabled'] = false;
1750
                                    if (isset($wizardConfig['title'])) {
1751
                                        $fieldConfig['config']['fieldControl']['listModule']['options']['title'] = $wizardConfig['title'];
1752
                                    }
1753
                                    if (isset($wizardConfig['params']['table'])) {
1754
                                        $fieldConfig['config']['fieldControl']['listModule']['options']['table']
1755
                                            = $wizardConfig['params']['table'];
1756
                                    }
1757
                                    if (isset($wizardConfig['params']['pid'])) {
1758
                                        $fieldConfig['config']['fieldControl']['listModule']['options']['pid']
1759
                                            = $wizardConfig['params']['pid'];
1760
                                    }
1761
                                    unset($fieldConfig['config']['wizards'][$wizardName]);
1762
                                    $this->messages[] = 'The list wizard in TCA has been migrated to a \'fieldControl\' = \'listModule\' element.'
1763
                                        . ' It has been migrated from TCA "'
1764
                                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
1765
                                        . '" to "'
1766
                                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldControl\'=\'listModule\'".';
1767
                                }
1768
                            }
1769
                        }
1770
                        if (empty($fieldConfig['config']['wizards'])) {
1771
                            unset($fieldConfig['config']['wizards']);
1772
                        }
1773
                        if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
1774
                            foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
1775
                                if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
1776
                                    if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1777
                                        && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1778
                                    ) {
1779
                                        foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
1780
                                            if (isset($wizard['type'])
1781
                                                && $wizard['type'] === 'script'
1782
                                                && isset($wizard['module']['name'])
1783
                                                && $wizard['module']['name'] === 'wizard_list'
1784
                                            ) {
1785
                                                $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['listModule']['disabled'] = false;
1786
                                                if (isset($wizard['title'])) {
1787
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['listModule']['options']['title']
1788
                                                        = $wizard['title'];
1789
                                                }
1790
                                                if (isset($wizard['params']['table'])) {
1791
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['listModule']['options']['table']
1792
                                                        = $wizard['params']['table'];
1793
                                                }
1794
                                                if (isset($wizard['params']['pid'])) {
1795
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['listModule']['options']['pid']
1796
                                                        = $wizard['params']['pid'];
1797
                                                }
1798
                                                unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
1799
                                                $this->messages[] = 'The list wizard in columnsOverrides using \'type\' = \'script\' has been migrated to a \'fieldControl\' = \'listModule\' element.'
1800
                                                    . ' It has been migrated from TCA "'
1801
                                                    . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
1802
                                                    . '[\'wizards\'][\'' . $wizardName . '\']" to "'
1803
                                                    . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'fieldControl\'=\'listModule\'".';
1804
                                            }
1805
                                        }
1806
                                        if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
1807
                                            unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
1808
                                        }
1809
                                    }
1810
                                }
1811
                            }
1812
                        }
1813
                    }
1814
                }
1815
            }
1816
        }
1817
1818
        return $tca;
1819
    }
1820
1821
    /**
1822
     * Migrate defaultExtras "nowrap", "enable-tab", "fixed-font". Then drop all
1823
     * remaining "defaultExtras", there shouldn't exist anymore.
1824
     *
1825
     * @param array $tca
1826
     * @return array
1827
     */
1828
    protected function migrateLastPiecesOfDefaultExtras(array $tca): array
1829
    {
1830
        foreach ($tca as $table => &$tableDefinition) {
1831
            if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1832
                foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1833
                    if (isset($fieldConfig['defaultExtras'])) {
1834
                        $defaultExtrasArray = GeneralUtility::trimExplode(':', $fieldConfig['defaultExtras'], true);
1835
                        foreach ($defaultExtrasArray as $defaultExtrasSetting) {
1836
                            if ($defaultExtrasSetting === 'rte_only') {
1837
                                $this->messages[] = 'The defaultExtras setting \'rte_only\' in TCA table '
1838
                                    . $table . '[\'columns\'][\'' . $fieldName . '\'] has been dropped, the setting'
1839
                                    . ' is no longer supported';
1840
                                continue;
1841
                            }
1842
                            if ($defaultExtrasSetting === 'nowrap') {
1843
                                $fieldConfig['config']['wrap'] = 'off';
1844
                                $this->messages[] = 'The defaultExtras setting \'nowrap\' in TCA table '
1845
                                    . $table . '[\'columns\'][\'' . $fieldName . '\'] has been migrated to TCA table '
1846
                                    . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wrap\'] = \'off\'';
1847
                            } elseif ($defaultExtrasSetting === 'enable-tab') {
1848
                                $fieldConfig['config']['enableTabulator'] = true;
1849
                                $this->messages[] = 'The defaultExtras setting \'enable-tab\' in TCA table '
1850
                                    . $table . '[\'columns\'][\'' . $fieldName . '\'] has been migrated to TCA table '
1851
                                    . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'enableTabulator\'] = true';
1852
                            } elseif ($defaultExtrasSetting === 'fixed-font') {
1853
                                $fieldConfig['config']['fixedFont'] = true;
1854
                                $this->messages[] = 'The defaultExtras setting \'fixed-font\' in TCA table '
1855
                                    . $table . '[\'columns\'][\'' . $fieldName . '\'] has been migrated to TCA table '
1856
                                    . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fixedFont\'] = true';
1857
                            } else {
1858
                                $this->messages[] = 'The defaultExtras setting \'' . $defaultExtrasSetting . '\' in TCA table '
1859
                                    . $table . '[\'columns\'][\'' . $fieldName . '\'] is unknown and has been dropped.';
1860
                            }
1861
                        }
1862
                        unset($fieldConfig['defaultExtras']);
1863
                    }
1864
                }
1865
            }
1866
            if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
1867
                foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
1868
                    if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
1869
                        foreach ($typeArray['columnsOverrides'] as $fieldName => &$overrideConfig) {
1870
                            if (!isset($overrideConfig['defaultExtras'])) {
1871
                                continue;
1872
                            }
1873
                            $defaultExtrasArray = GeneralUtility::trimExplode(':', $overrideConfig['defaultExtras'], true);
1874
                            foreach ($defaultExtrasArray as $defaultExtrasSetting) {
1875
                                if ($defaultExtrasSetting === 'rte_only') {
1876
                                    $this->messages[] = 'The defaultExtras setting \'rte_only\' in TCA table '
1877
                                        . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\']'
1878
                                        . ' has been dropped, the setting is no longer supported';
1879
                                    continue;
1880
                                }
1881
                                if ($defaultExtrasSetting === 'nowrap') {
1882
                                    $overrideConfig['config']['wrap'] = 'off';
1883
                                    $this->messages[] = 'The defaultExtras setting \'nowrap\' in TCA table '
1884
                                        . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\']'
1885
                                        . ' has been migrated to TCA table '
1886
                                        . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\'][\'config\'][\'wrap\'] = \'off\'';
1887
                                } elseif ($defaultExtrasSetting === 'enable-tab') {
1888
                                    $overrideConfig['config']['enableTabulator'] = true;
1889
                                    $this->messages[] = 'The defaultExtras setting \'enable-tab\' in TCA table '
1890
                                        . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\']'
1891
                                        . ' has been migrated to TCA table '
1892
                                        . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\'][\'config\'][\'enableTabulator\'] = true';
1893
                                } elseif ($defaultExtrasSetting === 'fixed-font') {
1894
                                    $overrideConfig['config']['fixedFont'] = true;
1895
                                    $this->messages[] = 'The defaultExtras setting \'fixed-font\' in TCA table '
1896
                                        . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\']'
1897
                                        . ' has been migrated to TCA table '
1898
                                        . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\'][\'config\'][\'fixedFont\'] = true';
1899
                                } else {
1900
                                    $this->messages[] = 'The defaultExtras setting \'' . $defaultExtrasSetting . '\' in TCA table '
1901
                                        . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'' . $fieldName . '\']'
1902
                                        . ' is unknown and has been dropped.';
1903
                                }
1904
                            }
1905
                            unset($overrideConfig['defaultExtras']);
1906
                        }
1907
                    }
1908
                }
1909
            }
1910
        }
1911
1912
        return $tca;
1913
    }
1914
1915
    /**
1916
     * Migrate wizard_table script to renderType="textTable" with options in fieldControl
1917
     *
1918
     * @param array $tca
1919
     * @return array
1920
     */
1921
    protected function migrateTableWizardToRenderType(array $tca): array
1922
    {
1923
        foreach ($tca as $table => &$tableDefinition) {
1924
            if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
1925
                foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
1926
                    if ($fieldConfig['config']['type'] === 'text') {
1927
                        if (isset($fieldConfig['config']['wizards'])
1928
                            && is_array($fieldConfig['config']['wizards'])
1929
                        ) {
1930
                            foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
1931
                                if (isset($wizardConfig['type'])
1932
                                    && $wizardConfig['type'] === 'script'
1933
                                    && isset($wizardConfig['module']['name'])
1934
                                    && $wizardConfig['module']['name'] === 'wizard_table'
1935
                                    && !isset($fieldConfig['config']['fieldControl']['tableWizard'])
1936
                                    && !isset($fieldConfig['config']['renderType'])
1937
                                ) {
1938
                                    $fieldConfig['config']['renderType'] = 'textTable';
1939
                                    if (isset($wizardConfig['title'])) {
1940
                                        $fieldConfig['config']['fieldControl']['tableWizard']['options']['title'] = $wizardConfig['title'];
1941
                                    }
1942
                                    if (isset($wizardConfig['params']['xmlOutput']) && (int)$wizardConfig['params']['xmlOutput'] !== 0) {
1943
                                        $fieldConfig['config']['fieldControl']['tableWizard']['options']['xmlOutput']
1944
                                            = (int)$wizardConfig['params']['xmlOutput'];
1945
                                    }
1946
                                    if (isset($wizardConfig['params']['numNewRows'])) {
1947
                                        $fieldConfig['config']['fieldControl']['tableWizard']['options']['numNewRows']
1948
                                            = $wizardConfig['params']['numNewRows'];
1949
                                    }
1950
                                    unset($fieldConfig['config']['wizards'][$wizardName]);
1951
                                    $this->messages[] = 'The table wizard in TCA has been migrated to a \'renderType\' = \'textTable\'.'
1952
                                        . ' It has been migrated from TCA "'
1953
                                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
1954
                                        . '" to "'
1955
                                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'renderType\'] = \'textTable\'".';
1956
                                }
1957
                            }
1958
                        }
1959
                        if (empty($fieldConfig['config']['wizards'])) {
1960
                            unset($fieldConfig['config']['wizards']);
1961
                        }
1962
                        if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
1963
                            foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
1964
                                if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
1965
                                    if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1966
                                        && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
1967
                                    ) {
1968
                                        foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
1969
                                            if (isset($wizard['type'])
1970
                                                && $wizard['type'] === 'script'
1971
                                                && isset($wizard['module']['name'])
1972
                                                && $wizard['module']['name'] === 'wizard_table'
1973
                                                && !isset($typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['tableWizard'])
1974
                                                && !isset($typeArray['columnsOverrides'][$fieldName]['config']['renderType'])
1975
                                            ) {
1976
                                                $typeArray['columnsOverrides'][$fieldName]['config']['renderType'] = 'textTable';
1977
                                                if (isset($wizard['title'])) {
1978
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['tableWizard']['options']['title']
1979
                                                        = $wizard['title'];
1980
                                                }
1981
                                                if (isset($wizard['params']['xmlOutput']) && (int)$wizard['params']['xmlOutput'] !== 0) {
1982
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['tableWizard']['options']['xmlOutput']
1983
                                                        = (int)$wizard['params']['xmlOutput'];
1984
                                                }
1985
                                                if (isset($wizard['params']['numNewRows'])) {
1986
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['tableWizard']['options']['numNewRows']
1987
                                                        = $wizard['params']['numNewRows'];
1988
                                                }
1989
                                                unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
1990
                                                $this->messages[] = 'The table wizard in columnsOverrides using \'type\' = \'script\' has been migrated to a \'renderType\' = \'textTable\'.'
1991
                                                    . ' It has been migrated from TCA "'
1992
                                                    . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
1993
                                                    . '[\'wizards\'][\'' . $wizardName . '\']"  to "'
1994
                                                    . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'renderType\'] = \'textTable\'".';
1995
                                            }
1996
                                        }
1997
                                        if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
1998
                                            unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
1999
                                        }
2000
                                    }
2001
                                }
2002
                            }
2003
                        }
2004
                    }
2005
                }
2006
            }
2007
        }
2008
2009
        return $tca;
2010
    }
2011
2012
    /**
2013
     * Migrate "wizard_rte" wizards to rtehtmlarea fieldControl
2014
     *
2015
     * @param array $tca
2016
     * @return array
2017
     */
2018
    protected function migrateFullScreenRichtextToFieldControl(array $tca): array
2019
    {
2020
        foreach ($tca as $table => &$tableDefinition) {
2021
            if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
2022
                foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
2023
                    if ($fieldConfig['config']['type'] === 'text') {
2024
                        if (isset($fieldConfig['config']['wizards'])
2025
                            && is_array($fieldConfig['config']['wizards'])
2026
                        ) {
2027
                            foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
2028
                                if (isset($wizardConfig['type'])
2029
                                    && $wizardConfig['type'] === 'script'
2030
                                    && isset($wizardConfig['module']['name'])
2031
                                    && $wizardConfig['module']['name'] === 'wizard_rte'
2032
                                    && !isset($fieldConfig['config']['fieldControl']['fullScreenRichtext'])
2033
                                    && isset($fieldConfig['config']['enableRichtext'])
2034
                                    && (bool)$fieldConfig['config']['enableRichtext'] === true
2035
                                ) {
2036
                                    // Field is configured for richtext, so enable the full screen wizard
2037
                                    $fieldConfig['config']['fieldControl']['fullScreenRichtext']['disabled'] = false;
2038
                                    if (isset($wizardConfig['title'])) {
2039
                                        $fieldConfig['config']['fieldControl']['fullScreenRichtext']['options']['title'] = $wizardConfig['title'];
2040
                                    }
2041
                                    unset($fieldConfig['config']['wizards'][$wizardName]);
2042
                                    $this->messages[] = 'The RTE fullscreen wizard in TCA has been migrated to a \'fieldControl\' = \'fullScreenRichtext\'.'
2043
                                        . ' It has been migrated from TCA "'
2044
                                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
2045
                                        . '" to "'
2046
                                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldControl\']=\'fullScreenRichtext\'".';
2047
                                } elseif (isset($wizardConfig['type'])
2048
                                    && $wizardConfig['type'] === 'script'
2049
                                    && isset($wizardConfig['module']['name'])
2050
                                    && $wizardConfig['module']['name'] === 'wizard_rte'
2051
                                    && !isset($fieldConfig['config']['fieldControl']['fullScreenRichtext'])
2052
                                    && (
2053
                                        !isset($fieldConfig['config']['enableRichtext'])
2054
                                        || isset($fieldConfig['config']['enableRichtext']) && (bool)$fieldConfig['config']['enableRichtext'] === false
2055
                                    )
2056
                                ) {
2057
                                    // Wizard is given, but field is not configured for richtext
2058
                                    // Find types that enableRichtext and enable full screen for those types
2059
                                    if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
2060
                                        foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
2061
                                            if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
2062
                                                if (isset($typeArray['columnsOverrides'][$fieldName]['config']['enableRichtext'])
2063
                                                    && (bool)$typeArray['columnsOverrides'][$fieldName]['config']['enableRichtext'] === true
2064
                                                ) {
2065
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['fullScreenRichtext']['disabled'] = false;
2066
                                                    if (isset($wizardConfig['title'])) {
2067
                                                        $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['fullScreenRichtext']['options']['title']
2068
                                                            = $wizardConfig['title'];
2069
                                                    }
2070
                                                    $this->messages[] = 'The RTE fullscreen wizard in TCA has been migrated to a \'fieldControl\' = \'fullScreenRichtext\'.'
2071
                                                        . ' It has been migrated from TCA "'
2072
                                                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
2073
                                                        . '" to "'
2074
                                                        . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'fieldControl\']=\'fullScreenRichtext\'';
2075
                                                }
2076
                                            }
2077
                                        }
2078
                                    }
2079
                                    unset($fieldConfig['config']['wizards'][$wizardName]);
2080
                                }
2081
                            }
2082
                        }
2083
                        if (empty($fieldConfig['config']['wizards'])) {
2084
                            unset($fieldConfig['config']['wizards']);
2085
                        }
2086
                        if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
2087
                            foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
2088
                                if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
2089
                                    if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
2090
                                        && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
2091
                                    ) {
2092
                                        foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
2093
                                            if (isset($wizard['type'])
2094
                                                && $wizard['type'] === 'script'
2095
                                                && isset($wizard['module']['name'])
2096
                                                && $wizard['module']['name'] === 'wizard_rte'
2097
                                                && !isset($typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['fullScreenRichtext'])
2098
                                            ) {
2099
                                                $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['fullScreenRichtext']['disabled'] = false;
2100
                                                if (isset($wizard['title'])) {
2101
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['fieldControl']['fullScreenRichtext']['options']['title']
2102
                                                        = $wizard['title'];
2103
                                                }
2104
                                                unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
2105
                                                $this->messages[] = 'The RTE fullscreen wizard in columnsOverrides using \'type\' = \'script\' has been migrated to a \'fieldControl\' = \'fullScreenRichtext\'.'
2106
                                                    . ' It has been migrated from TCA "'
2107
                                                    . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
2108
                                                    . '[\'wizards\'][\'' . $wizardName . '\']" to "'
2109
                                                    . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'fieldControl\']=\'fullScreenRichtext\'".';
2110
                                            }
2111
                                        }
2112
                                        if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
2113
                                            unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
2114
                                        }
2115
                                    }
2116
                                }
2117
                            }
2118
                        }
2119
                    }
2120
                }
2121
            }
2122
        }
2123
2124
        return $tca;
2125
    }
2126
2127
    /**
2128
     * Migrate the "suggest" wizard in type=group to "hideSuggest" and "suggestOptions"
2129
     *
2130
     * @param array $tca Given TCA
2131
     * @return array Modified TCA
2132
     */
2133
    protected function migrateSuggestWizardTypeGroup(array $tca): array
2134
    {
2135
        foreach ($tca as $table => &$tableDefinition) {
2136
            if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
2137
                foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
2138
                    if ($fieldConfig['config']['type'] === 'group'
2139
                        && isset($fieldConfig['config']['internal_type'])
2140
                        && $fieldConfig['config']['internal_type'] === 'db'
2141
                    ) {
2142
                        if (isset($fieldConfig['config']['hideSuggest'])) {
2143
                            continue;
2144
                        }
2145
                        if (isset($fieldConfig['config']['wizards']) && is_array($fieldConfig['config']['wizards'])) {
2146
                            foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
2147
                                if (isset($wizardConfig['type']) && $wizardConfig['type'] === 'suggest') {
2148
                                    unset($wizardConfig['type']);
2149
                                    if (!empty($wizardConfig)) {
2150
                                        $fieldConfig['config']['suggestOptions'] = $wizardConfig;
2151
                                        $this->messages[] = 'The suggest wizard options in TCA '
2152
                                            . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
2153
                                            . ' have been migrated to '
2154
                                            . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'suggestOptions\'].';
2155
                                    } else {
2156
                                        $this->messages[] = 'The suggest wizard in TCA '
2157
                                            . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'wizards\'][\'' . $wizardName . '\']'
2158
                                            . ' is enabled by default and has been removed.';
2159
                                    }
2160
                                    unset($fieldConfig['config']['wizards'][$wizardName]);
2161
                                }
2162
                            }
2163
                        }
2164
                        if (empty($fieldConfig['config']['wizards'])) {
2165
                            unset($fieldConfig['config']['wizards']);
2166
                        }
2167
                        if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
2168
                            foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
2169
                                if (isset($typeArray['columnsOverrides']) && is_array($typeArray['columnsOverrides'])) {
2170
                                    if (isset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
2171
                                        && is_array($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])
2172
                                    ) {
2173
                                        foreach ($typeArray['columnsOverrides'][$fieldName]['config']['wizards'] as $wizardName => $wizard) {
2174
                                            if (isset($wizard['type']) && $wizard['type'] === 'suggest'
2175
                                            ) {
2176
                                                unset($wizard['type']);
2177
                                                $fieldConfig['config']['hideSuggest'] = true;
2178
                                                $typeArray['columnsOverrides'][$fieldName]['config']['hideSuggest'] = false;
2179
                                                if (!empty($wizard)) {
2180
                                                    $typeArray['columnsOverrides'][$fieldName]['config']['suggestOptions'] = $wizard;
2181
                                                    $this->messages[] = 'The suggest wizard options in columnsOverrides have been migrated'
2182
                                                        . ' from TCA ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
2183
                                                        . '[\'wizards\'][\'' . $wizardName . '\'] to \'suggestOptions\' in '
2184
                                                        . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']';
2185
                                                } else {
2186
                                                    $this->messages[] = 'The suggest wizard in columnsOverrides has been migrated'
2187
                                                        . ' from TCA ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\']'
2188
                                                        . '[\'wizards\'][\'' . $wizardName . '\'] to \'hideSuggest\' => false in '
2189
                                                        . $table . '[\'types\'][\'' . $typeName . '\'][\'columnsOverrides\'][\'config\'][\'hideSuggest\']';
2190
                                                }
2191
                                                unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards'][$wizardName]);
2192
                                            }
2193
                                        }
2194
                                        if (empty($typeArray['columnsOverrides'][$fieldName]['config']['wizards'])) {
2195
                                            unset($typeArray['columnsOverrides'][$fieldName]['config']['wizards']);
2196
                                        }
2197
                                    }
2198
                                }
2199
                            }
2200
                        }
2201
                    }
2202
                }
2203
            }
2204
        }
2205
2206
        return $tca;
2207
    }
2208
2209
    /**
2210
     * Migrate some detail options of type=group config
2211
     *
2212
     * @param array $tca Given TCA
2213
     * @return array Modified TCA
2214
     */
2215
    protected function migrateOptionsOfTypeGroup(array $tca): array
2216
    {
2217
        foreach ($tca as $table => &$tableDefinition) {
2218
            if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
2219
                foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
2220
                    if ($fieldConfig['config']['type'] === 'group') {
2221
                        if (isset($fieldConfig['config']['selectedListStyle'])) {
2222
                            unset($fieldConfig['config']['selectedListStyle']);
2223
                            $this->messages[] = 'The \'type\' = \'group\' option \'selectedListStyle\' is obsolete and has been dropped'
2224
                                . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']';
2225
                        }
2226
                        if (isset($fieldConfig['config']['show_thumbs'])) {
2227
                            if ((bool)$fieldConfig['config']['show_thumbs'] === false && $fieldConfig['config']['internal_type'] === 'db') {
2228
                                $fieldConfig['config']['fieldWizard']['recordsOverview']['disabled'] = true;
2229
                                $this->messages[] = 'The \'type\' = \'group\' option \'show_thumbs\' = false is obsolete'
2230
                                    . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
2231
                                    . ' and has been migrated to'
2232
                                    . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldWizard\'][\'recordsOverview\'][\'disabled\'] = true';
2233
                            } elseif ((bool)$fieldConfig['config']['show_thumbs'] === false && $fieldConfig['config']['internal_type'] === 'file') {
2234
                                $fieldConfig['config']['fieldWizard']['fileThumbnails']['disabled'] = true;
2235
                                $this->messages[] = 'The \'type\' = \'group\' option \'show_thumbs\' = false is obsolete'
2236
                                    . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
2237
                                    . ' and has been migrated to'
2238
                                    . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldWizard\'][\'fileThumbnails\'][\'disabled\'] = true';
2239
                            } else {
2240
                                $this->messages[] = 'The \'type\' = \'group\' option \'show_thumbs\' is obsolete and has been dropped'
2241
                                    . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']';
2242
                            }
2243
                            unset($fieldConfig['config']['show_thumbs']);
2244
                        }
2245
                        if (isset($fieldConfig['config']['disable_controls']) && is_string($fieldConfig['config']['disable_controls'])) {
2246
                            $controls = GeneralUtility::trimExplode(',', $fieldConfig['config']['disable_controls'], true);
2247
                            foreach ($controls as $control) {
2248
                                if ($control === 'browser') {
2249
                                    $fieldConfig['config']['fieldControl']['elementBrowser']['disabled'] = true;
2250
                                    $this->messages[] = 'The \'type\' = \'group\' option \'disable_controls\' = \'browser\''
2251
                                       . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
2252
                                       . ' and has been migrated to'
2253
                                       . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldControl\'][\'elementBrowser\'][\'disabled\'] = true';
2254
                                } elseif ($control === 'delete') {
2255
                                    $this->messages[] = 'The \'type\' = \'group\' option \'disable_controls\' = \'delete\''
2256
                                       . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
2257
                                       . ' and has been migrated to'
2258
                                       . $table . '[\'columns\'][\' . $fieldName . \'][\'config\'][\'hideDeleteIcon\'] = true';
2259
                                    $fieldConfig['config']['hideDeleteIcon'] = true;
2260
                                } elseif ($control === 'allowedTables') {
2261
                                    $fieldConfig['config']['fieldWizard']['tableList']['disabled'] = true;
2262
                                    $this->messages[] = 'The \'type\' = \'group\' option \'disable_controls\' = \'allowedTables\''
2263
                                       . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
2264
                                       . ' and has been migrated to'
2265
                                       . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldWizard\'][\'tableList\'][\'disabled\'] = true';
2266
                                } elseif ($control === 'upload') {
2267
                                    $fieldConfig['config']['fieldWizard']['fileUpload']['disabled'] = true;
2268
                                    $this->messages[] = 'The \'type\' = \'group\' option \'disable_controls\' = \'upload\''
2269
                                       . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
2270
                                       . ' and has been migrated to'
2271
                                       . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'fieldWizard\'][\'fileUpload\'][\'disabled\'] = true';
2272
                                }
2273
                            }
2274
                            unset($fieldConfig['config']['disable_controls']);
2275
                        }
2276
                    }
2277
                }
2278
            }
2279
        }
2280
2281
        return $tca;
2282
    }
2283
2284
    /**
2285
     * Migrate "showIconTable" to a field wizard, drop selicon_cols
2286
     *
2287
     * @param array $tca Given TCA
2288
     * @return array Modified TCA
2289
     */
2290
    protected function migrateSelectShowIconTable(array $tca): array
2291
    {
2292
        foreach ($tca as $table => &$tableDefinition) {
2293
            if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
2294
                foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
2295
                    if ($fieldConfig['config']['type'] === 'select'
2296
                        && isset($fieldConfig['config']['renderType'])
2297
                        && $fieldConfig['config']['renderType'] === 'selectSingle'
2298
                    ) {
2299
                        if (isset($fieldConfig['config']['showIconTable'])) {
2300
                            if ((bool)$fieldConfig['config']['showIconTable'] === true) {
2301
                                $fieldConfig['config']['fieldWizard']['selectIcons']['disabled'] = false;
2302
                                $this->messages[] = 'The \'type\' = \'select\' option \'showIconTable\' = true is obsolete'
2303
                                    . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
2304
                                    . ' and has been migrated to'
2305
                                    . ' [\'config\'][\'fieldWizard\'][\'selectIcons\'][\'disabled\'] = false';
2306
                            } else {
2307
                                $this->messages[] = 'The \'type\' = \'group\' option \'showIconTable\' = false is obsolete'
2308
                                    . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
2309
                                    . ' and has been removed.';
2310
                            }
2311
                            unset($fieldConfig['config']['showIconTable']);
2312
                        }
2313
                        if (isset($fieldConfig['config']['selicon_cols'])) {
2314
                            unset($fieldConfig['config']['selicon_cols']);
2315
                            $this->messages[] = 'The \'type\' = \'group\' option \'selicon_cols\' = false is obsolete'
2316
                                . ' from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
2317
                                . ' and has been removed.';
2318
                        }
2319
                    }
2320
                }
2321
            }
2322
        }
2323
2324
        return $tca;
2325
    }
2326
2327
    /**
2328
     * Migrate imageManipulation "ratio" config to new "cropVariant" config
2329
     *
2330
     * @param array $tca
2331
     * @return array
2332
     */
2333
    protected function migrateImageManipulationConfig(array $tca): array
2334
    {
2335
        foreach ($tca as $table => &$tableDefinition) {
2336
            if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
2337
                foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
2338
                    if ($fieldConfig['config']['type'] === 'imageManipulation') {
2339
                        if (isset($fieldConfig['config']['enableZoom'])) {
2340
                            unset($fieldConfig['config']['enableZoom']);
2341
                            $this->messages[] = sprintf(
2342
                                'The config option "enableZoom" has been removed from TCA type "imageManipulation" in table "%s" and field "%s"',
2343
                                $table,
2344
                                $fieldName
2345
                            );
2346
                        }
2347
                        if (isset($fieldConfig['config']['ratios'])) {
2348
                            $legacyRatios = $fieldConfig['config']['ratios'];
2349
                            unset($fieldConfig['config']['ratios']);
2350
                            if (isset($fieldConfig['config']['cropVariants'])) {
2351
                                $this->messages[] = sprintf(
2352
                                    'The config option "ratios" has been deprecated and cannot be used together with the option "cropVariants" in table "%s" and field "%s"',
2353
                                    $table,
2354
                                    $fieldName
2355
                                );
2356
                                continue;
2357
                            }
2358
                            $fieldConfig['config']['cropVariants']['default'] = [
2359
                                'title' => 'LLL:EXT:lang/Resources/Private/Language/locallang_wizards.xlf:imwizard.crop_variant.default',
2360
                                'allowedAspectRatios' => [],
2361
                                'cropArea' => [
2362
                                    'x' => 0.0,
2363
                                    'y' => 0.0,
2364
                                    'width' => 1.0,
2365
                                    'height' => 1.0,
2366
                                ],
2367
                            ];
2368
                            foreach ($legacyRatios as $ratio => $ratioLabel) {
2369
                                $ratio = (float)$ratio;
2370
                                $ratioId = number_format($ratio, 2);
2371
                                $fieldConfig['config']['cropVariants']['default']['allowedAspectRatios'][$ratioId] = [
2372
                                    'title' => $ratioLabel,
2373
                                    'value' => $ratio,
2374
                                ];
2375
                            }
2376
                            $this->messages[] = sprintf(
2377
                                'Migrated config option "ratios" of type "imageManipulation" to option "cropVariants" in table "%s" and field "%s"',
2378
                                $table,
2379
                                $fieldName
2380
                            );
2381
                        }
2382
                    }
2383
                }
2384
            }
2385
        }
2386
2387
        return $tca;
2388
    }
2389
2390
    /**
2391
     * Migrate 'max' for renderType='inputDateTime'
2392
     *
2393
     * @param array $tca
2394
     * @return array
2395
     */
2396
    protected function migrateinputDateTimeMax(array $tca): array
2397
    {
2398
        foreach ($tca as $table => &$tableDefinition) {
2399
            if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
2400
                foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
2401
                    if (isset($fieldConfig['config']['renderType'])) {
2402
                        if ($fieldConfig['config']['renderType'] === 'inputDateTime') {
2403
                            if (isset($fieldConfig['config']['max'])) {
2404
                                unset($fieldConfig['config']['max']);
2405
                                $this->messages[] = 'The config option \'max\' has been removed from the TCA for renderType=\'inputDateTime\' in ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'max\']';
2406
                            }
2407
                        }
2408
                    }
2409
                }
2410
            }
2411
        }
2412
2413
        return $tca;
2414
    }
2415
2416
    /**
2417
     * Migrate type='inline' properties 'foreign_types', 'foreign_selector_fieldTcaOverride'
2418
     * and 'foreign_record_defaults' to 'overrideChildTca'
2419
     *
2420
     * @param array $tca
2421
     * @return array
2422
     */
2423
    protected function migrateInlineOverrideChildTca(array $tca): array
2424
    {
2425
        foreach ($tca as $table => &$tableDefinition) {
2426
            if (isset($tableDefinition['types']) && is_array($tableDefinition['types'])) {
2427
                foreach ($tableDefinition['types'] as $typeName => &$typeConfig) {
2428
                    if (!isset($typeConfig['columnsOverrides']) || !is_array($typeConfig['columnsOverrides'])) {
2429
                        continue;
2430
                    }
2431
                    foreach ($typeConfig['columnsOverrides'] as $fieldName => &$fieldConfig) {
2432
                        if (isset($fieldConfig['config']['overrideChildTca'])
2433
                            || (isset($fieldConfig['config']['type']) && $fieldConfig['config']['type'] !== 'inline')
2434
                            || (!isset($fieldConfig['config']['type']) && $tca[$table]['columns'][$fieldName]['config']['type'] !== 'inline')
2435
                        ) {
2436
                            // The new config is either set intentionally for compatibility
2437
                            // or accidentally. In any case we keep the new config and skip the migration.
2438
                            continue;
2439
                        }
2440
                        if (isset($fieldConfig['config']['foreign_types']) && is_array($fieldConfig['config']['foreign_types'])) {
2441
                            $fieldConfig['config']['overrideChildTca']['types'] = $fieldConfig['config']['foreign_types'];
2442
                            unset($fieldConfig['config']['foreign_types']);
2443
                            $this->messages[] = 'The \'foreign_types\' property from TCA ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnOverrides\'][\'' . $fieldName . '\'][\'config\']  and has been migrated to ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnOverrides\'][\'' . $fieldName . '\'][\'config\'][\'overrideChildTca\'][\'types\']';
2444
                        }
2445
                        if (isset($fieldConfig['config']['foreign_selector_fieldTcaOverride']) && is_array($fieldConfig['config']['foreign_selector_fieldTcaOverride'])) {
2446
                            $foreignSelectorFieldName = '';
2447
                            if (isset($fieldConfig['config']['foreign_selector']) && is_string($fieldConfig['config']['foreign_selector'])) {
2448
                                $foreignSelectorFieldName = $fieldConfig['config']['foreign_selector'];
2449
                            } elseif (isset($tca[$table]['columns'][$fieldName]['config']['foreign_selector']) && is_string($tca[$table]['columns'][$fieldName]['config']['foreign_selector'])) {
2450
                                $foreignSelectorFieldName = $tca[$table]['columns'][$fieldName]['config']['foreign_selector'];
2451
                            }
2452
                            if ($foreignSelectorFieldName) {
2453
                                $fieldConfig['config']['overrideChildTca']['columns'][$foreignSelectorFieldName] = $fieldConfig['config']['foreign_selector_fieldTcaOverride'];
2454
                                unset($fieldConfig['config']['foreign_selector_fieldTcaOverride']);
2455
                                $this->messages[] = 'The \'foreign_selector_fieldTcaOverride\' property from TCA ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnOverrides\'][\'' . $fieldName . '\'][\'config\']  and has been migrated to ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnOverrides\'][\'' . $fieldName . '\'][\'config\'][\'overrideChildTca\'][\'columns\'][\'' . $foreignSelectorFieldName . '\']';
2456
                            }
2457
                        }
2458
                        if (isset($fieldConfig['config']['foreign_record_defaults']) && is_array($fieldConfig['config']['foreign_record_defaults'])) {
2459
                            foreach ($fieldConfig['config']['foreign_record_defaults'] as $childFieldName => $defaultValue) {
2460
                                $fieldConfig['config']['overrideChildTca']['columns'][$childFieldName]['config']['default'] = $defaultValue;
2461
                                $this->messages[] = 'The \'foreign_record_defaults\' property from TCA ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnOverrides\'][\'' . $fieldName . '\'][\'config\'][\'' . $childFieldName . '\']  and has been migrated to ' . $table . '[\'types\'][\'' . $typeName . '\'][\'columnOverrides\'][\'' . $fieldName . '\'][\'config\'][\'overrideChildTca\'][\'columns\'][\'' . $childFieldName . '\'][\'config\'][\'default\']';
2462
                            }
2463
                            unset($fieldConfig['config']['foreign_record_defaults']);
2464
                        }
2465
                    }
2466
                    unset($fieldConfig);
2467
                }
2468
                unset($typeConfig);
2469
            }
2470
            if (isset($tableDefinition['columns']) && is_array($tableDefinition['columns'])) {
2471
                foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
2472
                    if ($fieldConfig['config']['type'] !== 'inline') {
2473
                        continue;
2474
                    }
2475
                    if (isset($fieldConfig['config']['foreign_types']) && is_array($fieldConfig['config']['foreign_types'])) {
2476
                        if (isset($fieldConfig['config']['overrideChildTca']['types'])
2477
                            && is_array($fieldConfig['config']['overrideChildTca']['types'])
2478
                        ) {
2479
                            $fieldConfig['config']['overrideChildTca']['types'] = array_replace_recursive(
2480
                                $fieldConfig['config']['foreign_types'],
2481
                                $fieldConfig['config']['overrideChildTca']['types']
2482
                            );
2483
                        } else {
2484
                            $fieldConfig['config']['overrideChildTca']['types'] = $fieldConfig['config']['foreign_types'];
2485
                        }
2486
                        unset($fieldConfig['config']['foreign_types']);
2487
                        $this->messages[] = 'The \'foreign_types\' property from TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']  and has been migrated to ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'overrideChildTca\'][\'types\']';
2488
                    }
2489
                    if (isset($fieldConfig['config']['foreign_selector'], $fieldConfig['config']['foreign_selector_fieldTcaOverride']) && is_string($fieldConfig['config']['foreign_selector']) && is_array($fieldConfig['config']['foreign_selector_fieldTcaOverride'])) {
2490
                        $foreignSelectorFieldName = $fieldConfig['config']['foreign_selector'];
2491
                        if (isset($fieldConfig['config']['overrideChildTca']['columns'][$foreignSelectorFieldName])
2492
                            && is_array($fieldConfig['config']['overrideChildTca']['columns'][$foreignSelectorFieldName])
2493
                        ) {
2494
                            $fieldConfig['config']['overrideChildTca']['columns'][$foreignSelectorFieldName] = array_replace_recursive(
2495
                                $fieldConfig['config']['foreign_selector_fieldTcaOverride'],
2496
                                $fieldConfig['config']['overrideChildTca']['columns'][$foreignSelectorFieldName]
2497
                            );
2498
                        } else {
2499
                            $fieldConfig['config']['overrideChildTca']['columns'][$foreignSelectorFieldName] = $fieldConfig['config']['foreign_selector_fieldTcaOverride'];
2500
                        }
2501
                        unset($fieldConfig['config']['foreign_selector_fieldTcaOverride']);
2502
                        $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 . '\']';
2503
                    }
2504
                    if (isset($fieldConfig['config']['foreign_record_defaults']) && is_array($fieldConfig['config']['foreign_record_defaults'])) {
2505
                        foreach ($fieldConfig['config']['foreign_record_defaults'] as $childFieldName => $defaultValue) {
2506
                            if (!isset($fieldConfig['config']['overrideChildTca']['columns'][$childFieldName]['config']['default'])) {
2507
                                $fieldConfig['config']['overrideChildTca']['columns'][$childFieldName]['config']['default'] = $defaultValue;
2508
                                $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\']';
2509
                            }
2510
                        }
2511
                        unset($fieldConfig['config']['foreign_record_defaults']);
2512
                    }
2513
                }
2514
                unset($fieldConfig);
2515
            }
2516
        }
2517
2518
        return $tca;
2519
    }
2520
2521
    /**
2522
     * Option $TCA[$table]['columns'][$columnName]['config']['behaviour']['localizeChildrenAtParentLocalization']
2523
     * is always on, so this option can be removed.
2524
     *
2525
     * @param array $tca
2526
     * @return array the modified TCA structure
2527
     */
2528
    protected function migrateLocalizeChildrenAtParentLocalization(array $tca): array
2529
    {
2530
        foreach ($tca as $table => &$tableDefinition) {
2531
            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
2532
                continue;
2533
            }
2534
            foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
2535
                if (($fieldConfig['config']['type'] ?? null) !== 'inline') {
2536
                    continue;
2537
                }
2538
2539
                $localizeChildrenAtParentLocalization = ($fieldConfig['config']['behaviour']['localizeChildrenAtParentLocalization'] ?? null);
2540
                if ($localizeChildrenAtParentLocalization === null) {
2541
                    continue;
2542
                }
2543
2544
                if ($localizeChildrenAtParentLocalization) {
2545
                    $this->messages[] = 'The TCA setting \'localizeChildrenAtParentLocalization\' is deprecated '
2546
                        . ' and should be removed from TCA for ' . $table . '[\'columns\']'
2547
                        . '[\'' . $fieldName . '\'][\'config\'][\'behaviour\'][\'localizeChildrenAtParentLocalization\']';
2548
                } else {
2549
                    $this->messages[] = 'The TCA setting \'localizeChildrenAtParentLocalization\' is deprecated '
2550
                        . ', as this functionality is always enabled. The option should be removed from TCA for '
2551
                        . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'behaviour\']'
2552
                        . '[\'localizeChildrenAtParentLocalization\']';
2553
                }
2554
                unset($fieldConfig['config']['behaviour']['localizeChildrenAtParentLocalization']);
2555
            }
2556
        }
2557
        return $tca;
2558
    }
2559
2560
    /**
2561
     * Removes $TCA['pages_language_overlay'] if defined.
2562
     *
2563
     * @param array $tca
2564
     * @return array the modified TCA structure
2565
     */
2566
    protected function migratePagesLanguageOverlayRemoval(array $tca)
2567
    {
2568
        if (isset($tca['pages_language_overlay'])) {
2569
            $this->messages[] = 'The TCA table \'pages_language_overlay\' is'
2570
                . ' not used anymore and has been removed automatically in'
2571
                . ' order to avoid negative side-effects.';
2572
            unset($tca['pages_language_overlay']);
2573
        }
2574
        return $tca;
2575
    }
2576
}
2577