We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * (c) Kitodo. Key to digital objects e.V. <[email protected]> |
||
5 | * |
||
6 | * This file is part of the Kitodo and TYPO3 projects. |
||
7 | * |
||
8 | * @license GNU General Public License version 3 or later. |
||
9 | * For the full copyright and license information, please read the |
||
10 | * LICENSE.txt file that was distributed with this source code. |
||
11 | */ |
||
12 | |||
13 | namespace Kitodo\Dlf\Updates; |
||
14 | |||
15 | use TYPO3\CMS\Core\Database\ConnectionPool; |
||
16 | use TYPO3\CMS\Core\Database\Query\QueryBuilder; |
||
17 | use TYPO3\CMS\Core\Utility\GeneralUtility; |
||
18 | use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite; |
||
19 | use TYPO3\CMS\Install\Updates\UpgradeWizardInterface; |
||
20 | |||
21 | /** |
||
22 | * Class MigrateSettings |
||
23 | * |
||
24 | * @package TYPO3 |
||
25 | * @subpackage dlf |
||
26 | * |
||
27 | * @internal |
||
28 | */ |
||
29 | class MigrateSettings implements UpgradeWizardInterface |
||
30 | { |
||
31 | |||
32 | /** |
||
33 | * Return the identifier for this wizard |
||
34 | * This should be the same string as used in the ext_localconf class registration |
||
35 | * |
||
36 | * @access public |
||
37 | * |
||
38 | * @return string |
||
39 | */ |
||
40 | public function getIdentifier(): string |
||
41 | { |
||
42 | return self::class; |
||
43 | } |
||
44 | |||
45 | /** |
||
46 | * Return the speaking name of this wizard |
||
47 | * |
||
48 | * @access public |
||
49 | * |
||
50 | * @return string |
||
51 | */ |
||
52 | public function getTitle(): string |
||
53 | { |
||
54 | return 'Migrate Kitodo.Presentation plugins to use Extbase settings naming scheme'; |
||
55 | } |
||
56 | |||
57 | /** |
||
58 | * Return the description for this wizard |
||
59 | * |
||
60 | * @access public |
||
61 | * |
||
62 | * @return string |
||
63 | */ |
||
64 | public function getDescription(): string |
||
65 | { |
||
66 | return 'This wizard migrates existing front end plugins of the extension Kitodo.Presentation (dlf) to' . |
||
67 | ' make use of the Extbase naming scheme. Therefore it updates the field values' . |
||
68 | ' "pi_flexform" within the tt_content table'; |
||
69 | } |
||
70 | |||
71 | /** |
||
72 | * Execute the update |
||
73 | * |
||
74 | * Called when a wizard reports that an update is necessary |
||
75 | * |
||
76 | * @access public |
||
77 | * |
||
78 | * @return bool |
||
79 | */ |
||
80 | public function executeUpdate(): bool |
||
81 | { |
||
82 | // Get all tt_content data of Kitodo.Presentation and update their flexforms settings |
||
83 | $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tt_content'); |
||
84 | |||
85 | /** @var QueryBuilder $queryBuilder */ |
||
86 | $queryBuilder = $connection->createQueryBuilder(); |
||
87 | $statement = $queryBuilder->select('uid') |
||
88 | ->addSelect('pi_flexform') |
||
89 | ->from('tt_content') |
||
90 | ->where( |
||
91 | $queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('list')), |
||
92 | $queryBuilder->expr()->like('list_type', $queryBuilder->createNamedParameter('dlf_%')) |
||
93 | ) |
||
94 | ->execute(); |
||
95 | |||
96 | // Update the found record sets |
||
97 | while ($record = $statement->fetchAssociative()) { |
||
98 | $queryBuilder = $connection->createQueryBuilder(); |
||
99 | $updateResult = $queryBuilder->update('tt_content') |
||
100 | ->where( |
||
101 | $queryBuilder->expr()->eq( |
||
102 | 'uid', |
||
103 | $queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT) |
||
104 | ) |
||
105 | ) |
||
106 | ->set('pi_flexform', $this->migrateFlexFormSettings($record['pi_flexform'])) |
||
107 | ->execute(); |
||
108 | |||
109 | // exit if at least one update statement is not successful |
||
110 | if (!((bool) $updateResult)) { |
||
111 | return false; |
||
112 | } |
||
113 | } |
||
114 | |||
115 | return true; |
||
116 | } |
||
117 | |||
118 | /** |
||
119 | * Is an update necessary? |
||
120 | * |
||
121 | * Looks for fe plugins in tt_content table to be migrated |
||
122 | * |
||
123 | * @access public |
||
124 | * |
||
125 | * @return bool |
||
126 | */ |
||
127 | public function updateNecessary(): bool |
||
128 | { |
||
129 | $oldSettingsFound = false; |
||
130 | |||
131 | $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tt_content'); |
||
132 | |||
133 | /** @var QueryBuilder $queryBuilder */ |
||
134 | $queryBuilder = $connection->createQueryBuilder(); |
||
135 | $statement = $queryBuilder->select('uid') |
||
136 | ->addSelect('pi_flexform') |
||
137 | ->from('tt_content') |
||
138 | ->where( |
||
139 | $queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('list')), |
||
140 | $queryBuilder->expr()->like('list_type', $queryBuilder->createNamedParameter('dlf_%')) |
||
141 | ) |
||
142 | ->execute(); |
||
143 | |||
144 | // Update the found record sets |
||
145 | while ($record = $statement->fetchAssociative()) { |
||
146 | $oldSettingsFound = $this->checkForOldSettings($record['pi_flexform']); |
||
147 | if ($oldSettingsFound === true) { |
||
148 | // We found at least one field to be updated --> break here |
||
149 | break; |
||
150 | } |
||
151 | } |
||
152 | |||
153 | return $oldSettingsFound; |
||
154 | } |
||
155 | |||
156 | /** |
||
157 | * Returns an array of class names of Prerequisite classes |
||
158 | * |
||
159 | * This way a wizard can define dependencies like "database up-to-date" or |
||
160 | * "reference index updated" |
||
161 | * |
||
162 | * @access public |
||
163 | * |
||
164 | * @return string[] |
||
165 | */ |
||
166 | public function getPrerequisites(): array |
||
167 | { |
||
168 | return [ |
||
169 | DatabaseUpdatedPrerequisite::class |
||
170 | ]; |
||
171 | } |
||
172 | |||
173 | |||
174 | /** |
||
175 | * @access protected |
||
176 | * |
||
177 | * @param string $oldValue |
||
178 | * |
||
179 | * @return string |
||
180 | */ |
||
181 | protected function migrateFlexFormSettings(string $oldValue): string |
||
182 | { |
||
183 | $xml = simplexml_load_string($oldValue); |
||
184 | |||
185 | // get all field elements |
||
186 | $fields = $xml->xpath("//field"); |
||
187 | |||
188 | foreach ($fields as $field) { |
||
189 | // change the index attribute if it doesn't start with 'settings.' yet |
||
190 | if (strpos($field['index'], 'settings.') === false) { |
||
191 | $field['index'] = 'settings.' . $field['index']; |
||
192 | } |
||
193 | } |
||
194 | |||
195 | return $xml->asXML(); |
||
0 ignored issues
–
show
Bug
Best Practice
introduced
by
![]() |
|||
196 | |||
197 | } |
||
198 | |||
199 | /** |
||
200 | * @access protected |
||
201 | * |
||
202 | * @param string $flexFormXml |
||
203 | * |
||
204 | * @return bool |
||
205 | */ |
||
206 | protected function checkForOldSettings(string $flexFormXml): bool |
||
207 | { |
||
208 | $xml = simplexml_load_string($flexFormXml); |
||
209 | |||
210 | // get all field elements with value of attribute index not containing "settings." |
||
211 | $fields = $xml->xpath("//field[not(starts-with(@index, 'settings.'))]"); |
||
212 | |||
213 | return (bool) $fields; |
||
214 | } |
||
215 | |||
216 | } |
||
217 |