[TASK] Doctrine: Migrate WorkspacesNotificationSettingsUpdate
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / Updates / WorkspacesNotificationSettingsUpdate.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\Database\ConnectionPool;
18 use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
19 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
20 use TYPO3\CMS\Core\Utility\GeneralUtility;
21
22 /**
23 * Migrate the workspaces notification settings to the enhanced schema.
24 */
25 class WorkspacesNotificationSettingsUpdate extends AbstractUpdate
26 {
27 /**
28 * @var string
29 */
30 protected $title = 'Migrate the workspaces notification settings to the enhanced schema';
31
32 /**
33 * Checks if an update is needed
34 *
35 * @param string &$description The description for the update
36 * @return bool Whether an update is needed (TRUE) or not (FALSE)
37 */
38 public function checkForUpdate(&$description)
39 {
40 if (!ExtensionManagementUtility::isLoaded('workspaces') || $this->isWizardDone()) {
41 return false;
42 }
43
44 $workspacesCount = GeneralUtility::makeInstance(ConnectionPool::class)
45 ->getConnectionForTable('sys_workspace')
46 ->count(
47 'uid',
48 'sys_workspace',
49 ['deleted' => 0]
50 );
51 $stagesCount = GeneralUtility::makeInstance(ConnectionPool::class)
52 ->getConnectionForTable('sys_workspace_stage')
53 ->count(
54 'uid',
55 'sys_workspace_stage',
56 ['deleted' => 0]
57 );
58 if ($workspacesCount + $stagesCount > 0) {
59 $description = 'The workspaces notification settings have been extended'
60 . ' and need to be migrated to the new definitions. This update wizard'
61 . ' upgrades the accordant settings in the available workspaces and stages.';
62 return true;
63 } else {
64 $this->markWizardAsDone();
65 }
66
67 return false;
68 }
69
70 /**
71 * Perform the database updates for workspace records
72 *
73 * @param array &$databaseQueries Queries done in this update
74 * @param mixed &$customMessages Custom messages
75 * @return bool
76 */
77 public function performUpdate(array &$databaseQueries, &$customMessages)
78 {
79 $workspaceConnection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('sys_workspace');
80 $queryBuilder = $workspaceConnection->createQueryBuilder();
81 $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
82 $statement = $queryBuilder->select('*')->from('sys_workspace')->execute();
83 while ($workspaceRecord = $statement->fetch()) {
84 $update = $this->prepareWorkspaceUpdate($workspaceRecord);
85 if ($update !== null) {
86 $queryBuilder = $workspaceConnection->createQueryBuilder();
87 $queryBuilder->update('sys_workspace')
88 ->where($queryBuilder->expr()->eq('uid', (int)$workspaceRecord['uid']));
89 foreach ($update as $field => $value) {
90 $queryBuilder->set($field, $queryBuilder->quote($value), false);
91 }
92 $databaseQueries[] = $queryBuilder->getSQL();
93 $queryBuilder->execute();
94 }
95 }
96
97 $stageConnection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('sys_workspace_stage');
98 $queryBuilder = $stageConnection->createQueryBuilder();
99 $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
100 $statement = $queryBuilder->select('*')->from('sys_workspace_stage')->execute();
101 while ($stageRecord = $statement->fetch()) {
102 $update = $this->prepareStageUpdate($stageRecord);
103 if ($update !== null) {
104 $queryBuilder = $workspaceConnection->createQueryBuilder();
105 $queryBuilder->update('sys_workspace_stage')
106 ->where($queryBuilder->expr()->eq('uid', (int)$stageRecord['uid']));
107 foreach ($update as $field => $value) {
108 $queryBuilder->set($field, $queryBuilder->quote($value), false);
109 }
110 $databaseQueries[] = $queryBuilder->getSQL();
111 $queryBuilder->execute();
112 }
113 }
114
115 $this->markWizardAsDone();
116 return true;
117 }
118
119 /**
120 * Prepares SQL updates for workspace records.
121 *
122 * @param array $workspaceRecord
123 * @return array|NULL
124 */
125 protected function prepareWorkspaceUpdate(array $workspaceRecord)
126 {
127 if (empty($workspaceRecord['uid'])) {
128 return null;
129 }
130
131 $update = array();
132 $update = $this->mapSettings($workspaceRecord, $update, 'edit', 'edit');
133 $update = $this->mapSettings($workspaceRecord, $update, 'publish', 'publish');
134 $update = $this->mapSettings($workspaceRecord, $update, 'publish', 'execute');
135 return $update;
136 }
137
138 /**
139 * Prepares SQL update for stage records.
140 *
141 * @param array $stageRecord
142 * @return array|null
143 */
144 protected function prepareStageUpdate(array $stageRecord)
145 {
146 if (empty($stageRecord['uid'])) {
147 return null;
148 }
149
150 $update = array();
151 $update = $this->mapSettings($stageRecord, $update);
152 return $update;
153 }
154
155 /**
156 * Maps settings to new meaning.
157 *
158 * @param array $record
159 * @param array $update
160 * @param string $from
161 * @param string $to
162 * @return array
163 */
164 protected function mapSettings(array $record, array $update, $from = '', $to = '')
165 {
166 $fromPrefix = ($from ? $from . '_' : '');
167 $toPrefix = ($to ? $to . '_' : '');
168
169 $settings = 0;
170 // Previous setting: "Allow notification settings during stage change"
171 if ($record[$fromPrefix . 'allow_notificaton_settings']) {
172 $settings += 1;
173 }
174 // Previous setting: "All are selected per default (can be changed)"
175 if ((int)$record[$fromPrefix . 'notification_mode'] === 0) {
176 $settings += 2;
177 }
178
179 // Custom stages: preselect responsible persons (8)
180 if (isset($record['responsible_persons'])) {
181 $preselection = 8;
182 // Workspace "edit" stage: preselect members (2)
183 } elseif ($to === 'edit') {
184 $preselection = 2;
185 // Workspace "publish" stage: preselect owners (1)
186 } elseif ($to === 'publish') {
187 $preselection = 1;
188 // Workspace "execute" stage: preselect owners (1) and members (2) as default
189 } else {
190 $preselection = 1 + 2;
191 }
192
193 $update[$toPrefix . 'allow_notificaton_settings'] = $settings;
194 $update[$toPrefix . 'notification_preselection'] = $preselection;
195
196 return $update;
197 }
198 }