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