Commit | Line | Data |
---|---|---|
bf6a5362 CW |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
bc77d7c0 | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
bf6a5362 | 5 | | | |
bc77d7c0 TO |
6 | | This work is published under the GNU AGPLv3 license with some | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
bf6a5362 CW |
9 | +--------------------------------------------------------------------+ |
10 | */ | |
11 | ||
ff6f993e | 12 | use Civi\Core\SettingsBag; |
13 | ||
bf6a5362 CW |
14 | /** |
15 | * Base class for incremental upgrades | |
16 | */ | |
17 | class CRM_Upgrade_Incremental_Base { | |
18 | const BATCH_SIZE = 5000; | |
19 | ||
20 | /** | |
21 | * Verify DB state. | |
22 | * | |
23 | * @param $errors | |
24 | * | |
25 | * @return bool | |
26 | */ | |
27 | public function verifyPreDBstate(&$errors) { | |
28 | return TRUE; | |
29 | } | |
30 | ||
31 | /** | |
32 | * Compute any messages which should be displayed before upgrade. | |
33 | * | |
34 | * Note: This function is called iteratively for each upcoming | |
35 | * revision to the database. | |
36 | * | |
37 | * @param $preUpgradeMessage | |
38 | * @param string $rev | |
39 | * a version number, e.g. '4.8.alpha1', '4.8.beta3', '4.8.0'. | |
40 | * @param null $currentVer | |
41 | */ | |
42 | public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL) { | |
43 | } | |
44 | ||
45 | /** | |
46 | * Compute any messages which should be displayed after upgrade. | |
47 | * | |
48 | * @param string $postUpgradeMessage | |
49 | * alterable. | |
50 | * @param string $rev | |
51 | * an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs. | |
bf6a5362 CW |
52 | */ |
53 | public function setPostUpgradeMessage(&$postUpgradeMessage, $rev) { | |
54 | } | |
55 | ||
bf6a5362 CW |
56 | /** |
57 | * (Queue Task Callback) | |
54957108 | 58 | * |
59 | * @param \CRM_Queue_TaskContext $ctx | |
60 | * @param string $rev | |
61 | * | |
62 | * @return bool | |
bf6a5362 CW |
63 | */ |
64 | public static function runSql(CRM_Queue_TaskContext $ctx, $rev) { | |
65 | $upgrade = new CRM_Upgrade_Form(); | |
66 | $upgrade->processSQL($rev); | |
67 | ||
68 | return TRUE; | |
69 | } | |
70 | ||
71 | /** | |
54957108 | 72 | * Syntactic sugar for adding a task. |
73 | * | |
74 | * Task is (a) in this class and (b) has a high priority. | |
bf6a5362 CW |
75 | * |
76 | * After passing the $funcName, you can also pass parameters that will go to | |
77 | * the function. Note that all params must be serializable. | |
54957108 | 78 | * |
79 | * @param string $title | |
80 | * @param string $funcName | |
bf6a5362 CW |
81 | */ |
82 | protected function addTask($title, $funcName) { | |
be2fb01f | 83 | $queue = CRM_Queue_Service::singleton()->load([ |
bf6a5362 CW |
84 | 'type' => 'Sql', |
85 | 'name' => CRM_Upgrade_Form::QUEUE_NAME, | |
be2fb01f | 86 | ]); |
bf6a5362 CW |
87 | |
88 | $args = func_get_args(); | |
89 | $title = array_shift($args); | |
90 | $funcName = array_shift($args); | |
91 | $task = new CRM_Queue_Task( | |
be2fb01f | 92 | [get_class($this), $funcName], |
bf6a5362 CW |
93 | $args, |
94 | $title | |
95 | ); | |
be2fb01f | 96 | $queue->createItem($task, ['weight' => -1]); |
bf6a5362 CW |
97 | } |
98 | ||
058b8a5e CW |
99 | /** |
100 | * Remove a payment processor if not in use | |
101 | * | |
87a33a95 CW |
102 | * @param CRM_Queue_TaskContext $ctx |
103 | * @param string $name | |
104 | * @return bool | |
058b8a5e CW |
105 | * @throws \CiviCRM_API3_Exception |
106 | */ | |
87a33a95 | 107 | public static function removePaymentProcessorType(CRM_Queue_TaskContext $ctx, $name) { |
be2fb01f | 108 | $processors = civicrm_api3('PaymentProcessor', 'getcount', ['payment_processor_type_id' => $name]); |
058b8a5e | 109 | if (empty($processors['result'])) { |
be2fb01f | 110 | $result = civicrm_api3('PaymentProcessorType', 'get', [ |
058b8a5e CW |
111 | 'name' => $name, |
112 | 'return' => 'id', | |
be2fb01f | 113 | ]); |
058b8a5e | 114 | if (!empty($result['id'])) { |
be2fb01f | 115 | civicrm_api3('PaymentProcessorType', 'delete', ['id' => $result['id']]); |
058b8a5e CW |
116 | } |
117 | } | |
87a33a95 | 118 | return TRUE; |
058b8a5e CW |
119 | } |
120 | ||
27e82c24 SL |
121 | /** |
122 | * @param string $table_name | |
123 | * @param string $constraint_name | |
124 | * @return bool | |
125 | */ | |
126 | public static function checkFKExists($table_name, $constraint_name) { | |
127 | return CRM_Core_BAO_SchemaHandler::checkFKExists($table_name, $constraint_name); | |
128 | } | |
129 | ||
b412f764 CW |
130 | /** |
131 | * Add a column to a table if it doesn't already exist | |
132 | * | |
133 | * @param CRM_Queue_TaskContext $ctx | |
134 | * @param string $table | |
135 | * @param string $column | |
136 | * @param string $properties | |
61612722 | 137 | * @param bool $localizable is this a field that should be localized |
9f266042 | 138 | * @param string|null $version CiviCRM version to use if rebuilding multilingual schema |
139 | * | |
b412f764 CW |
140 | * @return bool |
141 | */ | |
76ee148d | 142 | public static function addColumn($ctx, $table, $column, $properties, $localizable = FALSE, $version = NULL) { |
150676ad SL |
143 | $domain = new CRM_Core_DAO_Domain(); |
144 | $domain->find(TRUE); | |
be2fb01f | 145 | $queries = []; |
ce33da5a | 146 | if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists($table, $column, FALSE)) { |
61612722 SL |
147 | if ($domain->locales) { |
148 | if ($localizable) { | |
149 | $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales); | |
150 | foreach ($locales as $locale) { | |
ce33da5a | 151 | if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists($table, "{$column}_{$locale}", FALSE)) { |
41ace555 SL |
152 | $queries[] = "ALTER TABLE `$table` ADD COLUMN `{$column}_{$locale}` $properties"; |
153 | } | |
61612722 SL |
154 | } |
155 | } | |
156 | else { | |
157 | $queries[] = "ALTER TABLE `$table` ADD COLUMN `$column` $properties"; | |
158 | } | |
159 | } | |
160 | else { | |
161 | $queries[] = "ALTER TABLE `$table` ADD COLUMN `$column` $properties"; | |
162 | } | |
163 | foreach ($queries as $query) { | |
be2fb01f | 164 | CRM_Core_DAO::executeQuery($query, [], TRUE, NULL, FALSE, FALSE); |
61612722 SL |
165 | } |
166 | } | |
150676ad SL |
167 | if ($domain->locales) { |
168 | $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales); | |
76ee148d | 169 | CRM_Core_I18n_Schema::rebuildMultilingualSchema($locales, $version, TRUE); |
150676ad | 170 | } |
b412f764 CW |
171 | return TRUE; |
172 | } | |
173 | ||
fe83c251 | 174 | /** |
175 | * Do any relevant message template updates. | |
176 | * | |
177 | * @param CRM_Queue_TaskContext $ctx | |
178 | * @param string $version | |
179 | */ | |
180 | public static function updateMessageTemplates($ctx, $version) { | |
181 | $messageTemplateObject = new CRM_Upgrade_Incremental_MessageTemplates($version); | |
182 | $messageTemplateObject->updateTemplates(); | |
183 | ||
184 | } | |
185 | ||
504770b4 | 186 | /** |
187 | * Re-save any valid values from contribute settings into the normal setting | |
188 | * format. | |
189 | * | |
190 | * We render the array of contribution_invoice_settings and any that have | |
191 | * metadata defined we add to the correct key. This is safe to run even if no | |
192 | * settings are to be converted, per the test in | |
193 | * testConvertUpgradeContributeSettings. | |
194 | * | |
195 | * @param $ctx | |
196 | * | |
197 | * @return bool | |
198 | */ | |
199 | public static function updateContributeSettings($ctx) { | |
ff6f993e | 200 | // Use a direct query as api now does some handling on this. |
201 | $settings = CRM_Core_DAO::executeQuery("SELECT value, domain_id FROM civicrm_setting WHERE name = 'contribution_invoice_settings'"); | |
202 | ||
203 | while ($settings->fetch()) { | |
204 | $contributionSettings = (array) CRM_Utils_String::unserialize($settings->value); | |
205 | foreach (array_merge(SettingsBag::getContributionInvoiceSettingKeys(), ['deferred_revenue_enabled' => 'deferred_revenue_enabled']) as $possibleKeyName => $settingName) { | |
206 | if (!empty($contributionSettings[$possibleKeyName]) && empty(Civi::settings($settings->domain_id)->getExplicit($settingName))) { | |
207 | Civi::settings($settings->domain_id)->set($settingName, $contributionSettings[$possibleKeyName]); | |
208 | } | |
209 | } | |
504770b4 | 210 | } |
211 | return TRUE; | |
212 | } | |
213 | ||
7015248a | 214 | /** |
215 | * Do any relevant smart group updates. | |
216 | * | |
217 | * @param CRM_Queue_TaskContext $ctx | |
ac241c34 | 218 | * @param array $actions |
7015248a | 219 | * |
220 | * @return bool | |
221 | */ | |
ac241c34 CW |
222 | public function updateSmartGroups($ctx, $actions) { |
223 | $groupUpdateObject = new CRM_Upgrade_Incremental_SmartGroups(); | |
224 | $groupUpdateObject->updateGroups($actions); | |
7015248a | 225 | return TRUE; |
226 | } | |
227 | ||
21ca2cb6 | 228 | /** |
229 | * Drop a column from a table if it exist. | |
230 | * | |
231 | * @param CRM_Queue_TaskContext $ctx | |
232 | * @param string $table | |
233 | * @param string $column | |
234 | * @return bool | |
235 | */ | |
236 | public static function dropColumn($ctx, $table, $column) { | |
237 | if (CRM_Core_BAO_SchemaHandler::checkIfFieldExists($table, $column)) { | |
238 | CRM_Core_DAO::executeQuery("ALTER TABLE `$table` DROP COLUMN `$column`", | |
be2fb01f | 239 | [], TRUE, NULL, FALSE, FALSE); |
21ca2cb6 | 240 | } |
241 | return TRUE; | |
242 | } | |
243 | ||
19415e64 | 244 | /** |
245 | * Add a index to a table column. | |
246 | * | |
247 | * @param CRM_Queue_TaskContext $ctx | |
248 | * @param string $table | |
b48a3167 | 249 | * @param string|array $column |
19415e64 | 250 | * @return bool |
251 | */ | |
252 | public static function addIndex($ctx, $table, $column) { | |
be2fb01f | 253 | $tables = [$table => (array) $column]; |
19415e64 | 254 | CRM_Core_BAO_SchemaHandler::createIndexes($tables); |
255 | ||
256 | return TRUE; | |
257 | } | |
258 | ||
259 | /** | |
260 | * Drop a index from a table if it exist. | |
261 | * | |
262 | * @param CRM_Queue_TaskContext $ctx | |
263 | * @param string $table | |
264 | * @param string $indexName | |
265 | * @return bool | |
266 | */ | |
267 | public static function dropIndex($ctx, $table, $indexName) { | |
268 | CRM_Core_BAO_SchemaHandler::dropIndexIfExists($table, $indexName); | |
269 | ||
270 | return TRUE; | |
271 | } | |
272 | ||
e3ed5029 TO |
273 | /** |
274 | * Drop a table... but only if it's empty. | |
275 | * | |
276 | * @param CRM_Queue_TaskContext $ctx | |
277 | * @param string $table | |
278 | * @return bool | |
279 | */ | |
280 | public static function dropTableIfEmpty($ctx, $table) { | |
281 | if (CRM_Core_DAO::checkTableExists($table)) { | |
282 | if (!CRM_Core_DAO::checkTableHasData($table)) { | |
283 | CRM_Core_BAO_SchemaHandler::dropTable($table); | |
284 | } | |
285 | else { | |
286 | $ctx->log->warning("dropTableIfEmpty($table): Found data. Preserved table."); | |
287 | } | |
288 | } | |
289 | ||
290 | return TRUE; | |
291 | } | |
292 | ||
81e30d0a SL |
293 | /** |
294 | * Rebuild Multilingual Schema. | |
295 | * @param CRM_Queue_TaskContext $ctx | |
9f266042 | 296 | * @param string|null $version CiviCRM version to use if rebuilding multilingual schema |
297 | * | |
81e30d0a SL |
298 | * @return bool |
299 | */ | |
76ee148d | 300 | public static function rebuildMultilingalSchema($ctx, $version = NULL) { |
81e30d0a SL |
301 | $domain = new CRM_Core_DAO_Domain(); |
302 | $domain->find(TRUE); | |
303 | if ($domain->locales) { | |
304 | $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales); | |
76ee148d | 305 | CRM_Core_I18n_Schema::rebuildMultilingualSchema($locales, $version); |
81e30d0a SL |
306 | } |
307 | return TRUE; | |
308 | } | |
309 | ||
bf6a5362 | 310 | } |