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