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