[FEATURE] Move CE table options from flexform to tt_content
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / Updates / TableFlexFormToTtContentFieldsUpdate.php
1 <?php
2 namespace TYPO3\CMS\Install\Updates;
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\ExtensionManagementUtility;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19
20 /**
21 * Migrate the Flexform for CType 'table' to regular fields in tt_content
22 */
23 class TableFlexFormToTtContentFieldsUpdate extends AbstractUpdate {
24
25 /**
26 * @var string
27 */
28 protected $title = 'Migrate the Flexform for CType "table" to regular fields in tt_content';
29
30 /**
31 * Checks if an update is needed
32 *
33 * @param string &$description The description for the update
34 * @return bool Whether an update is needed (TRUE) or not (FALSE)
35 */
36 public function checkForUpdate(&$description) {
37 $flexFormCount = $this->getDatabaseConnection()->exec_SELECTcountRows(
38 'uid',
39 'tt_content',
40 'CType=\'table\' AND pi_flexform IS NOT NULL AND deleted = 0'
41 );
42
43 if (
44 $this->isWizardDone() || $flexFormCount === 0
45 || ExtensionManagementUtility::isLoaded('css_styled_content')
46 ) {
47 return FALSE;
48 }
49
50 $description = 'The extension "frontend" uses regular database fields in the tt_content table ' .
51 'for the CType "table". Before this was a FlexForm.<br /><br />'.
52 'This update wizard migrates these FlexForms to regular database fields.';
53
54 return TRUE;
55 }
56
57 /**
58 * Performs the database update if CType 'table' still has content in pi_flexform
59 *
60 * @param array &$databaseQueries Queries done in this update
61 * @param mixed &$customMessages Custom messages
62 * @return bool
63 */
64 public function performUpdate(array &$databaseQueries, &$customMessages) {
65 $databaseConnection = $this->getDatabaseConnection();
66
67 $databaseResult = $databaseConnection->exec_SELECTquery(
68 'uid, pi_flexform',
69 'tt_content',
70 'CType=\'table\' AND pi_flexform IS NOT NULL AND deleted = 0'
71 );
72
73 while ($tableRecord = $databaseConnection->sql_fetch_assoc($databaseResult)) {
74 $flexForm = $this->initializeFlexForm($tableRecord['pi_flexform']);
75
76 if (is_array($flexForm)) {
77 $fields = $this->mapFieldsFromFlexForm($flexForm);
78
79 // Set pi_flexform to NULL
80 $fields['pi_flexform'] = NULL;
81
82 $databaseConnection->exec_UPDATEquery(
83 'tt_content',
84 'uid=' . (int)$tableRecord['uid'],
85 $fields
86 );
87
88 $databaseQueries[] = $databaseConnection->debug_lastBuiltQuery;
89 }
90 }
91
92 $databaseConnection->sql_free_result($databaseResult);
93
94 $this->markWizardAsDone();
95
96 return TRUE;
97 }
98
99 /**
100 * Map the old FlexForm values to the new database fields
101 * and fill them with the proper data
102 *
103 * @param array $flexForm The content of the FlexForm
104 * @return array The fields which need to be updated in the tt_content table
105 */
106 protected function mapFieldsFromFlexForm($flexForm) {
107 $fields = array();
108
109 $mapping = array(
110 'table_caption' => array(
111 'sheet' => 'sDEF',
112 'fieldName' => 'acctables_caption',
113 'default' => '',
114 'values' => 'passthrough'
115 ),
116 'table_delimiter' => array(
117 'sheet' => 's_parsing',
118 'fieldName' => 'tableparsing_delimiter',
119 'default' => 124,
120 'values' => 'passthrough'
121 ),
122 'table_enclosure' => array(
123 'sheet' => 's_parsing',
124 'fieldName' => 'tableparsing_quote',
125 'default' => 0,
126 'values' => 'passthrough'
127 ),
128 'table_header_position' => array(
129 'sheet' => 'sDEF',
130 'fieldName' => 'acctables_headerpos',
131 'default' => 0,
132 'values' => array(
133 'top' => 1,
134 'left' => 2
135 )
136 ),
137 'table_tfoot' => array(
138 'sheet' => 'sDEF',
139 'fieldName' => 'acctables_tfoot',
140 'default' => 0,
141 'values' => 'passthrough'
142 )
143 );
144
145 foreach ($mapping as $fieldName => $configuration) {
146 $flexFormValue = $this->getFlexFormValue($flexForm, $configuration['fieldName'], $configuration['sheet']);
147
148 if ($flexFormValue !== '') {
149 if ($configuration['values'] === 'passthrough') {
150 $fields[$fieldName] = $flexFormValue;
151 } elseif (is_array($configuration['values'])) {
152 $fields[$fieldName] = $configuration['values'][$flexFormValue];
153 }
154 } else {
155 $fields[$fieldName] = $configuration['default'];
156 }
157 }
158
159 return $fields;
160
161 }
162
163 /**
164 * Convert the XML of the FlexForm to an array
165 *
166 * @param string|NULL $flexFormXml The XML of the FlexForm
167 * @return array|NULL Converted XML to array
168 */
169 protected function initializeFlexForm($flexFormXml) {
170 $flexForm = NULL;
171
172 if ($flexFormXml) {
173 $flexForm = GeneralUtility::xml2array($flexFormXml);
174 if (!is_array($flexForm)) {
175 $flexForm = NULL;
176 }
177 }
178
179 return $flexForm;
180 }
181
182 /**
183 * @param array $flexForm The content of the FlexForm
184 * @param string $fieldName The field name to get the value for
185 * @param string $sheet The sheet on which this value is located
186 * @return string The value
187 */
188 protected function getFlexFormValue(array $flexForm, $fieldName, $sheet = 'sDEF') {
189 return $flexForm['data'][$sheet]['lDEF'][$fieldName]['vDEF'];
190 }
191 }