[!!!][TASK] Remove legacy soft references functionality
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Migrations / TcaMigration.php
1 <?php
2 namespace TYPO3\CMS\Core\Migrations;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Utility\GeneralUtility;
18 use TYPO3\CMS\Core\Utility\StringUtility;
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 = array();
33
34 /**
35 * Migrate old TCA to new TCA.
36 *
37 * See unit tests for details.
38 *
39 * @param array $tca
40 * @return array
41 */
42 public function migrate(array $tca)
43 {
44 $tca = $this->migrateT3editorWizardToRenderTypeT3editorIfNotEnabledByTypeConfig($tca);
45 $tca = $this->migrateSpecialConfigurationAndRemoveShowItemStylePointerConfig($tca);
46 $tca = $this->migrateT3editorWizardWithEnabledByTypeConfigToColumnsOverrides($tca);
47 $tca = $this->migrateShowItemAdditionalPaletteToOwnPalette($tca);
48 $tca = $this->migrateIconsForFormFieldWizardsToNewLocation($tca);
49 $tca = $this->migrateExtAndSysextPathToEXTPath($tca);
50 $tca = $this->migrateIconsInOptionTags($tca);
51 $tca = $this->migrateIconfileRelativePathOrFilenameOnlyToExtReference($tca);
52 $tca = $this->migrateSelectFieldRenderType($tca);
53 $tca = $this->migrateSelectFieldIconTable($tca);
54 $tca = $this->migrateElementBrowserWizardToLinkHandler($tca);
55 $tca = $this->migrateDefaultExtrasRteTransFormOptions($tca);
56 $tca = $this->migrateColorPickerWizardToRenderType($tca);
57 $tca = $this->migrateSelectTreeOptions($tca);
58 $tca = $this->migrateTSconfigSoftReferences($tca);
59 // @todo: if showitem/defaultExtras wizards[xy] is migrated to columnsOverrides here, enableByTypeConfig could be dropped
60 return $tca;
61 }
62
63 /**
64 * Get messages of migrated fields. Can be used for deprecation messages after migrate() was called.
65 *
66 * @return array Migration messages
67 */
68 public function getMessages()
69 {
70 return $this->messages;
71 }
72
73 /**
74 * Migrate type=text field with t3editor wizard to renderType=t3editor without this wizard
75 *
76 * @param array $tca Incoming TCA
77 * @return array Migrated TCA
78 */
79 protected function migrateT3editorWizardToRenderTypeT3editorIfNotEnabledByTypeConfig(array $tca)
80 {
81 $newTca = $tca;
82 foreach ($tca as $table => $tableDefinition) {
83 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
84 continue;
85 }
86 foreach ($tableDefinition['columns'] as $fieldName => $fieldConfig) {
87 if (
88 !empty($fieldConfig['config']['type']) // type is set
89 && trim($fieldConfig['config']['type']) === 'text' // to "text"
90 && isset($fieldConfig['config']['wizards'])
91 && is_array($fieldConfig['config']['wizards']) // and there are wizards
92 ) {
93 foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
94 if (
95 !empty($wizardConfig['userFunc']) // a userFunc is defined
96 && trim($wizardConfig['userFunc']) === 'TYPO3\\CMS\\T3editor\\FormWizard->main' // and set to FormWizard
97 && (
98 !isset($wizardConfig['enableByTypeConfig']) // and enableByTypeConfig is not set
99 || (isset($wizardConfig['enableByTypeConfig']) && !$wizardConfig['enableByTypeConfig']) // or set, but not enabled
100 )
101 ) {
102 // Set renderType from text to t3editor
103 $newTca[$table]['columns'][$fieldName]['config']['renderType'] = 't3editor';
104 // Unset this wizard definition
105 unset($newTca[$table]['columns'][$fieldName]['config']['wizards'][$wizardName]);
106 // Move format parameter
107 if (!empty($wizardConfig['params']['format'])) {
108 $newTca[$table]['columns'][$fieldName]['config']['format'] = $wizardConfig['params']['format'];
109 }
110 $this->messages[] = 'Migrated t3editor wizard in TCA of table "' . $table . '" field "' . $fieldName . '" to a renderType definition.';
111 }
112 }
113 // If no wizard is left after migration, unset the whole sub array
114 if (empty($newTca[$table]['columns'][$fieldName]['config']['wizards'])) {
115 unset($newTca[$table]['columns'][$fieldName]['config']['wizards']);
116 }
117 }
118 }
119 }
120 return $newTca;
121 }
122
123 /**
124 * Remove "style pointer", the 5th parameter from "types" "showitem" configuration.
125 * Move "specConf", 4th parameter from "tyes" "showitem" to "types" "columnsOverrides.
126 *
127 * @param array $tca Incoming TCA
128 * @return array Modified TCA
129 */
130 protected function migrateSpecialConfigurationAndRemoveShowItemStylePointerConfig(array $tca)
131 {
132 $newTca = $tca;
133 foreach ($tca as $table => $tableDefinition) {
134 if (!isset($tableDefinition['types']) || !is_array($tableDefinition['types'])) {
135 continue;
136 }
137 foreach ($tableDefinition['types'] as $typeName => $typeArray) {
138 if (!isset($typeArray['showitem']) || !is_string($typeArray['showitem']) || strpos($typeArray['showitem'], ';') === false) {
139 // Continue directly if no semicolon is found
140 continue;
141 }
142 $itemList = GeneralUtility::trimExplode(',', $typeArray['showitem'], true);
143 $newFieldStrings = array();
144 foreach ($itemList as $fieldString) {
145 $fieldString = rtrim($fieldString, ';');
146 // Unpack the field definition, migrate and remove as much as possible
147 // Keep empty parameters in trimExplode here (third parameter FALSE), so position is not changed
148 $fieldArray = GeneralUtility::trimExplode(';', $fieldString);
149 $fieldArray = array(
150 'fieldName' => isset($fieldArray[0]) ? $fieldArray[0] : '',
151 'fieldLabel' => isset($fieldArray[1]) ? $fieldArray[1] : null,
152 'paletteName' => isset($fieldArray[2]) ? $fieldArray[2] : null,
153 'fieldExtra' => isset($fieldArray[3]) ? $fieldArray[3] : null,
154 );
155 $fieldName = $fieldArray['fieldName'];
156 if (!empty($fieldArray['fieldExtra'])) {
157 // Move fieldExtra "specConf" to columnsOverrides "defaultExtras"
158 if (!isset($newTca[$table]['types'][$typeName]['columnsOverrides'])) {
159 $newTca[$table]['types'][$typeName]['columnsOverrides'] = array();
160 }
161 if (!isset($newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldArray['fieldName']])) {
162 $newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldArray['fieldName']] = array();
163 }
164 // Merge with given defaultExtras from columns.
165 // They will be the first part of the string, so if "specConf" from types changes the same settings,
166 // those will override settings from defaultExtras of columns
167 $newDefaultExtras = array();
168 if (!empty($tca[$table]['columns'][$fieldArray['fieldName']]['defaultExtras'])) {
169 $newDefaultExtras[] = $tca[$table]['columns'][$fieldArray['fieldName']]['defaultExtras'];
170 }
171 $newDefaultExtras[] = $fieldArray['fieldExtra'];
172 $newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldArray['fieldName']]['defaultExtras'] = implode(':', $newDefaultExtras);
173 }
174 unset($fieldArray['fieldExtra']);
175 if (count($fieldArray) === 3 && empty($fieldArray['paletteName'])) {
176 unset($fieldArray['paletteName']);
177 }
178 if (count($fieldArray) === 2 && empty($fieldArray['fieldLabel'])) {
179 unset($fieldArray['fieldLabel']);
180 }
181 if (count($fieldArray) === 1 && empty($fieldArray['fieldName'])) {
182 // The field may vanish if nothing is left
183 unset($fieldArray['fieldName']);
184 }
185 $newFieldString = implode(';', $fieldArray);
186 if ($newFieldString !== $fieldString) {
187 $this->messages[] = 'Changed showitem string of TCA table "' . $table . '" type "' . $typeName . '" due to changed field "' . $fieldName . '".';
188 }
189 if (!empty($newFieldString)) {
190 $newFieldStrings[] = $newFieldString;
191 }
192 }
193 $newTca[$table]['types'][$typeName]['showitem'] = implode(',', $newFieldStrings);
194 }
195 }
196 return $newTca;
197 }
198
199 /**
200 * Migrate type=text field with t3editor wizard that is "enableByTypeConfig" to columnsOverrides
201 * with renderType=t3editor
202 *
203 * @param array $tca Incoming TCA
204 * @return array Migrated TCA
205 */
206 protected function migrateT3editorWizardWithEnabledByTypeConfigToColumnsOverrides(array $tca)
207 {
208 $newTca = $tca;
209 foreach ($tca as $table => $tableDefinition) {
210 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
211 continue;
212 }
213 foreach ($tableDefinition['columns'] as $fieldName => $fieldConfig) {
214 if (
215 !empty($fieldConfig['config']['type']) // type is set
216 && trim($fieldConfig['config']['type']) === 'text' // to "text"
217 && isset($fieldConfig['config']['wizards'])
218 && is_array($fieldConfig['config']['wizards']) // and there are wizards
219 ) {
220 foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
221 if (
222 !empty($wizardConfig['userFunc']) // a userFunc is defined
223 && trim($wizardConfig['userFunc']) === 'TYPO3\CMS\T3editor\FormWizard->main' // and set to FormWizard
224 && !empty($wizardConfig['enableByTypeConfig']) // and enableByTypeConfig is enabled
225 ) {
226 // Remove this wizard
227 unset($newTca[$table]['columns'][$fieldName]['config']['wizards'][$wizardName]);
228 // Find configured types that use this wizard
229 if (!isset($tableDefinition['types']) || !is_array($tableDefinition['types'])) {
230 // No type definition at all ... continue directly
231 continue;
232 }
233 foreach ($tableDefinition['types'] as $typeName => $typeArray) {
234 if (
235 empty($typeArray['columnsOverrides'][$fieldName]['defaultExtras'])
236 || strpos($typeArray['columnsOverrides'][$fieldName]['defaultExtras'], $wizardName) === false
237 ) {
238 // Continue directly if this wizard is not enabled for given type
239 continue;
240 }
241 $defaultExtras = $typeArray['columnsOverrides'][$fieldName]['defaultExtras'];
242 $defaultExtrasArray = GeneralUtility::trimExplode(':', $defaultExtras, true);
243 $newDefaultExtrasArray = array();
244 foreach ($defaultExtrasArray as $fieldExtraField) {
245 // There might be multiple enabled wizards separated by | ... split them
246 if (substr($fieldExtraField, 0, 8) === 'wizards[') {
247 $enabledWizards = substr($fieldExtraField, 8, strlen($fieldExtraField) - 8); // Cut off "wizards[
248 $enabledWizards = substr($enabledWizards, 0, strlen($enabledWizards) - 1);
249 $enabledWizardsArray = GeneralUtility::trimExplode('|', $enabledWizards, true);
250 $newEnabledWizardsArray = array();
251 foreach ($enabledWizardsArray as $enabledWizardName) {
252 if ($enabledWizardName === $wizardName) {
253 // Found a columnsOverrides configuration that has this wizard enabled
254 // Force renderType = t3editor
255 $newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldName]['config']['renderType'] = 't3editor';
256 // Transfer format option if given
257 if (!empty($wizardConfig['params']['format'])) {
258 $newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldName]['config']['format'] = $wizardConfig['params']['format'];
259 }
260 $this->messages[] = 'Migrated t3editor wizard in TCA of table "' . $table . '" field "' . $fieldName
261 . '" to a renderType definition with columnsOverrides in type "' . $typeName . '".';
262 } else {
263 // Some other enabled wizard
264 $newEnabledWizardsArray[] = $enabledWizardName;
265 }
266 }
267 if (!empty($newEnabledWizardsArray)) {
268 $newDefaultExtrasArray[] = 'wizards[' . implode('|', $newEnabledWizardsArray) . ']';
269 }
270 } else {
271 $newDefaultExtrasArray[] = $fieldExtraField;
272 }
273 }
274 if (!empty($newDefaultExtrasArray)) {
275 $newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldName]['defaultExtras'] = implode(':', $newDefaultExtrasArray);
276 } else {
277 unset($newTca[$table]['types'][$typeName]['columnsOverrides'][$fieldName]['defaultExtras']);
278 }
279 }
280 }
281 }
282 // If no wizard is left after migration, unset the whole sub array
283 if (empty($newTca[$table]['columns'][$fieldName]['config']['wizards'])) {
284 unset($newTca[$table]['columns'][$fieldName]['config']['wizards']);
285 }
286 }
287 }
288 }
289 return $newTca;
290 }
291
292 /**
293 * Migrate types showitem 'aField;aLabel;aPalette' to 'afield;aLabel, --palette--;;aPalette'
294 *
295 * Old showitem can have a syntax like:
296 * fieldName;aLabel;aPalette
297 * This way, the palette with name "aPalette" is rendered after fieldName.
298 * The migration parses this to a syntax like:
299 * fieldName;aLabel, --palette--;;paletteName
300 *
301 * @param array $tca Incoming TCA
302 * @return array Migrated TCA
303 */
304 protected function migrateShowItemAdditionalPaletteToOwnPalette(array $tca)
305 {
306 $newTca = $tca;
307 foreach ($tca as $table => $tableDefinition) {
308 if (!isset($tableDefinition['types']) || !is_array($tableDefinition['types'])) {
309 continue;
310 }
311 foreach ($tableDefinition['types'] as $typeName => $typeArray) {
312 if (
313 !isset($typeArray['showitem'])
314 || !is_string($typeArray['showitem'])
315 || strpos($typeArray['showitem'], ';') === false // no field parameters
316 ) {
317 continue;
318 }
319 $itemList = GeneralUtility::trimExplode(',', $typeArray['showitem'], true);
320 $newFieldStrings = array();
321 foreach ($itemList as $fieldString) {
322 $fieldArray = GeneralUtility::trimExplode(';', $fieldString);
323 $fieldArray = array(
324 'fieldName' => isset($fieldArray[0]) ? $fieldArray[0] : '',
325 'fieldLabel' => isset($fieldArray[1]) ? $fieldArray[1] : null,
326 'paletteName' => isset($fieldArray[2]) ? $fieldArray[2] : null,
327 );
328 if ($fieldArray['fieldName'] !== '--palette--' && $fieldArray['paletteName'] !== null) {
329 if ($fieldArray['fieldLabel']) {
330 $fieldString = $fieldArray['fieldName'] . ';' . $fieldArray['fieldLabel'];
331 } else {
332 $fieldString = $fieldArray['fieldName'];
333 }
334 $paletteString = '--palette--;;' . $fieldArray['paletteName'];
335 $this->messages[] = 'Migrated TCA table "' . $table . '" showitem field of type "' . $typeName . '": Moved additional palette'
336 . ' with name "' . $fieldArray['paletteName'] . '" as 3rd argument of field "' . $fieldArray['fieldName']
337 . '" to an own palette. The result of this part is: "' . $fieldString . ', ' . $paletteString . '"';
338 $newFieldStrings[] = $fieldString;
339 $newFieldStrings[] = $paletteString;
340 } else {
341 $newFieldStrings[] = $fieldString;
342 }
343 }
344 $newTca[$table]['types'][$typeName]['showitem'] = implode(',', $newFieldStrings);
345 }
346 }
347 return $newTca;
348 }
349
350 /**
351 * Migrate core icons for form field wizard to new location
352 *
353 * add.gif => EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_add.gif
354 * link_popup.gif => EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_link.gif
355 * wizard_rte2.gif => EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_rte.gif
356 * wizard_table.gif => EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_table.gif
357 * edit2.gif => EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_edit.gif
358 * list.gif => EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_list.gif
359 * wizard_forms.gif => EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_forms.gif
360 *
361 * @param array $tca Incoming TCA
362 * @return array Migrated TCA
363 */
364 protected function migrateIconsForFormFieldWizardsToNewLocation(array $tca)
365 {
366 $newTca = $tca;
367
368 $oldFileNames = array(
369 'add.gif',
370 'link_popup.gif',
371 'wizard_rte2.gif',
372 'wizard_table.gif',
373 'edit2.gif',
374 'list.gif',
375 'wizard_forms.gif',
376 );
377
378 $newFileLocations = array(
379 'add.gif' => 'EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_add.gif',
380 'link_popup.gif' => 'EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_link.gif',
381 'wizard_rte2.gif' => 'EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_rte.gif',
382 'wizard_table.gif' => 'EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_table.gif',
383 'edit2.gif' => 'EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_edit.gif',
384 'list.gif' => 'EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_list.gif',
385 'wizard_forms.gif' => 'EXT:backend/Resources/Public/Images/FormFieldWizard/wizard_forms.gif',
386 );
387
388 foreach ($tca as $table => $tableDefinition) {
389 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
390 continue;
391 }
392 foreach ($tableDefinition['columns'] as $fieldName => $fieldConfig) {
393 if (
394 isset($fieldConfig['config']['wizards'])
395 && is_array($fieldConfig['config']['wizards']) // and there are wizards
396 ) {
397 foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizardConfig) {
398 if (!is_array($wizardConfig)) {
399 continue;
400 }
401
402 foreach ($wizardConfig as $option => $value) {
403 if ($option === 'icon' && in_array($value, $oldFileNames, true)) {
404 $newTca[$table]['columns'][$fieldName]['config']['wizards'][$wizardName]['icon'] = $newFileLocations[$value];
405 $this->messages[] = 'Migrated icon path of wizard "' . $wizardName . '" in field "' . $fieldName . '" from TCA table "' . $table . '". New path is: ' . $newFileLocations[$value];
406 }
407 }
408 }
409 }
410 }
411 }
412
413 return $newTca;
414 }
415
416 /**
417 * Migrate file reference which starts with ext/ or sysext/ to EXT:
418 *
419 * @param array $tca Incoming TCA
420 * @return array Migrated TCA
421 */
422 protected function migrateExtAndSysextPathToEXTPath(array $tca)
423 {
424 foreach ($tca as $table => &$tableDefinition) {
425 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
426 continue;
427 }
428 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
429 if (
430 !empty($fieldConfig['config']['type']) // type is set
431 && trim($fieldConfig['config']['type']) === 'select' // to "select"
432 && isset($fieldConfig['config']['items'])
433 && is_array($fieldConfig['config']['items']) // and there are items
434 ) {
435 foreach ($fieldConfig['config']['items'] as &$itemConfig) {
436 // more then two values? then the third entry is the image path
437 if (!empty($itemConfig[2])) {
438 $tcaPath = implode('.', [$table, 'columns', $fieldName, 'config', 'items']);
439 $pathParts = GeneralUtility::trimExplode('/', $itemConfig[2]);
440 // remove first element (ext or sysext)
441 array_shift($pathParts);
442 $path = implode('/', $pathParts);
443 // If the path starts with ext/ or sysext/ migrate it
444 if (
445 StringUtility::beginsWith($itemConfig[2], 'ext/')
446 || StringUtility::beginsWith($itemConfig[2], 'sysext/')
447 ) {
448 $this->messages[] = '[' . $tcaPath . '] ext/ or sysext/ within the path (' . $path . ') in items array is deprecated, use EXT: reference';
449 $itemConfig[2] = 'EXT:' . $path;
450 } elseif (StringUtility::beginsWith($itemConfig[2], 'i/')) {
451 $this->messages[] = '[' . $tcaPath . '] i/ within the path (' . $path . ') in items array is deprecated, use EXT: reference';
452 $itemConfig[2] = 'EXT:t3skin/icons/gfx/' . $itemConfig[2];
453 }
454 }
455 }
456 }
457 }
458 }
459 return $tca;
460 }
461
462 /**
463 * Migrate "iconsInOptionTags" for "select" TCA fields
464 *
465 * @param array $tca Incoming TCA
466 * @return array Migrated TCA
467 */
468 protected function migrateIconsInOptionTags(array $tca)
469 {
470 $newTca = $tca;
471
472 foreach ($newTca as $table => &$tableDefinition) {
473 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
474 continue;
475 }
476 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
477 if (isset($fieldConfig['config']['iconsInOptionTags'])) {
478 unset($fieldConfig['config']['iconsInOptionTags']);
479 $this->messages[] = 'Configuration option "iconsInOptionTags" was removed from field "' . $fieldName . '" in TCA table "' . $table . '"';
480 }
481 }
482 }
483
484 return $newTca;
485 }
486
487 /**
488 * Migrate "iconfile" references which starts with ../ to EXT: and consisting of filename only to absolute paths in EXT:t3skin
489 *
490 * @param array $tca Incoming TCA
491 * @return array Migrated TCA
492 */
493 protected function migrateIconfileRelativePathOrFilenameOnlyToExtReference(array $tca)
494 {
495 foreach ($tca as $table => &$tableDefinition) {
496 if (!isset($tableDefinition['ctrl']) || !is_array($tableDefinition['ctrl'])) {
497 continue;
498 }
499 if (!isset($tableDefinition['ctrl']['iconfile'])) {
500 continue;
501 }
502 if (StringUtility::beginsWith($tableDefinition['ctrl']['iconfile'], '../typo3conf/ext/')) {
503 $tableDefinition['ctrl']['iconfile'] = str_replace('../typo3conf/ext/', 'EXT:', $tableDefinition['ctrl']['iconfile']);
504 $tcaPath = implode('.', [$table, 'ctrl', 'iconfile']);
505 $this->messages[] = '[' . $tcaPath . '] relative path to ../typo3conf/ext/ is deprecated, use EXT: instead';
506 } elseif (strpos($tableDefinition['ctrl']['iconfile'], '/') === false) {
507 $tableDefinition['ctrl']['iconfile'] = 'EXT:t3skin/icons/gfx/i/' . $tableDefinition['ctrl']['iconfile'];
508 $tcaPath = implode('.', [$table, 'ctrl', 'iconfile']);
509 $this->messages[] = '[' . $tcaPath . '] filename only is deprecated, use EXT: or absolute reference instead';
510 }
511 }
512 return $tca;
513 }
514
515 /**
516 * Migrate "type=select" with "renderMode=[tree|singlebox|checkbox]" to "renderType=[selectTree|selectSingleBox|selectCheckBox]".
517 * This migration also take care of "maxitems" settings and set "renderType=[selectSingle|selectMultipleSideBySide]" if no other
518 * renderType is already set.
519 *
520 * @param array $tca
521 * @return array
522 */
523 public function migrateSelectFieldRenderType(array $tca)
524 {
525 $newTca = $tca;
526
527 foreach ($newTca as $table => &$tableDefinition) {
528 if (empty($tableDefinition['columns'])) {
529 continue;
530 }
531
532 foreach ($tableDefinition['columns'] as $columnName => &$columnDefinition) {
533 // Only handle select fields.
534 if (empty($columnDefinition['config']['type']) || $columnDefinition['config']['type'] !== 'select') {
535 continue;
536 }
537 // Do not handle field where the render type is set.
538 if (!empty($columnDefinition['config']['renderType'])) {
539 continue;
540 }
541
542 $tableColumnInfo = 'table "' . $table . '" and column "' . $columnName . '"';
543 $this->messages[] = 'Using select fields without the "renderType" setting is deprecated in ' . $tableColumnInfo;
544
545 $columnConfig = &$columnDefinition['config'];
546 if (!empty($columnConfig['renderMode'])) {
547 $this->messages[] = 'The "renderMode" setting for select fields is deprecated. Please use "renderType" instead in ' . $tableColumnInfo;
548 switch ($columnConfig['renderMode']) {
549 case 'tree':
550 $columnConfig['renderType'] = 'selectTree';
551 break;
552 case 'singlebox':
553 $columnConfig['renderType'] = 'selectSingleBox';
554 break;
555 case 'checkbox':
556 $columnConfig['renderType'] = 'selectCheckBox';
557 break;
558 default:
559 $this->messages[] = 'The render mode ' . $columnConfig['renderMode'] . ' is invalid for the select field in ' . $tableColumnInfo;
560 }
561 continue;
562 }
563
564 $maxItems = !empty($columnConfig['maxitems']) ? (int)$columnConfig['maxitems'] : 1;
565 if ($maxItems <= 1) {
566 $columnConfig['renderType'] = 'selectSingle';
567 } else {
568 $columnConfig['renderType'] = 'selectMultipleSideBySide';
569 }
570 }
571 }
572
573 return $newTca;
574 }
575
576 /**
577 * Migrate the visibility of the icon table for fields with "renderType=selectSingle"
578 *
579 * @param array $tca
580 * @return array Migrated TCA
581 */
582 public function migrateSelectFieldIconTable(array $tca)
583 {
584 foreach ($tca as $table => &$tableDefinition) {
585 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
586 continue;
587 }
588 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
589 if (empty($fieldConfig['config']['renderType']) || $fieldConfig['config']['renderType'] !== 'selectSingle') {
590 continue;
591 }
592 if (!empty($fieldConfig['config']['selicon_cols'])) {
593 // selicon_cols without showIconTable true does not make sense, so set it to true here if not already defined
594 if (!array_key_exists('showIconTable', $fieldConfig['config'])) {
595 $this->messages[] = 'The "showIconTable" setting is missing for table "' . $table . '" and field "' . $fieldName . '"';
596 $fieldConfig['config']['showIconTable'] = true;
597 }
598 }
599 if (array_key_exists('noIconsBelowSelect', $fieldConfig['config'])) {
600 $this->messages[] = 'The "noIconsBelowSelect" setting for select fields was removed. Please define the setting "showIconTable" for table "' . $table . '" and field "' . $fieldName . '"';
601 if (!$fieldConfig['config']['noIconsBelowSelect']) {
602 // If old setting was explicitly false, enable icon table if not defined yet
603 if (!array_key_exists('showIconTable', $fieldConfig['config'])) {
604 $fieldConfig['config']['showIconTable'] = true;
605 }
606 }
607 unset($fieldConfig['config']['noIconsBelowSelect']);
608 }
609 if (array_key_exists('suppress_icons', $fieldConfig['config'])) {
610 $this->messages[] = 'The "suppress_icons" setting for select fields was removed. Please define the setting "showIconTable" for table "' . $table . '" and field "' . $fieldName . '"';
611 unset($fieldConfig['config']['suppress_icons']);
612 }
613 if (array_key_exists('foreign_table_loadIcons', $fieldConfig['config'])) {
614 $this->messages[] = 'The "foreign_table_loadIcons" setting for select fields was removed. Please define the setting "showIconTable" for table "' . $table . '" and field "' . $fieldName . '"';
615 unset($fieldConfig['config']['foreign_table_loadIcons']);
616 }
617 }
618 }
619 return $tca;
620 }
621
622 /**
623 * Migrate wizard "wizard_element_browser" used in mode "wizard" to use the "wizard_link" instead
624 *
625 * @param array $tca
626 * @return array Migrated TCA
627 */
628 protected function migrateElementBrowserWizardToLinkHandler(array $tca)
629 {
630 foreach ($tca as $table => &$tableDefinition) {
631 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
632 continue;
633 }
634 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
635 if (
636 isset($fieldConfig['config']['wizards']['link']['module']['name']) && $fieldConfig['config']['wizards']['link']['module']['name'] === 'wizard_element_browser'
637 && isset($fieldConfig['config']['wizards']['link']['module']['urlParameters']['mode']) && $fieldConfig['config']['wizards']['link']['module']['urlParameters']['mode'] === 'wizard'
638 ) {
639 $fieldConfig['config']['wizards']['link']['module']['name'] = 'wizard_link';
640 unset($fieldConfig['config']['wizards']['link']['module']['urlParameters']['mode']);
641 if (empty($fieldConfig['config']['wizards']['link']['module']['urlParameters'])) {
642 unset($fieldConfig['config']['wizards']['link']['module']['urlParameters']);
643 }
644 $this->messages[] = 'Reference to "wizard_element_browser" was migrated to new "wizard_link" for field "' . $fieldName . '" in TCA table "' . $table . '"';
645 }
646 }
647 }
648 return $tca;
649 }
650
651 /**
652 * Migrate defaultExtras "richtext:rte_transform[mode=ts_css]" and similar stuff like
653 * "richtext:rte_transform[mode=ts_css]" to "richtext:rte_transform"
654 *
655 * @param array $tca
656 * @return array Migrated TCA
657 */
658 protected function migrateDefaultExtrasRteTransFormOptions(array $tca)
659 {
660 foreach ($tca as $table => &$tableDefinition) {
661 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
662 continue;
663 }
664 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
665 if (isset($fieldConfig['defaultExtras'])) {
666 $oldValue = $fieldConfig['defaultExtras'];
667 $fieldConfig['defaultExtras'] = preg_replace(
668 '/richtext(\[([^\]]*)\])*:rte_transform(\[([^\]]*)\])/',
669 'richtext${1}:rte_transform',
670 $fieldConfig['defaultExtras'],
671 -1,
672 $replacementCount
673 );
674 if ($replacementCount) {
675 $this->messages[] = 'rte_transform options are deprecated. String "' . $oldValue . '" in TCA'
676 . ' ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'defaultExtras\'] was changed to "'
677 . $fieldConfig['defaultExtras'] . '"';
678 }
679 }
680 }
681 }
682
683 foreach ($tca as $table => &$tableDefinition) {
684 if (!isset($tableDefinition['types']) || !is_array($tableDefinition['types'])) {
685 continue;
686 }
687 foreach ($tableDefinition['types'] as $typeName => &$typeArray) {
688 if (!isset($typeArray['columnsOverrides']) || !is_array($typeArray['columnsOverrides'])) {
689 continue;
690 }
691 foreach ($typeArray['columnsOverrides'] as $fieldName => &$fieldConfig) {
692 if (isset($fieldConfig['defaultExtras'])) {
693 $oldValue = $fieldConfig['defaultExtras'];
694 $fieldConfig['defaultExtras'] = preg_replace(
695 '/richtext(\[([^\]]*)\])*:rte_transform(\[([^\]]*)\])/',
696 'richtext${1}:rte_transform',
697 $fieldConfig['defaultExtras'],
698 -1,
699 $replacementCount
700 );
701 if ($replacementCount) {
702 $this->messages[] = 'rte_transform options are deprecated. String "'
703 . $oldValue . '" in TCA'
704 . ' ' . $table . '[\'types\'][\'' . $typeName
705 . '\'][\'columnsOverrides\'][\'' . $fieldName
706 . '\'][\'defaultExtras\']' .
707 ' was changed to "' . $fieldConfig['defaultExtras'] . '"';
708 }
709 }
710 }
711 }
712 }
713
714 return $tca;
715 }
716
717 /**
718 * Migrates fields having a colorpicker wizard to a color field
719 *
720 * @param array $tca Incoming TCA
721 * @return array Migrated TCA
722 */
723 protected function migrateColorPickerWizardToRenderType(array $tca)
724 {
725 foreach ($tca as $table => &$tableDefinition) {
726 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
727 continue;
728 }
729 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
730 if (isset($fieldConfig['config'])) {
731 if (isset($fieldConfig['config']['wizards'])) {
732 foreach ($fieldConfig['config']['wizards'] as $wizardName => $wizard) {
733 if (isset($wizard['type']) && ($wizard['type'] === 'colorbox')) {
734 unset($fieldConfig['config']['wizards'][$wizardName]);
735 if (empty($fieldConfig['config']['wizards'])) {
736 unset($fieldConfig['config']['wizards']);
737 }
738 $fieldConfig['config']['renderType'] = 'colorpicker';
739
740 $this->messages[] = 'The color-picker wizard using \'colorbox\' is deprecated'
741 . ' in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
742 . '[\'wizards\'][\'' . $wizardName . '\'] and is changed to ' . $table
743 . '[\'columns\'][\'' . $fieldName . '\'][\'config\'] = \'colorpicker\'';
744 }
745 }
746 }
747 }
748 }
749 }
750
751 return $tca;
752 }
753
754 /**
755 * Migrates selectTree fields deprecated options
756 *
757 * @param array $tca Incoming TCA
758 * @return array Migrated TCA
759 */
760 protected function migrateSelectTreeOptions(array $tca)
761 {
762 foreach ($tca as $table => &$tableDefinition) {
763 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
764 continue;
765 }
766 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
767 if (isset($fieldConfig['config']['renderType']) && $fieldConfig['config']['renderType'] === 'selectTree') {
768 if (isset($fieldConfig['config']['treeConfig']['appearance']['width'])) {
769 $this->messages[] = 'The selectTree field [\'treeConfig\'][\'appearance\'][\'width\'] setting is deprecated'
770 . ' and was removed in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
771 . '[\'treeConfig\'][\'appearance\'][\'width\'] ';
772 unset($fieldConfig['config']['treeConfig']['appearance']['width']);
773 }
774
775 if (isset($fieldConfig['config']['treeConfig']['appearance']['allowRecursiveMode'])) {
776 $this->messages[] = 'The selectTree field [\'treeConfig\'][\'appearance\'][\'allowRecursiveMode\'] setting is deprecated'
777 . ' and was removed in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\']'
778 . '[\'treeConfig\'][\'appearance\'][\'allowRecursiveMode\'] ';
779 unset($fieldConfig['config']['treeConfig']['appearance']['allowRecursiveMode']);
780 }
781
782 if (isset($fieldConfig['config']['autoSizeMax'])) {
783 $this->messages[] = 'The selectTree field [\'autoSizeMax\'] setting is deprecated'
784 . ' and was removed in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'config\'][\'autoSizeMax\'].'
785 . ' The \'size\' value was adapted to the previous autoSizeMax value';
786 $fieldConfig['config']['size'] = $fieldConfig['config']['autoSizeMax'];
787 unset($fieldConfig['config']['autoSizeMax']);
788 }
789 }
790 }
791 }
792 return $tca;
793 }
794
795 /**
796 * Migrates selectTree fields deprecated options
797 *
798 * @param array $tca Incoming TCA
799 * @return array Migrated TCA
800 */
801 protected function migrateTSconfigSoftReferences(array $tca)
802 {
803 foreach ($tca as $table => &$tableDefinition) {
804 if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
805 continue;
806 }
807 foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
808 if (isset($fieldConfig['config'])) {
809 if (isset($fieldConfig['config']['softref'])) {
810 $softReferences = array_flip(GeneralUtility::trimExplode(',', $fieldConfig['config']['softref']));
811 $changed = false;
812 if (isset($softReferences['TSconfig'])) {
813 $changed = true;
814 unset($softReferences['TSconfig']);
815 }
816 if (isset($softReferences['TStemplate'])) {
817 $changed = true;
818 unset($softReferences['TStemplate']);
819 }
820 if ($changed) {
821 if (!empty($softReferences)) {
822 $softReferences = array_flip($softReferences);
823 $fieldConfig['config']['softref'] = implode(',', $softReferences);
824 } else {
825 unset($fieldConfig['config']['softref']);
826 }
827 $this->messages[] = 'The soft reference setting using \'TSconfig\' and '
828 . '\'TStemplate\' was removed in TCA ' . $table . '[\'columns\']'
829 . '[\'' . $fieldName . '\'][\'config\'][\'softref\']';
830 }
831 }
832 }
833 }
834 }
835 return $tca;
836 }
837 }