Merge pull request #10954 from seamuslee001/CRM-21157
[civicrm-core.git] / CRM / Upgrade / Incremental / php / FourSeven.php
CommitLineData
6cc25669
CW
1<?php
2/*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
0f03f337 6 | Copyright CiviCRM LLC (c) 2004-2017 |
6cc25669
CW
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License along with this program; if not, contact CiviCRM LLC |
21 | at info[AT]civicrm[DOT]org. If you have questions about the |
22 | GNU Affero General Public License or the licensing of CiviCRM, |
23 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
24 +--------------------------------------------------------------------+
25 */
26
27/**
bf6a5362 28 * Upgrade logic for 4.7
6cc25669 29 */
bf6a5362 30class CRM_Upgrade_Incremental_php_FourSeven extends CRM_Upgrade_Incremental_Base {
6cc25669 31
f431d51f
J
32 /**
33 * Compute any messages which should be displayed beforeupgrade.
34 *
35 * Note: This function is called iteratively for each upcoming
36 * revision to the database.
37 *
3bdf1f3a 38 * @param string $preUpgradeMessage
f431d51f
J
39 * @param string $rev
40 * a version number, e.g. '4.4.alpha1', '4.4.beta3', '4.4.0'.
41 * @param null $currentVer
f431d51f
J
42 */
43 public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL) {
44 if ($rev == '4.7.alpha1') {
f431d51f
J
45 // CRM-16478 Remove custom fatal error template path option
46 $config = CRM_Core_Config::singleton();
18b3bef6 47 if (!empty($config->fatalErrorTemplate) && $config->fatalErrorTemplate != 'CRM/common/fatal.tpl') {
f431d51f
J
48 $preUpgradeMessage .= '<p>' . ts('The custom fatal error template setting will be removed during the upgrade. You are currently using this custom template: %1 . Following the upgrade you will need to use the standard approach to overriding template files, as described in the documentation.', array(1 => $config->fatalErrorTemplate)) . '</p>';
49 }
f431d51f 50 }
a40fd1ac
CW
51 if ($rev == '4.7.alpha4') {
52 // CRM-17004 Warn of Moneris removal
87a33a95
CW
53 $count = 1;
54 // Query only works in 4.3+
55 if (version_compare($currentVer, "4.3.0") > 0) {
56 $count = CRM_Core_DAO::singleValueQuery("SELECT COUNT(id) FROM civicrm_payment_processor WHERE payment_processor_type_id IN (SELECT id FROM civicrm_payment_processor_type WHERE name = 'Moneris')");
57 }
58 if ($count && !function_exists('moneris_civicrm_managed')) {
a40fd1ac
CW
59 $preUpgradeMessage .= '<p>' . ts('The %1 payment processor is no longer bundled with CiviCRM. After upgrading you will need to install the extension to continue using it.', array(1 => 'Moneris')) . '</p>';
60 }
61 }
b9446a4c 62 if ($rev == '4.7.13') {
4b9e9cda
SL
63 $preUpgradeMessage .= '<p>' . ts('A new permission has been added called %1 This Permission is now used to control access to the Manage Tags screen', array(1 => 'manage tags')) . '</p>';
64 }
17511f38
TO
65 if ($rev == '4.7.22') {
66 // Based on support inquiries for 4.7.21, show message during 4.7.22.
67 // For affected users, this issue prevents loading the regular status screen.
68 if (!$this->checkImageUploadDir()) {
69 $preUpgradeMessage .= '<p>' . ts('There appears to be an inconsistency in the configuration of "Image Upload URL" and "Image Upload Directory".') . '</p>'
70 . '<p>'
71 . ts('Further advice will be displayed at the end of the upgrade.')
72 . '</p>';
73 }
74 }
f431d51f
J
75 }
76
6cc25669
CW
77 /**
78 * Compute any messages which should be displayed after upgrade.
79 *
80 * @param string $postUpgradeMessage
81 * alterable.
82 * @param string $rev
83 * an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs.
6cc25669
CW
84 */
85 public function setPostUpgradeMessage(&$postUpgradeMessage, $rev) {
6dbe2c23
CW
86 if ($rev == '4.7.alpha1') {
87 $config = CRM_Core_Config::singleton();
bf6a5362 88 // FIXME: Performing an upgrade step during postUpgrade message phase is probably bad
6dbe2c23
CW
89 $editor_id = self::updateWysiwyg();
90 $msg = NULL;
91 $ext_href = 'href="' . CRM_Utils_System::url('civicrm/admin/extensions', 'reset=1') . '"';
92 $dsp_href = 'href="' . CRM_Utils_System::url('civicrm/admin/setting/preferences/display', 'reset=1') . '"';
93 $blog_href = 'href="https://civicrm.org/blogs/colemanw/big-changes-wysiwyg-editing-47"';
94 switch ($editor_id) {
95 // TinyMCE
96 case 1:
97 $msg = ts('Your configured editor "TinyMCE" is no longer part of the main CiviCRM download. To continue using it, visit the <a %1>Manage Extensions</a> page to download and install the TinyMCE extension.', array(1 => $ext_href));
98 break;
99
100 // Drupal/Joomla editor
101 case 3:
102 case 4:
103 $msg = ts('CiviCRM no longer integrates with the "%1 Default Editor." Your wysiwyg setting has been reset to the built-in CKEditor. <a %2>Learn more...</a>', array(1 => $config->userFramework, 2 => $blog_href));
104 break;
105 }
106 if ($msg) {
107 $postUpgradeMessage .= '<p>' . $msg . '</p>';
108 }
109 $postUpgradeMessage .= '<p>' . ts('CiviCRM now includes the easy-to-use CKEditor Configurator. To customize the features and display of your wysiwyg editor, visit the <a %1>Display Preferences</a> page. <a %2>Learn more...</a>', array(1 => $dsp_href, 2 => $blog_href)) . '</p>';
dd55005c 110
111 $postUpgradeMessage .= '<br /><br />' . ts('Default version of the following System Workflow Message Templates have been modified: <ul><li>Personal Campaign Pages - Owner Notification</li></ul> If you have modified these templates, please review the new default versions and implement updates as needed to your copies (Administer > Communications > Message Templates > System Workflow Messages).');
f431d51f
J
112
113 $postUpgradeMessage .= '<p>' . ts('The custom fatal error template setting has been removed.') . '</p>';
6dbe2c23 114 }
a742ee50
TO
115 //if ($rev == '4.7.11') {
116 // $postUpgradeMessage .= '<br /><br />' . ts("WARNING: For increased security, profile submissions embedded in remote sites are no longer allowed to create or edit data by default. If you need to allow users to submit profiles from external sites, you can restore this at Administer > System Settings > Misc (Undelete, PDFs, Limits, Logging, Captcha, etc.) > 'Accept profile submissions from external sites'");
117 //}
11769bd1 118 if ($rev == '4.7.11') {
9867e465 119 $postUpgradeMessage .= '<br /><br />' . ts("By default, CiviCRM now disables the ability to import directly from SQL. To use this feature, you must explicitly grant permission 'import SQL datasource'.");
11769bd1 120 }
c7c54ade
CW
121 if ($rev == '4.7.14') {
122 $ck_href = 'href="' . CRM_Utils_System::url('civicrm/admin/ckeditor') . '"';
123 $postUpgradeMessage .= '<p>' . ts('CiviMail no longer forces CKEditor to add html/head/body tags to email content because some sites place these in the message header/footer. This was added in 4.7.5 and is now disabled by default.')
3444e690 124 . '<br />' . ts('You can re-enable it by visiting the <a %1>CKEditor Config</a> screen and setting "fullPage = true" under the Advanced Options of the CiviMail preset.', array(1 => $ck_href))
c7c54ade
CW
125 . '</p>';
126 }
c4aa623c 127 if ($rev == '4.7.19') {
7dffc2a7 128 $postUpgradeMessage .= '<br /><br />' . ts('Default version of the following System Workflow Message Templates have been modified: <ul><li>Additional Payment Receipt or Refund Notification</li><li>Contribution Invoice</li></ul> If you have modified these templates, please review the new default versions and implement updates as needed to your copies (Administer > Communications > Message Templates > System Workflow Messages).');
eca6c81c
SL
129 $check = CRM_Core_DAO::singleValueQuery("SELECT count(id) FROM civicrm_domain");
130 $smsCheck = CRM_Core_DAO::singleValueQuery("SELECT count(id) FROM civicrm_sms_provider");
131 if ($check > 1 && (bool) $smsCheck) {
132 $postUpgradeMessage .= '<p>civicrm_sms_provider ' . ts('has now had a domain id column added. As there is more than 1 domains in this install you need to manually set the domain id for the providers in this install') . '</p>';
133 }
c4aa623c 134 }
17511f38
TO
135 if ($rev == '4.7.22') {
136 // Based on support inquiries for 4.7.21, show message during 4.7.22.
137 // For affected users, this issue prevents loading the regular status screen.
138 if (!$this->checkImageUploadDir()) {
139 $config = CRM_Core_Config::singleton();
140 $postUpgradeMessage .=
141 '<h3>' . ts('Warning') . '</h3>'
142 . '<p>' . ts('There appears to be an inconsistency in the configuration of "Image Upload URL" and "Image Upload Directory".') . '</p>'
143 . sprintf("<ul><li><b>imageUploadDir</b>: <code>%s</code></li><li><b>imageUploadURL</b>: <code>%s</code></li></ul>", htmlentities($config->imageUploadDir), htmlentities($config->imageUploadURL))
144 . '<p>'
145 . ts('You may need to check that: <ul><li>(a) the path and URL match,</li><li> (b) the httpd/htaccess policy allows requests for files inside this folder,</li><li>and (c) the web domain matches the normal web domain.</ul>')
146 . '</p>'
147 . '<p><em>'
148 . ts('(Note: Although files should be readable, it is best if they are not listable or browseable.)')
149 . '</em></p>'
150 . '<p>'
151 . ts('If this remains unresolved, then some important screens may fail to load.')
152 . '</p>';
153 }
154 }
a058f8a1 155 if ($rev == '4.7.23') {
9cad3ff4
CW
156 $postUpgradeMessage .= '<br /><br />' . ts('Default version of the following System Workflow Message Templates have been modified: <ul><li>Contribution Invoice</li></ul> If you have modified these templates, please review the new default versions and implement updates as needed to your copies (Administer > Communications > Message Templates > System Workflow Messages).');
157 }
6cc25669
CW
158 }
159
6cc25669
CW
160 /**
161 * Upgrade function.
162 *
163 * @param string $rev
164 */
165 public function upgrade_4_7_alpha1($rev) {
8c748d50 166 $this->addTask('Drop action scheudle mapping foreign key', 'dropActionScheudleMappingForeignKey');
b604d7ec 167 $this->addTask('Migrate \'on behalf of\' information to module_data', 'migrateOnBehalfOfInfo');
bf6a5362 168 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
f806379b 169 $this->addTask(ts('Migrate Settings to %1', array(1 => $rev)), 'migrateSettings', $rev);
b604d7ec 170 $this->addTask('Add Getting Started dashlet', 'addGettingStartedDashlet', $rev);
a40fd1ac
CW
171 }
172
173 /**
174 * Upgrade function.
175 *
176 * @param string $rev
177 */
178 public function upgrade_4_7_alpha4($rev) {
179 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
058b8a5e 180 $this->addTask(ts('Remove %1', array(1 => 'Moneris')), 'removePaymentProcessorType', 'Moneris');
b2222b9f 181 $this->addTask('Update Smart Groups', 'fixContactTypeInSmartGroups');
6cc25669
CW
182 }
183
0094ac08
CW
184 /**
185 * Upgrade function.
186 *
187 * @param string $rev
188 */
189 public function upgrade_4_7_beta2($rev) {
190 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
191 $this->addTask('Delete unused file', 'deleteVersionCheckCacheFile');
192 }
193
fb1f3850
DRJ
194 /**
195 * Upgrade function.
196 *
197 * @param string $rev
198 */
902e557f 199 public function upgrade_4_7_beta6($rev) {
13599400 200 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
fb1f3850 201 $this->addTask('Disable flexible jobs extension', 'disableFlexibleJobsExtension');
20d5377e 202 $this->addTask('Add Index to financial_trxn trxn_id field', 'addIndexFinancialTrxnTrxnID');
fb1f3850
DRJ
203 }
204
8ca47f5c 205 /**
206 * Upgrade function.
207 *
208 * @param string $rev
209 */
210 public function upgrade_4_7_1($rev) {
2af0b023 211 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
8ca47f5c 212 $this->addTask('Add Index to civicrm_contribution creditnote_id field', 'addIndexContributionCreditNoteID');
213 }
214
2179c899 215 /**
216 * Upgrade function.
217 *
218 * @param string $rev
219 */
220 public function upgrade_4_7_2($rev) {
2af0b023 221 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
2179c899 222 $this->addTask('Fix Index on civicrm_financial_item combined entity_id + entity_table', 'addCombinedIndexFinancialItemEntityIDEntityType');
1f395432 223 $this->addTask('enable financial account relationships for chargeback & refund', 'addRefundAndChargeBackAccountsIfNotExist');
3fe26f4c 224 $this->addTask('Add Index to civicrm_contribution.source', 'addIndexContributionSource');
2179c899 225 }
226
fd28b6a0 227 /**
228 * Upgrade function.
229 *
230 * @param string $rev
231 */
232 public function upgrade_4_7_3($rev) {
2af0b023 233 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
fd28b6a0 234 $this->addTask('Add Index to civicrm_contribution.total_amount', 'addIndexContributionAmount');
235 }
236
6eb752fa 237 /**
238 * Upgrade function.
239 *
240 * @param string $rev
241 */
242 public function upgrade_4_7_4($rev) {
2af0b023 243 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
6eb752fa 244 $this->addTask('Add Contact Deleted by Merge Activity Type', 'addDeletedByMergeActivityType');
245 }
246
2cbdd085
J
247 /**
248 * Upgrade function.
249 *
250 * @param string $rev
251 */
6a2d3987 252 public function upgrade_4_7_7($rev) {
2cbdd085 253 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
6a2d3987
J
254 // https://issues.civicrm.org/jira/browse/CRM-18006
255 if (CRM_Core_DAO::checkTableExists('civicrm_install_canary')) {
256 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_install_canary ENGINE=InnoDB');
257 }
2cbdd085
J
258 }
259
2af0b023
CW
260 /**
261 * Upgrade function.
262 *
263 * @param string $rev
264 */
6a2d3987 265 public function upgrade_4_7_8($rev) {
2af0b023 266 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
6a2d3987 267 $this->addTask('Upgrade mailing foreign key constraints', 'upgradeMailingFKs');
065ffec9
TO
268 }
269
da1ecd73
SL
270 /**
271 * Upgrade function.
272 *
273 * @param string $rev
274 */
e8a4535e 275 public function upgrade_4_7_10($rev) {
da1ecd73 276 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
b5095b43
CW
277 $this->addTask('Upgrade Add Help Pre and Post Fields to price value table', 'addHelpPreAndHelpPostFieldsPriceFieldValue');
278 $this->addTask('Alter index and type for image URL', 'alterIndexAndTypeForImageURL');
da1ecd73
SL
279 }
280
00c27b41
CW
281 /**
282 * Upgrade function.
283 *
284 * @param string $rev
285 */
286 public function upgrade_4_7_11($rev) {
287 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
288 $this->addTask('Dashboard schema updates', 'dashboardSchemaUpdate');
b5095b43 289 $this->addTask('Fill in setting "remote_profile_submissions"', 'migrateRemoteSubmissionsSetting');
00c27b41
CW
290 }
291
7c61320c
SL
292 /**
293 * Upgrade function.
294 *
295 * @param string $rev
296 */
297 public function upgrade_4_7_12($rev) {
298 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
b5095b43 299 $this->addTask('Add Data Type column to civicrm_option_group', 'addDataTypeColumnToOptionGroupTable');
7c61320c 300 }
cb5962bd
SL
301 /**
302 * Upgrade function.
303 *
304 * @param string $rev
305 */
306 public function upgrade_4_7_13($rev) {
307 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
6846f088
CW
308 $this->addTask('CRM-19372 - Add column to allow for payment processors to set what card types are accepted', 'addColumn',
309 'civicrm_payment_processor', 'accepted_credit_cards', "text DEFAULT NULL COMMENT 'array of accepted credit card types'");
cb5962bd
SL
310 }
311
7ad5ae6a
CW
312 /**
313 * Upgrade function.
314 *
315 * @param string $rev
316 */
317 public function upgrade_4_7_14($rev) {
318 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
319 $this->addTask('Add WYSIWYG Editor Presets', 'addWysiwygPresets');
320 }
7c61320c 321
b412f764
CW
322 /**
323 * Upgrade function.
324 *
325 * @param string $rev
326 */
327 public function upgrade_4_7_15($rev) {
6846f088
CW
328 $this->addTask('CRM-19626 - Add min_amount column to civicrm_price_set', 'addColumn',
329 'civicrm_price_set', 'min_amount', "INT(10) UNSIGNED DEFAULT '0' COMMENT 'Minimum Amount required for this set.'");
b412f764
CW
330 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
331 }
332
703875d8
TO
333 /**
334 * Upgrade function.
335 *
336 * @param string $rev
337 */
338 public function upgrade_4_7_16($rev) {
73c5338d
CW
339 $this->addTask('CRM-19723 - Add icon column to civicrm_option_value', 'addColumn',
340 'civicrm_option_value', 'icon', "varchar(255) COMMENT 'crm-i icon class' DEFAULT NULL");
341 $this->addTask('CRM-19769 - Add color column to civicrm_tag', 'addColumn',
342 'civicrm_tag', 'color', "varchar(255) COMMENT 'Hex color value e.g. #ffffff' DEFAULT NULL");
343 $this->addTask('CRM-19779 - Add color column to civicrm_option_value', 'addColumn',
344 'civicrm_option_value', 'color', "varchar(255) COMMENT 'Hex color value e.g. #ffffff' DEFAULT NULL");
703875d8 345 $this->addTask('Add new CiviMail fields', 'addMailingTemplateType');
cd063b10
CW
346 $this->addTask('CRM-19770 - Add is_star column to civicrm_activity', 'addColumn',
347 'civicrm_activity', 'is_star', "tinyint DEFAULT '0' COMMENT 'Activity marked as favorite.'");
73c5338d 348 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
703875d8
TO
349 }
350
36610486 351 /**
352 * Upgrade function.
353 *
354 * @param string $rev
355 */
356 public function upgrade_4_7_18($rev) {
357 $this->addTask('Update Kenyan Provinces', 'updateKenyanProvinces');
358 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
359 }
360
8712faa9
PN
361 /**
362 * Upgrade function.
363 *
364 * @param string $rev
365 */
366 public function upgrade_4_7_19($rev) {
040073c9
CW
367 if (CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_financial_account', 'opening_balance')) {
368 $query = "SELECT id FROM civicrm_financial_account WHERE opening_balance <> 0 OR current_period_opening_balance <> 0";
369 $result = CRM_Core_DAO::executeQuery($query);
370 if (!$result->N) {
371 $this->addTask('Drop Column current_period_opening_balance From civicrm_financial_account table.', 'dropColumn', 'civicrm_financial_account', 'current_period_opening_balance');
372 $this->addTask('Drop Column opening_balance From civicrm_financial_account table.', 'dropColumn', 'civicrm_financial_account', 'opening_balance');
373 }
8712faa9 374 }
4eae8dda 375 $this->addTask('CRM-19961 - Add domain_id column to civicrm_sms_provider', 'addColumn',
61612722 376 'civicrm_sms_provider', 'domain_id', "int(10) unsigned COMMENT 'Which Domain is this sms provier for'");
4eae8dda 377 $this->addTask('CRM-19961 - Populate domain id table and perhaps add foreign key', 'populateSMSProviderDomainId');
8712faa9 378 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
ccfd6962 379 $this->addTask('CRM-16633 - Add "Change Case Subject" activity', 'addChangeCaseSubjectActivityType');
460931ca
JP
380 $this->addTask('Add is_public column to civicrm_custom_group', 'addColumn',
381 'civicrm_custom_group', 'is_public', "boolean DEFAULT '1' COMMENT 'Is this property public?'");
8712faa9
PN
382 }
383
6f0dad97
SL
384 /**
385 * Upgrade function.
386 *
387 * @param string $rev
388 */
389 public function upgrade_4_7_20($rev) {
390 $this->addtask('Fix Schema on civicrm_action_schedule', 'fixSchemaOnCiviCRMActionSchedule');
391 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
040073c9
CW
392 $this->addTask('Add activity_status column to civicrm_mail_settings', 'addColumn',
393 'civicrm_mail_settings', 'activity_status', "varchar (255) DEFAULT NULL COMMENT 'Name of status to use when creating email to activity.'");
6f0dad97
SL
394 }
395
9cad3ff4
CW
396 /**
397 * Upgrade function.
398 *
399 * @param string $rev
400 */
a058f8a1 401 public function upgrade_4_7_23($rev) {
9cad3ff4
CW
402 $this->addTask('CRM-20387 - Add invoice_number column to civicrm_contribution', 'addColumn',
403 'civicrm_contribution', 'invoice_number', "varchar(255) COMMENT 'Human readable invoice number' DEFAULT NULL");
404 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
405 }
406
e87b39f4
SL
407 /**
408 * Upgrade function.
409 *
410 * @param string $rev
411 */
412 public function upgrade_4_7_25($rev) {
07683c33 413 $this->addTask("CRM-20927 - Add column to 'civicrm_menu' for additional metadata", 'addColumn',
e87b39f4 414 'civicrm_menu', 'module_data', "text COMMENT 'All other menu metadata not stored in other fields'");
58e9d364 415 $this->addTask('CRM-21052 - Determine activity revision policy', 'pickActivityRevisionPolicy');
e87b39f4 416 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
41ace555
SL
417 $this->addTask('Add cancel button text column to civicrm_uf_group', 'addColumn',
418 'civicrm_uf_group', 'cancel_button_text', "varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Custom Text to display on the cancel button when used in create or edit mode'", TRUE);
419 $this->addTask('Add Submit button text column to civicrm_uf_group', 'addColumn',
420 'civicrm_uf_group', 'submit_button_text', "varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Custom Text to display on the submit button on profile edit/create screens'", TRUE);
f6cecca8
TO
421
422 $this->addTask('CRM-20958 - Add created_date to civicrm_activity', 'addColumn',
423 'civicrm_activity', 'created_date', "timestamp NULL DEFAULT NULL COMMENT 'When was the activity was created.'");
424 $this->addTask('CRM-20958 - Add modified_date to civicrm_activity', 'addColumn',
425 'civicrm_activity', 'modified_date', "timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'When was the activity (or closely related entity) was created or modified or deleted.'");
426 $this->addTask('CRM-20958 - Add created_date to civicrm_case', 'addColumn',
427 'civicrm_case', 'created_date', "timestamp NULL DEFAULT NULL COMMENT 'When was the case was created.'");
428 $this->addTask('CRM-20958 - Add modified_date to civicrm_case', 'addColumn',
429 'civicrm_case', 'modified_date', "timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'When was the case (or closely related entity) was created or modified or deleted.'");
e87b39f4
SL
430 }
431
432
2af0b023 433 /*
2cbdbcef 434 * Important! All upgrade functions MUST add a 'runSql' task.
2af0b023
CW
435 * Uncomment and use the following template for a new upgrade version
436 * (change the x in the function name):
437 */
438
439 // /**
440 // * Upgrade function.
441 // *
442 // * @param string $rev
443 // */
444 // public function upgrade_4_7_x($rev) {
445 // $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
446 // // Additional tasks here...
b5095b43
CW
447 // // Note: do not use ts() in the addTask description because it adds unnecessary strings to transifex.
448 // // The above is an exception because 'Upgrade DB to %1: SQL' is generic & reusable.
2af0b023
CW
449 // }
450
6cc25669
CW
451 /**
452 * CRM-16354
453 *
6dbe2c23 454 * @return int
6cc25669 455 */
6dbe2c23 456 public static function updateWysiwyg() {
aaffa79f 457 $editorID = Civi::settings()->get('editor_id');
6dbe2c23
CW
458 // Previously a numeric value indicated one of 4 wysiwyg editors shipped in core, and no value indicated 'Textarea'
459 // Now the options are "Textarea", "CKEditor", and the rest have been dropped from core.
460 $newEditor = $editorID ? "CKEditor" : "Textarea";
08ef4ddd 461 Civi::settings()->set('editor_id', $newEditor);
6cc25669 462
6dbe2c23 463 return $editorID;
6cc25669
CW
464 }
465
f806379b
TO
466 /**
467 * Migrate any last remaining options from `civicrm_domain.config_backend` to `civicrm_setting`.
468 * Cleanup setting schema.
469 *
470 * @param CRM_Queue_TaskContext $ctx
471 * @return bool
472 */
5c9edd99 473 public static function migrateSettings(CRM_Queue_TaskContext $ctx) {
4cc9e637
TO
474 // Tip: If there are problems with adding the new uniqueness index, try inspecting:
475 // SELECT name, domain_id, contact_id, count(*) AS dupes FROM civicrm_setting cs GROUP BY name, domain_id, contact_id HAVING dupes > 1;
476
477 // Nav records are expendable. https://forum.civicrm.org/index.php?topic=36933.0
478 CRM_Core_DAO::executeQuery('DELETE FROM civicrm_setting WHERE contact_id IS NOT NULL AND name = "navigation"');
3ddd2901 479
726e6261
SL
480 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_setting DROP INDEX index_group_name');
481 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_setting DROP COLUMN group_name');
482
3ddd2901
SL
483 // Handle Strange activity_tab_filter settings.
484 CRM_Core_DAO::executeQuery('CREATE TABLE civicrm_activity_setting LIKE civicrm_setting');
726e6261 485 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_activity_setting ADD UNIQUE INDEX index_domain_contact_name (domain_id, contact_id, name)');
3ddd2901 486 CRM_Core_DAO::executeQuery('INSERT INTO civicrm_activity_setting (name, contact_id, domain_id, value)
726e6261 487 SELECT DISTINCT name, contact_id, domain_id, value
3ddd2901
SL
488 FROM civicrm_setting
489 WHERE name = "activity_tab_filter"
490 AND value is not NULL');
ee4d8422 491 CRM_Core_DAO::executeQuery('DELETE FROM civicrm_setting WHERE name = "activity_tab_filter"');
4cc9e637 492
e6a2c901 493 $date = CRM_Utils_Time::getTime('Y-m-d H:i:s');
f806379b 494 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_setting ADD UNIQUE INDEX index_domain_contact_name (domain_id, contact_id, name)');
e6a2c901
SL
495 CRM_Core_DAO::executeQuery("INSERT INTO civicrm_setting (name, contact_id, domain_id, value, is_domain, created_id, created_date)
496 SELECT name, contact_id, domain_id, value, 0, contact_id,'$date'
3ddd2901 497 FROM civicrm_activity_setting
e6a2c901
SL
498 WHERE name = 'activity_tab_filter'
499 AND value is not NULL"
d09d52ce 500 );
3ddd2901 501 CRM_Core_DAO::executeQuery('DROP TABLE civicrm_activity_setting');
f806379b
TO
502
503 $domainDao = CRM_Core_DAO::executeQuery('SELECT id, config_backend FROM civicrm_domain');
504 while ($domainDao->fetch()) {
505 $settings = CRM_Upgrade_Incremental_php_FourSeven::convertBackendToSettings($domainDao->id, $domainDao->config_backend);
506 CRM_Core_Error::debug_var('convertBackendToSettings', array(
507 'domainId' => $domainDao->id,
508 'backend' => $domainDao->config_backend,
509 'settings' => $settings,
510 ));
511
512 foreach ($settings as $name => $value) {
513 $rowParams = array(
514 1 => array($domainDao->id, 'Positive'),
515 2 => array($name, 'String'),
516 3 => array(serialize($value), 'String'),
517 );
518 $settingId = CRM_Core_DAO::singleValueQuery(
519 'SELECT id FROM civicrm_setting WHERE domain_id = %1 AND name = %2',
520 $rowParams);
521 if (!$settingId) {
522 CRM_Core_DAO::executeQuery(
523 'INSERT INTO civicrm_setting (domain_id, name, value, is_domain) VALUES (%1,%2,%3,1)',
524 $rowParams);
525 }
526 }
527 }
528
9e726168 529 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_domain DROP COLUMN config_backend');
f806379b
TO
530
531 return TRUE;
532 }
533
534 /**
535 * Take a config_backend blob and produce an equivalent list of settings.
536 *
537 * @param int $domainId
538 * Domain ID.
539 * @param string $config_backend
540 * Serialized blob.
541 * @return array
542 */
543 public static function convertBackendToSettings($domainId, $config_backend) {
544 if (!$config_backend) {
545 return array();
546 }
547
548 $backend = unserialize($config_backend);
549 if (!$backend) {
550 return array();
551 }
552
553 $mappings = \CRM_Core_Config_MagicMerge::getPropertyMap();
554 $settings = array();
555 foreach ($backend as $propertyName => $propertyValue) {
556 if (isset($mappings[$propertyName][0]) && preg_match('/^setting/', $mappings[$propertyName][0])) {
557 // $mapping format: $propertyName => Array(0 => $type, 1 => $setting|NULL).
558 $settingName = isset($mappings[$propertyName][1]) ? $mappings[$propertyName][1] : $propertyName;
559 $settings[$settingName] = $propertyValue;
560 }
561 }
562
563 return $settings;
564 }
565
0a95c936 566 /**
567 * Add Getting Started dashlet to dashboard
568 *
569 * @param \CRM_Queue_TaskContext $ctx
570 *
571 * @return bool
572 */
5c9edd99 573 public static function addGettingStartedDashlet(CRM_Queue_TaskContext $ctx) {
9c4a04f2 574 $sql = "SELECT count(*) FROM civicrm_dashboard WHERE name='getting-started'";
e1674273 575 $res = CRM_Core_DAO::singleValueQuery($sql);
576 $domainId = CRM_Core_Config::domainID();
577 if ($res <= 0) {
578 $sql = "INSERT INTO `civicrm_dashboard`
a8b704c5 579 ( `domain_id`, `name`, `label`, `url`, `permission`, `permission_operator`, `column_no`, `is_minimized`, `is_active`, `weight`, `fullscreen_url`, `is_fullscreen`, `is_reserved`) VALUES ( {$domainId}, 'getting-started', 'Getting Started', 'civicrm/dashlet/getting-started?reset=1&snippet=5', 'access CiviCRM', NULL, 0, 0, 1, 0, 'civicrm/dashlet/getting-started?reset=1&snippet=5&context=dashletFullscreen', 1, 1)";
e1674273 580 CRM_Core_DAO::executeQuery($sql);
581 // Add default position for Getting Started Dashlet ( left column)
582 $sql = "INSERT INTO `civicrm_dashboard_contact` (dashboard_id, contact_id, column_no, is_active)
583SELECT (SELECT MAX(id) FROM `civicrm_dashboard`), contact_id, 0, IF (SUM(is_active) > 0, 1, 0)
429da6a1 584FROM `civicrm_dashboard_contact` JOIN `civicrm_contact` WHERE civicrm_dashboard_contact.contact_id = civicrm_contact.id GROUP BY contact_id";
e1674273 585 CRM_Core_DAO::executeQuery($sql);
586 }
0a95c936 587 return TRUE;
e1674273 588 }
4175ee03 589
6b1e1a2c 590 /**
591 * Migrate on-behalf information to uf_join.module_data as on-behalf columns will be dropped
592 * on DB upgrade
593 *
594 * @param CRM_Queue_TaskContext $ctx
595 *
596 * @return bool
597 * TRUE for success
598 */
599 public static function migrateOnBehalfOfInfo(CRM_Queue_TaskContext $ctx) {
d3e92c88 600 $domain = new CRM_Core_DAO_Domain();
601 $domain->find(TRUE);
6b1e1a2c 602
d3e92c88 603 // fetch onBehalf entry in UFJoin table
6b1e1a2c 604 $ufGroupDAO = new CRM_Core_DAO_UFJoin();
605 $ufGroupDAO->module = 'OnBehalf';
606 $ufGroupDAO->find(TRUE);
607
f635ab77 608 $forOrgColums = array('is_for_organization');
d3e92c88 609 if ($domain->locales) {
610 $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);
611 foreach ($locales as $locale) {
612 $forOrgColums[] = "for_organization_{$locale}";
613 }
614 }
615 else {
616 $forOrgColums[] = "for_organization";
617 }
618
619 $query = "
620 SELECT " . implode(", ", $forOrgColums) . ", uj.id as join_id, uj.uf_group_id as uf_group_id
621 FROM civicrm_contribution_page cp
622 INNER JOIN civicrm_uf_join uj ON uj.entity_id = cp.id AND uj.module = 'OnBehalf'";
623 $dao = CRM_Core_DAO::executeQuery($query, array(), TRUE, NULL, FALSE, FALSE);
6b1e1a2c 624
625 if ($dao->N) {
6b1e1a2c 626 while ($dao->fetch()) {
627 $onBehalfParams['on_behalf'] = array('is_for_organization' => $dao->is_for_organization);
628 if ($domain->locales) {
6b1e1a2c 629 foreach ($locales as $locale) {
630 $for_organization = "for_organization_{$locale}";
631 $onBehalfParams['on_behalf'] += array(
632 $locale => array(
633 'for_organization' => $dao->$for_organization,
634 ),
635 );
636 }
637 }
638 else {
639 $onBehalfParams['on_behalf'] += array(
640 'default' => array(
641 'for_organization' => $dao->for_organization,
642 ),
643 );
644 }
645 $ufJoinParam = array(
646 'id' => $dao->join_id,
647 'module' => 'on_behalf',
d3e92c88 648 'uf_group_id' => $dao->uf_group_id,
6b1e1a2c 649 'module_data' => json_encode($onBehalfParams),
650 );
651 CRM_Core_BAO_UFJoin::create($ufJoinParam);
652 }
653 }
654
655 return TRUE;
9e42a501
TO
656 }
657
658 /**
659 * v4.7.11 adds a new setting "remote_profile_submissions". This is
660 * long-standing feature that existing sites may be using; however, it's
661 * a bit prone to abuse. For new sites, the default is to disable it
662 * (since that is more secure). For existing sites, the default is to
663 * enable it (since that is more compatible).
664 *
665 * @param \CRM_Queue_TaskContext $ctx
666 *
667 * @return bool
668 */
5c9edd99 669 public static function migrateRemoteSubmissionsSetting(CRM_Queue_TaskContext $ctx) {
9e42a501
TO
670 $domains = CRM_Core_DAO::executeQuery("SELECT DISTINCT d.id FROM civicrm_domain d LEFT JOIN civicrm_setting s ON d.id=s.domain_id AND s.name = 'remote_profile_submissions' WHERE s.id IS NULL");
671 while ($domains->fetch()) {
672 CRM_Core_DAO::executeQuery(
673 "INSERT INTO civicrm_setting (`name`, `value`, `domain_id`, `is_domain`, `contact_id`, `component_id`, `created_date`, `created_id`)
674 VALUES (%2, %3, %4, %5, NULL, NULL, %6, NULL)",
675 array(
676 2 => array('remote_profile_submissions', 'String'),
677 3 => array('s:1:"1";', 'String'),
678 4 => array($domains->id, 'Integer'),
679 5 => array(1, 'Integer'),
680 6 => array(date('Y-m-d H:i:s'), 'String'),
681 )
682 );
683 }
684 return TRUE;
6b1e1a2c 685 }
cb804cd9 686
b2222b9f
CW
687 /**
688 * CRM-11782 - Get rid of VALUE_SEPARATOR character in saved search form values
689 *
690 * @param \CRM_Queue_TaskContext $ctx
691 *
692 * @return bool
693 */
5c9edd99 694 public static function fixContactTypeInSmartGroups(CRM_Queue_TaskContext $ctx) {
b2222b9f
CW
695 $sep = CRM_Core_DAO::VALUE_SEPARATOR;
696 $dao = CRM_Core_DAO::executeQuery("SELECT id, form_values FROM civicrm_saved_search WHERE form_values LIKE '%$sep%'");
697 while ($dao->fetch()) {
698 $formValues = unserialize($dao->form_values);
699 if (isset($formValues['contact_type']) && is_array($formValues['contact_type'])) {
700 $newVals = array();
701 foreach ($formValues['contact_type'] as $key => $val) {
702 $newVals[str_replace($sep, '__', $key)] = is_string($val) ? str_replace($sep, '__', $val) : $val;
703 }
704 $formValues['contact_type'] = $newVals;
705 }
706 CRM_Core_DAO::executeQuery("UPDATE civicrm_saved_search SET form_values = %1 WHERE id = {$dao->id}", array(1 => array(serialize($formValues), 'String')));
707 }
708
709 return TRUE;
710 }
711
0094ac08
CW
712 /**
713 * CRM-17637 - Ths file location has been moved; delete the old one
714 *
715 * @param \CRM_Queue_TaskContext $ctx
716 *
717 * @return bool
718 */
5c9edd99 719 public static function deleteVersionCheckCacheFile(CRM_Queue_TaskContext $ctx) {
0094ac08
CW
720 $config = CRM_Core_Config::singleton();
721 $cacheFile = $config->uploadDir . 'version-info-cache.json';
722 if (file_exists($cacheFile)) {
723 unlink($cacheFile);
724 }
725 return TRUE;
726 }
727
fb1f3850
DRJ
728 /**
729 * CRM-17669 and CRM-17686, make scheduled jobs more flexible, disable the 4.6 extension if installed
730 *
731 * @param \CRM_Queue_TaskContext $ctx
732 *
733 * @return bool
734 */
5c9edd99 735 public static function disableFlexibleJobsExtension(CRM_Queue_TaskContext $ctx) {
d357221c
DRJ
736 try {
737 civicrm_api3('Extension', 'disable', array('key' => 'com.klangsoft.flexiblejobs'));
738 }
739 catch (CiviCRM_API3_Exception $e) {
740 // just ignore if the extension isn't installed
741 }
fb1f3850
DRJ
742
743 return TRUE;
744 }
745
20d5377e 746 /**
747 * CRM-17752 add index to civicrm_financial_trxn.trxn_id (deliberately non-unique).
748 *
749 * @param \CRM_Queue_TaskContext $ctx
750 *
751 * @return bool
752 */
5c9edd99 753 public static function addIndexFinancialTrxnTrxnID(CRM_Queue_TaskContext $ctx) {
20d5377e 754 $tables = array('civicrm_financial_trxn' => array('trxn_id'));
755 CRM_Core_BAO_SchemaHandler::createIndexes($tables);
756 return TRUE;
757 }
758
8ca47f5c 759 /**
760 * CRM-17882 Add index to civicrm_contribution.credit_note_id.
761 *
762 * @param \CRM_Queue_TaskContext $ctx
763 *
764 * @return bool
765 */
5c9edd99 766 public static function addIndexContributionCreditNoteID(CRM_Queue_TaskContext $ctx) {
8ca47f5c 767 $tables = array('civicrm_contribution' => array('creditnote_id'));
768 CRM_Core_BAO_SchemaHandler::createIndexes($tables);
769 return TRUE;
770 }
771
2179c899 772 /**
773 * CRM-17775 Add correct index for table civicrm_financial_item.
774 *
775 * Note that the entity ID should always precede the entity_table as
776 * it is more unique. This is better for performance and does not cause fallback
777 * to no index if table it omitted.
778 *
779 * @return bool
780 */
5c9edd99 781 public static function addCombinedIndexFinancialItemEntityIDEntityType() {
2179c899 782 CRM_Core_BAO_SchemaHandler::dropIndexIfExists('civicrm_financial_item', 'UI_id');
783 CRM_Core_BAO_SchemaHandler::dropIndexIfExists('civicrm_financial_item', 'IX_Entity');
784 CRM_Core_BAO_SchemaHandler::createIndexes(array(
785 'civicrm_financial_item' => array(array('entity_id', 'entity_table')),
786 ));
787 return TRUE;
788 }
789
1f395432 790 /**
791 * CRM-17951 Add accounts option values for refund and chargeback.
792 *
793 * Add Chargeback contribution status and Chargeback and Contra account relationships,
794 * checking first if one exists.
795 */
5c9edd99 796 public static function addRefundAndChargeBackAccountsIfNotExist() {
1f395432 797 // First we enable and edit the record for Credit contra - this exists but is disabled for most sites.
798 // Using the ensure function (below) will not enabled a disabled option (by design).
799 CRM_Core_DAO::executeQuery("UPDATE civicrm_option_value v
800 INNER JOIN civicrm_option_group g on v.option_group_id=g.id and g.name='account_relationship'
801 SET v.is_active=1, v.label='Credit/Contra Revenue Account is', v.name='Credit/Contra Revenue Account is', v.description='Credit/Contra Revenue Account is'
802 WHERE v.name = 'Credit/Contra Account is';");
803
804 CRM_Core_BAO_OptionValue::ensureOptionValueExists(array(
805 'option_group_id' => 'account_relationship',
4a907feb
EM
806 'name' => 'Chargeback Account is',
807 'label' => ts('Chargeback Account is'),
1f395432 808 'is_active' => TRUE,
809 'component_id' => 'CiviContribute',
810 ));
811
812 CRM_Core_BAO_OptionValue::ensureOptionValueExists(array(
813 'option_group_id' => 'contribution_status',
814 'name' => 'Chargeback',
815 'label' => ts('Chargeback'),
816 'is_active' => TRUE,
817 'component_id' => 'CiviContribute',
818 ));
819 return TRUE;
820 }
821
3fe26f4c 822 /**
823 * CRM-17999 Add index to civicrm_contribution.source.
824 *
825 * @param \CRM_Queue_TaskContext $ctx
826 *
827 * @return bool
828 */
5c9edd99 829 public static function addIndexContributionSource(CRM_Queue_TaskContext $ctx) {
3fe26f4c 830 CRM_Core_BAO_SchemaHandler::createIndexes(array('civicrm_contribution' => array('source')));
831 return TRUE;
832 }
833
fd28b6a0 834 /**
835 * CRM-18124 Add index to civicrm_contribution.total_amount.
836 *
837 * Note that I made this a combined index with receive_date because the issue included
838 * both criteria and they seemed likely to be used in conjunction to me in other cases.
839 *
840 * @param \CRM_Queue_TaskContext $ctx
841 *
842 * @return bool
843 */
5c9edd99 844 public static function addIndexContributionAmount(CRM_Queue_TaskContext $ctx) {
fd28b6a0 845 CRM_Core_BAO_SchemaHandler::createIndexes(array(
846 'civicrm_contribution' => array(array('total_amount', 'receive_date')),
847 ));
848 return TRUE;
849 }
850
6eb752fa 851 /**
852 * CRM-18124 Add index to civicrm_contribution.total_amount.
853 *
854 * Note that I made this a combined index with receive_date because the issue included
855 * both criteria and they seemed likely to be used in conjunction to me in other cases.
856 *
857 * @param \CRM_Queue_TaskContext $ctx
858 *
859 * @return bool
860 */
5c9edd99 861 public static function addDeletedByMergeActivityType(CRM_Queue_TaskContext $ctx) {
6eb752fa 862 CRM_Core_BAO_OptionValue::ensureOptionValueExists(array(
863 'option_group_id' => 'activity_type',
864 'name' => 'Contact Deleted by Merge',
865 'label' => ts('Contact Deleted by Merge'),
866 'description' => ts('Contact was merged into another contact'),
867 'is_active' => TRUE,
e14e412b 868 'filter' => 1,
6eb752fa 869 ));
870 return TRUE;
871 }
872
da1ecd73
SL
873 /**
874 * CRM-12252 Add Help Pre and Help Post Fields for Price Field Value Table.
875 *
876 * @param \CRM_Queue_TaskContext $ctx
877 *
878 * @return bool
879 */
5c9edd99 880 public static function addHelpPreAndHelpPostFieldsPriceFieldValue(CRM_Queue_TaskContext $ctx) {
da1ecd73
SL
881 $domain = new CRM_Core_DAO_Domain();
882 $domain->find(TRUE);
883 if ($domain->locales) {
884 $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);
885 foreach ($locales as $locale) {
01ee8ba6 886 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists("civicrm_price_field_value", "help_pre_{$locale}")) {
3dc870a2
SL
887 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_price_field_value`
888 ADD COLUMN `help_pre_{$locale}` text COLLATE utf8_unicode_ci COMMENT 'Price field option pre help text.'", array(), TRUE, NULL, FALSE, FALSE);
da1ecd73 889 }
01ee8ba6 890 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists("civicrm_price_field_value", "help_post_{$locale}")) {
3dc870a2
SL
891 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_price_field_value`
892 ADD COLUMN `help_post_{$locale}` text COLLATE utf8_unicode_ci COMMENT 'Price field option post help text.'", array(), TRUE, NULL, FALSE, FALSE);
da1ecd73
SL
893 }
894 }
41ace555 895 CRM_Core_I18n_Schema::rebuildMultilingualSchema($locales, NULL, TRUE);
da1ecd73
SL
896 }
897 else {
898 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_price_field_value', 'help_pre')) {
3dc870a2
SL
899 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_price_field_value`
900 ADD COLUMN `help_pre` text COLLATE utf8_unicode_ci COMMENT 'Price field option pre help text.'");
da1ecd73
SL
901 }
902 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_price_field_value', 'help_post')) {
3dc870a2
SL
903 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_price_field_value`
904 ADD COLUMN `help_post` text COLLATE utf8_unicode_ci COMMENT 'Price field option post help text.'");
da1ecd73
SL
905 }
906 }
907 return TRUE;
908 }
909
8c748d50
SL
910 /**
911 * CRM-18464 Check if Foreign key exists and also drop any index of same name accidentially created.
912 *
913 * @param \CRM_Queue_TaskContext $ctx
914 *
915 * @return bool
916 */
917 public static function dropActionScheudleMappingForeignKey(CRM_Queue_TaskContext $ctx) {
918 CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_action_schedule', 'FK_civicrm_action_schedule_mapping_id');
8c748d50
SL
919 return TRUE;
920 }
921
2cbdd085
J
922 /**
923 * CRM-18345 Don't delete mailing data on email/phone deletion
924 * Implemented here in CRM-18526
925 *
926 * @param \CRM_Queue_TaskContext $ctx
927 *
928 * @return bool
929 */
5c9edd99 930 public static function upgradeMailingFKs(CRM_Queue_TaskContext $ctx) {
2cbdd085
J
931
932 // Safely drop the foreign keys
169475b7
SL
933 CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_mailing_event_queue', 'FK_civicrm_mailing_event_queue_email_id');
934 CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_mailing_event_queue', 'FK_civicrm_mailing_event_queue_phone_id');
935 CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_mailing_recipients', 'FK_civicrm_mailing_recipients_email_id');
936 CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_mailing_recipients', 'FK_civicrm_mailing_recipients_phone_id');
2cbdd085
J
937
938 // Set up the new foreign keys
939 CRM_Core_DAO::executeQuery("SET FOREIGN_KEY_CHECKS = 0;");
940
941 CRM_Core_DAO::executeQuery("
942 ALTER TABLE `civicrm_mailing_event_queue`
943 ADD CONSTRAINT `FK_civicrm_mailing_event_queue_email_id`
944 FOREIGN KEY (`email_id`)
945 REFERENCES `civicrm_email`(`id`)
946 ON DELETE SET NULL
947 ON UPDATE RESTRICT;
948 ");
949
950 CRM_Core_DAO::executeQuery("
951 ALTER TABLE `civicrm_mailing_event_queue`
952 ADD CONSTRAINT `FK_civicrm_mailing_event_queue_phone_id`
953 FOREIGN KEY (`phone_id`)
954 REFERENCES `civicrm_phone`(`id`)
955 ON DELETE SET NULL
956 ON UPDATE RESTRICT;
957 ");
958
959 CRM_Core_DAO::executeQuery("
960 ALTER TABLE `civicrm_mailing_recipients`
961 ADD CONSTRAINT `FK_civicrm_mailing_recipients_email_id`
962 FOREIGN KEY (`email_id`)
963 REFERENCES `civicrm_email`(`id`)
964 ON DELETE SET NULL
965 ON UPDATE RESTRICT;
966 ");
967
968 CRM_Core_DAO::executeQuery("
969 ALTER TABLE `civicrm_mailing_recipients`
970 ADD CONSTRAINT `FK_civicrm_mailing_recipients_phone_id`
971 FOREIGN KEY (`phone_id`)
972 REFERENCES `civicrm_phone`(`id`)
973 ON DELETE SET NULL
974 ON UPDATE RESTRICT;
975 ");
976
977 CRM_Core_DAO::executeQuery("SET FOREIGN_KEY_CHECKS = 1;");
978
979 return TRUE;
980 }
981
00c27b41
CW
982 /**
983 * CRM-17663 - Dashboard schema changes
984 *
985 * @param \CRM_Queue_TaskContext $ctx
986 *
987 * @return bool
988 */
5c9edd99 989 public static function dashboardSchemaUpdate(CRM_Queue_TaskContext $ctx) {
00c27b41
CW
990 if (!CRM_Core_BAO_SchemaHandler::checkIfIndexExists('civicrm_dashboard_contact', 'index_dashboard_id_contact_id')) {
991 // Delete any stray duplicate rows and add unique index to prevent new dupes and enable INSERT/UPDATE combo query
992 CRM_Core_DAO::executeQuery('DELETE c1 FROM civicrm_dashboard_contact c1, civicrm_dashboard_contact c2 WHERE c1.contact_id = c2.contact_id AND c1.dashboard_id = c2.dashboard_id AND c1.id > c2.id');
993 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_dashboard_contact ADD UNIQUE INDEX index_dashboard_id_contact_id (dashboard_id, contact_id);');
994 }
87568e34
SL
995 $domain = new CRM_Core_DAO_Domain();
996 $domain->find(TRUE);
41ace555
SL
997 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard_contact', 'content', FALSE, TRUE);
998 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard_contact', 'is_minimized', FALSE, TRUE);
999 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard_contact', 'is_fullscreen', FALSE, TRUE);
1000 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard_contact', 'created_date', FALSE, TRUE);
1001 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard', 'is_fullscreen', FALSE, TRUE);
1002 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard', 'is_minimized', FALSE, TRUE);
1003 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard', 'column_no', FALSE, TRUE);
1004 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard', 'weight', FALSE, TRUE);
242055d3
CW
1005
1006 CRM_Core_DAO::executeQuery('UPDATE civicrm_dashboard SET url = REPLACE(url, "&snippet=5", ""), fullscreen_url = REPLACE(fullscreen_url, "&snippet=5", "")');
a8f56d71
CW
1007
1008 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_dashboard', 'cache_minutes')) {
8c3f9072
SL
1009 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_dashboard ADD COLUMN cache_minutes int unsigned NOT NULL DEFAULT 60 COMMENT "Number of minutes to cache dashlet content in browser localStorage."',
1010 array(), TRUE, NULL, FALSE, FALSE);
1011 }
1012 if ($domain->locales) {
1013 $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);
41ace555 1014 CRM_Core_I18n_Schema::rebuildMultilingualSchema($locales, NULL, TRUE);
a8f56d71
CW
1015 }
1016
1017 CRM_Core_DAO::executeQuery('UPDATE civicrm_dashboard SET cache_minutes = 1440 WHERE name = "blog"');
1018 CRM_Core_DAO::executeQuery('UPDATE civicrm_dashboard SET cache_minutes = 7200 WHERE name IN ("activity","getting-started")');
242055d3 1019 return TRUE;
00c27b41
CW
1020 }
1021
8e2e96a5 1022 /**
1023 * CRM-19100 - Alter Index and Type for Image URL
1024 * @return bool
1025 */
1026 public static function alterIndexAndTypeForImageURL() {
98daafd5 1027 $length = array();
1028 CRM_Core_BAO_SchemaHandler::dropIndexIfExists('civicrm_contact', 'index_image_url');
8e2e96a5 1029 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_contact` CHANGE `image_URL` `image_URL` TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT 'optional URL for preferred image (photo, logo, etc.) to display for this contact.'");
98daafd5 1030
1031 $length['civicrm_contact']['image_URL'] = 128;
1032 CRM_Core_BAO_SchemaHandler::createIndexes(array('civicrm_contact' => array('image_URL')), 'index', $length);
8e2e96a5 1033
1034 return TRUE;
1035 }
1036
bc854509 1037 /**
1038 * Add mailing template type.
1039 *
1040 * @return bool
1041 */
703875d8
TO
1042 public static function addMailingTemplateType() {
1043 if (!CRM_Core_DAO::checkFieldExists('civicrm_mailing', 'template_type', FALSE)) {
1044 CRM_Core_DAO::executeQuery('
1045 ALTER TABLE civicrm_mailing
1046 ADD COLUMN `template_type` varchar(64) NOT NULL DEFAULT \'traditional\' COMMENT \'The language/processing system used for email templates.\',
1047 ADD COLUMN `template_options` longtext COMMENT \'Advanced options used by the email templating system. (JSON encoded)\'
1048 ');
1049 }
1050 return TRUE;
1051 }
1052
d0e7e124
SL
1053 /**
1054 * CRM-18651 Add DataType column to Option Group Table
1055 * @return bool
1056 */
1057 public static function addDataTypeColumnToOptionGroupTable() {
7c61320c 1058 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_option_group', 'data_type')) {
a37e4e6c
SL
1059 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_option_group` ADD COLUMN `data_type` varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL comment 'Data Type of Option Group.'",
1060 array(), TRUE, NULL, FALSE, FALSE);
1061 }
1062 $domain = new CRM_Core_DAO_Domain();
1063 $domain->find(TRUE);
1064 if ($domain->locales) {
1065 $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);
41ace555 1066 CRM_Core_I18n_Schema::rebuildMultilingualSchema($locales, NULL, TRUE);
d0e7e124 1067 }
a37e4e6c 1068
d0e7e124
SL
1069 CRM_Core_DAO::executeQuery("UPDATE `civicrm_option_group` SET `data_type` = 'Integer'
1070 WHERE name IN ('activity_type', 'gender', 'payment_instrument', 'participant_role', 'event_type')");
1071 return TRUE;
1072 }
1073
7ad5ae6a
CW
1074 /**
1075 * CRM-19372 Add field to store accepted credit credit cards for a payment processor.
1076 * @return bool
1077 */
1078 public static function addWysiwygPresets() {
1079 CRM_Core_BAO_OptionGroup::ensureOptionGroupExists(array(
1080 'name' => 'wysiwyg_presets',
1081 'title' => ts('WYSIWYG Editor Presets'),
1082 'is_reserved' => 1,
1083 ));
1084 $values = array(
1085 'default' => array('label' => ts('Default'), 'is_default' => 1),
1086 'civimail' => array('label' => ts('CiviMail'), 'component_id' => 'CiviMail'),
1087 'civievent' => array('label' => ts('CiviEvent'), 'component_id' => 'CiviEvent'),
1088 );
1089 foreach ($values as $name => $value) {
34273b2a 1090 CRM_Core_BAO_OptionValue::ensureOptionValueExists($value + array(
7ad5ae6a
CW
1091 'name' => $name,
1092 'option_group_id' => 'wysiwyg_presets',
1093 ));
1094 }
1095 $fileName = Civi::paths()->getPath('[civicrm.files]/persist/crm-ckeditor-config.js');
99316116 1096 // Ensure the config file contains the allowedContent setting
7ad5ae6a
CW
1097 if (file_exists($fileName)) {
1098 $config = file_get_contents($fileName);
1099 $pos = strrpos($config, '};');
1100 $setting = "\n\tconfig.allowedContent = true;\n";
1101 $config = substr_replace($config, $setting, $pos, 0);
1102 unlink($fileName);
949a87e8
CW
1103 $newFileName = Civi::paths()->getPath('[civicrm.files]/persist/crm-ckeditor-default.js');
1104 file_put_contents($newFileName, $config);
7ad5ae6a 1105 }
7ad5ae6a
CW
1106 return TRUE;
1107 }
1108
36610486 1109 /**
1110 * Update Kenyan Provinces to reflect changes per CRM-20062
1111 *
1112 * @param \CRM_Queue_TaskContext $ctx
1113 */
35e62234 1114 public static function updateKenyanProvinces(CRM_Queue_TaskContext $ctx) {
36610486 1115 $kenyaCountryID = CRM_Core_DAO::singleValueQuery('SELECT max(id) from civicrm_country where iso_code = "KE"');
1116 $oldProvinces = array(
1117 'Nairobi Municipality',
1118 'Coast',
1119 'North-Eastern Kaskazini Mashariki',
1120 'Rift Valley',
1121 'Western Magharibi',
1122 );
1123 self::deprecateStateProvinces($kenyaCountryID, $oldProvinces);
1124 return TRUE;
1125 }
1126
1127 /**
1128 * Deprecate provinces that no longer exist.
1129 *
1130 * @param int $countryID
1131 * @param array $provinces
1132 */
1133 public static function deprecateStateProvinces($countryID, $provinces) {
1134 foreach ($provinces as $province) {
1135 $existingStateID = CRM_Core_DAO::singleValueQuery("
1136 SELECT id FROM civicrm_state_province
1137 WHERE country_id = %1
1138 AND name = %2
1139 ",
1140 array(1 => array($countryID, 'Int'), 2 => array($province, 'String')));
1141
1142 if (!$existingStateID) {
1143 continue;
1144 }
1145 if (!CRM_Core_DAO::singleValueQuery("
1146 SELECT count(*) FROM civicrm_address
1147 WHERE state_province_id = %1
1148 ", array(1 => array($existingStateID, 'Int')))
1149 ) {
1150 CRM_Core_DAO::executeQuery("DELETE FROM civicrm_state_province WHERE id = %1", array(1 => array($existingStateID, 'Int')));
1151 }
1152 else {
1153 $params = array('1' => array(ts("Former - $province"), 'String'));
1154 CRM_Core_DAO::executeQuery("
1155 UPDATE civicrm_state_province SET name = %1 WHERE id = $existingStateID
1156 ", $params);
1157 }
1158 }
1159 }
1160
4eae8dda
SL
1161 /**
1162 * CRM-19961
1163 * Poputate newly added domain id column and add foriegn key onto table.
1164 */
1165 public static function populateSMSProviderDomainId() {
1166 $count = CRM_Core_DAO::singleValueQuery("SELECT count(id) FROM civicrm_domain");
9cec4195 1167 if ($count == 1) {
4eae8dda
SL
1168 CRM_Core_DAO::executeQuery("UPDATE civicrm_sms_provider SET domain_id = (SELECT id FROM civicrm_domain)");
1169 }
27e82c24 1170 if (!parent::checkFKExists('civicrm_sms_provider', 'FK_civicrm_sms_provider_domain_id')) {
f5078cc0
SL
1171 CRM_Core_DAO::executeQuery("SET FOREIGN_KEY_CHECKS = 0;");
1172 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_sms_provider`
1173 ADD CONSTRAINT FK_civicrm_sms_provider_domain_id
1174 FOREIGN KEY (`domain_id`) REFERENCES `civicrm_domain`(`id`)
1175 ON DELETE SET NULL");
4eae8dda 1176
f5078cc0
SL
1177 CRM_Core_DAO::executeQuery("SET FOREIGN_KEY_CHECKS = 1;");
1178 }
4eae8dda
SL
1179 return TRUE;
1180 }
1181
ccfd6962
CW
1182 /**
1183 * CRM-16633 - Add activity type for Change Case Status
1184 *
1185 * @param \CRM_Queue_TaskContext $ctx
1186 *
1187 * @return bool
1188 */
1189 public static function addChangeCaseSubjectActivityType(CRM_Queue_TaskContext $ctx) {
1190 CRM_Core_BAO_OptionValue::ensureOptionValueExists(array(
1191 'option_group_id' => 'activity_type',
1192 'name' => 'Change Case Subject',
1193 'label' => ts('Change Case Subject'),
1194 'is_active' => TRUE,
1195 'component_id' => 'CiviCase',
1196 'icon' => 'fa-pencil-square-o',
1197 ));
1198 return TRUE;
1199 }
1200
6f0dad97
SL
1201 /**
1202 * CRM-19986 fix schema differnces in civicrm_action_schedule
1203 */
1204 public static function fixSchemaOnCiviCRMActionSchedule() {
27e82c24 1205 if (!parent::checkFKExists('civicrm_action_schedule', 'FK_civicrm_action_schedule_sms_template_id')) {
6f0dad97
SL
1206 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_action_schedule`
1207 ADD CONSTRAINT FK_civicrm_action_schedule_sms_template_id
1208 FOREIGN KEY (`sms_template_id`) REFERENCES `civicrm_msg_template`(`id`)
1209 ON DELETE SET NULL");
1210 }
1211 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_action_schedule`
1212 CHANGE `mapping_id` `mapping_id` varchar(64) COLLATE
1213 utf8_unicode_ci DEFAULT NULL COMMENT 'Name/ID of the mapping to use on this table'");
1214 return TRUE;
1215 }
1216
58e9d364
TO
1217 public static function pickActivityRevisionPolicy(CRM_Queue_TaskContext $ctx) {
1218 // CRM-21052 - If site is using activity revisions, continue doing so. Otherwise, switch out.
1219 $count = CRM_Core_DAO::singleValueQuery('SELECT count(*) FROM civicrm_activity WHERE is_current_revision = 0 OR original_id IS NOT NULL');
1220 Civi::settings()->set('civicaseActivityRevisions', $count > 0);
1221 return TRUE;
1222 }
1223
17511f38
TO
1224 /**
1225 * @return bool
1226 */
1227 protected function checkImageUploadDir() {
1228 $config = CRM_Core_Config::singleton();
1229 $check = new CRM_Utils_Check_Component_Security();
1230 return $config->imageUploadDir && $config->imageUploadURL && $check->isDirAccessible($config->imageUploadDir, $config->imageUploadURL);
1231 }
1232
6cc25669 1233}