Merge pull request #9469 from jitendrapurohit/CRM-19692-4.7.14-rc
[civicrm-core.git] / CRM / Upgrade / Incremental / php / FourSeven.php
CommitLineData
6cc25669
CW
1<?php
2/*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
fa938177 6 | Copyright CiviCRM LLC (c) 2004-2016 |
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 }
f431d51f
J
62 }
63
6cc25669
CW
64 /**
65 * Compute any messages which should be displayed after upgrade.
66 *
67 * @param string $postUpgradeMessage
68 * alterable.
69 * @param string $rev
70 * an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs.
6cc25669
CW
71 */
72 public function setPostUpgradeMessage(&$postUpgradeMessage, $rev) {
6dbe2c23
CW
73 if ($rev == '4.7.alpha1') {
74 $config = CRM_Core_Config::singleton();
bf6a5362 75 // FIXME: Performing an upgrade step during postUpgrade message phase is probably bad
6dbe2c23
CW
76 $editor_id = self::updateWysiwyg();
77 $msg = NULL;
78 $ext_href = 'href="' . CRM_Utils_System::url('civicrm/admin/extensions', 'reset=1') . '"';
79 $dsp_href = 'href="' . CRM_Utils_System::url('civicrm/admin/setting/preferences/display', 'reset=1') . '"';
80 $blog_href = 'href="https://civicrm.org/blogs/colemanw/big-changes-wysiwyg-editing-47"';
81 switch ($editor_id) {
82 // TinyMCE
83 case 1:
84 $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));
85 break;
86
87 // Drupal/Joomla editor
88 case 3:
89 case 4:
90 $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));
91 break;
92 }
93 if ($msg) {
94 $postUpgradeMessage .= '<p>' . $msg . '</p>';
95 }
96 $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 97
98 $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
99
100 $postUpgradeMessage .= '<p>' . ts('The custom fatal error template setting has been removed.') . '</p>';
6dbe2c23 101 }
a742ee50
TO
102 //if ($rev == '4.7.11') {
103 // $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'");
104 //}
11769bd1 105 if ($rev == '4.7.11') {
9867e465 106 $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 107 }
6cc25669
CW
108 }
109
6cc25669
CW
110 /**
111 * Upgrade function.
112 *
113 * @param string $rev
114 */
115 public function upgrade_4_7_alpha1($rev) {
b604d7ec 116 $this->addTask('Migrate \'on behalf of\' information to module_data', 'migrateOnBehalfOfInfo');
bf6a5362 117 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
f806379b 118 $this->addTask(ts('Migrate Settings to %1', array(1 => $rev)), 'migrateSettings', $rev);
b604d7ec 119 $this->addTask('Add Getting Started dashlet', 'addGettingStartedDashlet', $rev);
a40fd1ac
CW
120 }
121
122 /**
123 * Upgrade function.
124 *
125 * @param string $rev
126 */
127 public function upgrade_4_7_alpha4($rev) {
128 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
058b8a5e 129 $this->addTask(ts('Remove %1', array(1 => 'Moneris')), 'removePaymentProcessorType', 'Moneris');
b2222b9f 130 $this->addTask('Update Smart Groups', 'fixContactTypeInSmartGroups');
6cc25669
CW
131 }
132
0094ac08
CW
133 /**
134 * Upgrade function.
135 *
136 * @param string $rev
137 */
138 public function upgrade_4_7_beta2($rev) {
139 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
140 $this->addTask('Delete unused file', 'deleteVersionCheckCacheFile');
141 }
142
fb1f3850
DRJ
143 /**
144 * Upgrade function.
145 *
146 * @param string $rev
147 */
902e557f 148 public function upgrade_4_7_beta6($rev) {
13599400 149 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
fb1f3850 150 $this->addTask('Disable flexible jobs extension', 'disableFlexibleJobsExtension');
20d5377e 151 $this->addTask('Add Index to financial_trxn trxn_id field', 'addIndexFinancialTrxnTrxnID');
fb1f3850
DRJ
152 }
153
8ca47f5c 154 /**
155 * Upgrade function.
156 *
157 * @param string $rev
158 */
159 public function upgrade_4_7_1($rev) {
2af0b023 160 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
8ca47f5c 161 $this->addTask('Add Index to civicrm_contribution creditnote_id field', 'addIndexContributionCreditNoteID');
162 }
163
2179c899 164 /**
165 * Upgrade function.
166 *
167 * @param string $rev
168 */
169 public function upgrade_4_7_2($rev) {
2af0b023 170 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
2179c899 171 $this->addTask('Fix Index on civicrm_financial_item combined entity_id + entity_table', 'addCombinedIndexFinancialItemEntityIDEntityType');
1f395432 172 $this->addTask('enable financial account relationships for chargeback & refund', 'addRefundAndChargeBackAccountsIfNotExist');
3fe26f4c 173 $this->addTask('Add Index to civicrm_contribution.source', 'addIndexContributionSource');
2179c899 174 }
175
fd28b6a0 176 /**
177 * Upgrade function.
178 *
179 * @param string $rev
180 */
181 public function upgrade_4_7_3($rev) {
2af0b023 182 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
fd28b6a0 183 $this->addTask('Add Index to civicrm_contribution.total_amount', 'addIndexContributionAmount');
184 }
185
6eb752fa 186 /**
187 * Upgrade function.
188 *
189 * @param string $rev
190 */
191 public function upgrade_4_7_4($rev) {
2af0b023 192 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
6eb752fa 193 $this->addTask('Add Contact Deleted by Merge Activity Type', 'addDeletedByMergeActivityType');
194 }
195
2cbdd085
J
196 /**
197 * Upgrade function.
198 *
199 * @param string $rev
200 */
6a2d3987 201 public function upgrade_4_7_7($rev) {
2cbdd085 202 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
6a2d3987
J
203 // https://issues.civicrm.org/jira/browse/CRM-18006
204 if (CRM_Core_DAO::checkTableExists('civicrm_install_canary')) {
205 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_install_canary ENGINE=InnoDB');
206 }
2cbdd085
J
207 }
208
2af0b023
CW
209 /**
210 * Upgrade function.
211 *
212 * @param string $rev
213 */
6a2d3987 214 public function upgrade_4_7_8($rev) {
2af0b023 215 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
6a2d3987 216 $this->addTask('Upgrade mailing foreign key constraints', 'upgradeMailingFKs');
065ffec9
TO
217 }
218
da1ecd73
SL
219 /**
220 * Upgrade function.
221 *
222 * @param string $rev
223 */
e8a4535e 224 public function upgrade_4_7_10($rev) {
da1ecd73 225 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
b5095b43
CW
226 $this->addTask('Upgrade Add Help Pre and Post Fields to price value table', 'addHelpPreAndHelpPostFieldsPriceFieldValue');
227 $this->addTask('Alter index and type for image URL', 'alterIndexAndTypeForImageURL');
da1ecd73
SL
228 }
229
00c27b41
CW
230 /**
231 * Upgrade function.
232 *
233 * @param string $rev
234 */
235 public function upgrade_4_7_11($rev) {
236 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
237 $this->addTask('Dashboard schema updates', 'dashboardSchemaUpdate');
b5095b43 238 $this->addTask('Fill in setting "remote_profile_submissions"', 'migrateRemoteSubmissionsSetting');
00c27b41
CW
239 }
240
7c61320c
SL
241 /**
242 * Upgrade function.
243 *
244 * @param string $rev
245 */
246 public function upgrade_4_7_12($rev) {
247 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
b5095b43 248 $this->addTask('Add Data Type column to civicrm_option_group', 'addDataTypeColumnToOptionGroupTable');
7c61320c 249 }
cb5962bd
SL
250 /**
251 * Upgrade function.
252 *
253 * @param string $rev
254 */
255 public function upgrade_4_7_13($rev) {
256 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
b5095b43 257 $this->addTask('Add column to allow for payment processors to set what card types are accepted', 'addAcceptedCardTypesField');
cb5962bd
SL
258 }
259
7ad5ae6a
CW
260 /**
261 * Upgrade function.
262 *
263 * @param string $rev
264 */
265 public function upgrade_4_7_14($rev) {
266 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
267 $this->addTask('Add WYSIWYG Editor Presets', 'addWysiwygPresets');
268 }
7c61320c 269
2af0b023 270 /*
2cbdbcef 271 * Important! All upgrade functions MUST add a 'runSql' task.
2af0b023
CW
272 * Uncomment and use the following template for a new upgrade version
273 * (change the x in the function name):
274 */
275
276 // /**
277 // * Upgrade function.
278 // *
279 // * @param string $rev
280 // */
281 // public function upgrade_4_7_x($rev) {
282 // $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
283 // // Additional tasks here...
b5095b43
CW
284 // // Note: do not use ts() in the addTask description because it adds unnecessary strings to transifex.
285 // // The above is an exception because 'Upgrade DB to %1: SQL' is generic & reusable.
2af0b023
CW
286 // }
287
6cc25669
CW
288 /**
289 * CRM-16354
290 *
6dbe2c23 291 * @return int
6cc25669 292 */
6dbe2c23 293 public static function updateWysiwyg() {
aaffa79f 294 $editorID = Civi::settings()->get('editor_id');
6dbe2c23
CW
295 // Previously a numeric value indicated one of 4 wysiwyg editors shipped in core, and no value indicated 'Textarea'
296 // Now the options are "Textarea", "CKEditor", and the rest have been dropped from core.
297 $newEditor = $editorID ? "CKEditor" : "Textarea";
08ef4ddd 298 Civi::settings()->set('editor_id', $newEditor);
6cc25669 299
6dbe2c23 300 return $editorID;
6cc25669
CW
301 }
302
f806379b
TO
303 /**
304 * Migrate any last remaining options from `civicrm_domain.config_backend` to `civicrm_setting`.
305 * Cleanup setting schema.
306 *
307 * @param CRM_Queue_TaskContext $ctx
308 * @return bool
309 */
5c9edd99 310 public static function migrateSettings(CRM_Queue_TaskContext $ctx) {
4cc9e637
TO
311 // Tip: If there are problems with adding the new uniqueness index, try inspecting:
312 // SELECT name, domain_id, contact_id, count(*) AS dupes FROM civicrm_setting cs GROUP BY name, domain_id, contact_id HAVING dupes > 1;
313
314 // Nav records are expendable. https://forum.civicrm.org/index.php?topic=36933.0
315 CRM_Core_DAO::executeQuery('DELETE FROM civicrm_setting WHERE contact_id IS NOT NULL AND name = "navigation"');
3ddd2901 316
726e6261
SL
317 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_setting DROP INDEX index_group_name');
318 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_setting DROP COLUMN group_name');
319
3ddd2901
SL
320 // Handle Strange activity_tab_filter settings.
321 CRM_Core_DAO::executeQuery('CREATE TABLE civicrm_activity_setting LIKE civicrm_setting');
726e6261 322 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_activity_setting ADD UNIQUE INDEX index_domain_contact_name (domain_id, contact_id, name)');
3ddd2901 323 CRM_Core_DAO::executeQuery('INSERT INTO civicrm_activity_setting (name, contact_id, domain_id, value)
726e6261 324 SELECT DISTINCT name, contact_id, domain_id, value
3ddd2901
SL
325 FROM civicrm_setting
326 WHERE name = "activity_tab_filter"
327 AND value is not NULL');
ee4d8422 328 CRM_Core_DAO::executeQuery('DELETE FROM civicrm_setting WHERE name = "activity_tab_filter"');
4cc9e637 329
e6a2c901 330 $date = CRM_Utils_Time::getTime('Y-m-d H:i:s');
f806379b 331 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_setting ADD UNIQUE INDEX index_domain_contact_name (domain_id, contact_id, name)');
e6a2c901
SL
332 CRM_Core_DAO::executeQuery("INSERT INTO civicrm_setting (name, contact_id, domain_id, value, is_domain, created_id, created_date)
333 SELECT name, contact_id, domain_id, value, 0, contact_id,'$date'
3ddd2901 334 FROM civicrm_activity_setting
e6a2c901
SL
335 WHERE name = 'activity_tab_filter'
336 AND value is not NULL"
d09d52ce 337 );
3ddd2901 338 CRM_Core_DAO::executeQuery('DROP TABLE civicrm_activity_setting');
f806379b
TO
339
340 $domainDao = CRM_Core_DAO::executeQuery('SELECT id, config_backend FROM civicrm_domain');
341 while ($domainDao->fetch()) {
342 $settings = CRM_Upgrade_Incremental_php_FourSeven::convertBackendToSettings($domainDao->id, $domainDao->config_backend);
343 CRM_Core_Error::debug_var('convertBackendToSettings', array(
344 'domainId' => $domainDao->id,
345 'backend' => $domainDao->config_backend,
346 'settings' => $settings,
347 ));
348
349 foreach ($settings as $name => $value) {
350 $rowParams = array(
351 1 => array($domainDao->id, 'Positive'),
352 2 => array($name, 'String'),
353 3 => array(serialize($value), 'String'),
354 );
355 $settingId = CRM_Core_DAO::singleValueQuery(
356 'SELECT id FROM civicrm_setting WHERE domain_id = %1 AND name = %2',
357 $rowParams);
358 if (!$settingId) {
359 CRM_Core_DAO::executeQuery(
360 'INSERT INTO civicrm_setting (domain_id, name, value, is_domain) VALUES (%1,%2,%3,1)',
361 $rowParams);
362 }
363 }
364 }
365
9e726168 366 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_domain DROP COLUMN config_backend');
f806379b
TO
367
368 return TRUE;
369 }
370
371 /**
372 * Take a config_backend blob and produce an equivalent list of settings.
373 *
374 * @param int $domainId
375 * Domain ID.
376 * @param string $config_backend
377 * Serialized blob.
378 * @return array
379 */
380 public static function convertBackendToSettings($domainId, $config_backend) {
381 if (!$config_backend) {
382 return array();
383 }
384
385 $backend = unserialize($config_backend);
386 if (!$backend) {
387 return array();
388 }
389
390 $mappings = \CRM_Core_Config_MagicMerge::getPropertyMap();
391 $settings = array();
392 foreach ($backend as $propertyName => $propertyValue) {
393 if (isset($mappings[$propertyName][0]) && preg_match('/^setting/', $mappings[$propertyName][0])) {
394 // $mapping format: $propertyName => Array(0 => $type, 1 => $setting|NULL).
395 $settingName = isset($mappings[$propertyName][1]) ? $mappings[$propertyName][1] : $propertyName;
396 $settings[$settingName] = $propertyValue;
397 }
398 }
399
400 return $settings;
401 }
402
0a95c936 403 /**
404 * Add Getting Started dashlet to dashboard
405 *
406 * @param \CRM_Queue_TaskContext $ctx
407 *
408 * @return bool
409 */
5c9edd99 410 public static function addGettingStartedDashlet(CRM_Queue_TaskContext $ctx) {
9c4a04f2 411 $sql = "SELECT count(*) FROM civicrm_dashboard WHERE name='getting-started'";
e1674273 412 $res = CRM_Core_DAO::singleValueQuery($sql);
413 $domainId = CRM_Core_Config::domainID();
414 if ($res <= 0) {
415 $sql = "INSERT INTO `civicrm_dashboard`
a8b704c5 416 ( `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 417 CRM_Core_DAO::executeQuery($sql);
418 // Add default position for Getting Started Dashlet ( left column)
419 $sql = "INSERT INTO `civicrm_dashboard_contact` (dashboard_id, contact_id, column_no, is_active)
420SELECT (SELECT MAX(id) FROM `civicrm_dashboard`), contact_id, 0, IF (SUM(is_active) > 0, 1, 0)
429da6a1 421FROM `civicrm_dashboard_contact` JOIN `civicrm_contact` WHERE civicrm_dashboard_contact.contact_id = civicrm_contact.id GROUP BY contact_id";
e1674273 422 CRM_Core_DAO::executeQuery($sql);
423 }
0a95c936 424 return TRUE;
e1674273 425 }
4175ee03 426
6b1e1a2c 427 /**
428 * Migrate on-behalf information to uf_join.module_data as on-behalf columns will be dropped
429 * on DB upgrade
430 *
431 * @param CRM_Queue_TaskContext $ctx
432 *
433 * @return bool
434 * TRUE for success
435 */
436 public static function migrateOnBehalfOfInfo(CRM_Queue_TaskContext $ctx) {
d3e92c88 437 $domain = new CRM_Core_DAO_Domain();
438 $domain->find(TRUE);
6b1e1a2c 439
d3e92c88 440 // fetch onBehalf entry in UFJoin table
6b1e1a2c 441 $ufGroupDAO = new CRM_Core_DAO_UFJoin();
442 $ufGroupDAO->module = 'OnBehalf';
443 $ufGroupDAO->find(TRUE);
444
f635ab77 445 $forOrgColums = array('is_for_organization');
d3e92c88 446 if ($domain->locales) {
447 $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);
448 foreach ($locales as $locale) {
449 $forOrgColums[] = "for_organization_{$locale}";
450 }
451 }
452 else {
453 $forOrgColums[] = "for_organization";
454 }
455
456 $query = "
457 SELECT " . implode(", ", $forOrgColums) . ", uj.id as join_id, uj.uf_group_id as uf_group_id
458 FROM civicrm_contribution_page cp
459 INNER JOIN civicrm_uf_join uj ON uj.entity_id = cp.id AND uj.module = 'OnBehalf'";
460 $dao = CRM_Core_DAO::executeQuery($query, array(), TRUE, NULL, FALSE, FALSE);
6b1e1a2c 461
462 if ($dao->N) {
6b1e1a2c 463 while ($dao->fetch()) {
464 $onBehalfParams['on_behalf'] = array('is_for_organization' => $dao->is_for_organization);
465 if ($domain->locales) {
6b1e1a2c 466 foreach ($locales as $locale) {
467 $for_organization = "for_organization_{$locale}";
468 $onBehalfParams['on_behalf'] += array(
469 $locale => array(
470 'for_organization' => $dao->$for_organization,
471 ),
472 );
473 }
474 }
475 else {
476 $onBehalfParams['on_behalf'] += array(
477 'default' => array(
478 'for_organization' => $dao->for_organization,
479 ),
480 );
481 }
482 $ufJoinParam = array(
483 'id' => $dao->join_id,
484 'module' => 'on_behalf',
d3e92c88 485 'uf_group_id' => $dao->uf_group_id,
6b1e1a2c 486 'module_data' => json_encode($onBehalfParams),
487 );
488 CRM_Core_BAO_UFJoin::create($ufJoinParam);
489 }
490 }
491
492 return TRUE;
9e42a501
TO
493 }
494
495 /**
496 * v4.7.11 adds a new setting "remote_profile_submissions". This is
497 * long-standing feature that existing sites may be using; however, it's
498 * a bit prone to abuse. For new sites, the default is to disable it
499 * (since that is more secure). For existing sites, the default is to
500 * enable it (since that is more compatible).
501 *
502 * @param \CRM_Queue_TaskContext $ctx
503 *
504 * @return bool
505 */
5c9edd99 506 public static function migrateRemoteSubmissionsSetting(CRM_Queue_TaskContext $ctx) {
9e42a501
TO
507 $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");
508 while ($domains->fetch()) {
509 CRM_Core_DAO::executeQuery(
510 "INSERT INTO civicrm_setting (`name`, `value`, `domain_id`, `is_domain`, `contact_id`, `component_id`, `created_date`, `created_id`)
511 VALUES (%2, %3, %4, %5, NULL, NULL, %6, NULL)",
512 array(
513 2 => array('remote_profile_submissions', 'String'),
514 3 => array('s:1:"1";', 'String'),
515 4 => array($domains->id, 'Integer'),
516 5 => array(1, 'Integer'),
517 6 => array(date('Y-m-d H:i:s'), 'String'),
518 )
519 );
520 }
521 return TRUE;
6b1e1a2c 522 }
cb804cd9 523
b2222b9f
CW
524 /**
525 * CRM-11782 - Get rid of VALUE_SEPARATOR character in saved search form values
526 *
527 * @param \CRM_Queue_TaskContext $ctx
528 *
529 * @return bool
530 */
5c9edd99 531 public static function fixContactTypeInSmartGroups(CRM_Queue_TaskContext $ctx) {
b2222b9f
CW
532 $sep = CRM_Core_DAO::VALUE_SEPARATOR;
533 $dao = CRM_Core_DAO::executeQuery("SELECT id, form_values FROM civicrm_saved_search WHERE form_values LIKE '%$sep%'");
534 while ($dao->fetch()) {
535 $formValues = unserialize($dao->form_values);
536 if (isset($formValues['contact_type']) && is_array($formValues['contact_type'])) {
537 $newVals = array();
538 foreach ($formValues['contact_type'] as $key => $val) {
539 $newVals[str_replace($sep, '__', $key)] = is_string($val) ? str_replace($sep, '__', $val) : $val;
540 }
541 $formValues['contact_type'] = $newVals;
542 }
543 CRM_Core_DAO::executeQuery("UPDATE civicrm_saved_search SET form_values = %1 WHERE id = {$dao->id}", array(1 => array(serialize($formValues), 'String')));
544 }
545
546 return TRUE;
547 }
548
0094ac08
CW
549 /**
550 * CRM-17637 - Ths file location has been moved; delete the old one
551 *
552 * @param \CRM_Queue_TaskContext $ctx
553 *
554 * @return bool
555 */
5c9edd99 556 public static function deleteVersionCheckCacheFile(CRM_Queue_TaskContext $ctx) {
0094ac08
CW
557 $config = CRM_Core_Config::singleton();
558 $cacheFile = $config->uploadDir . 'version-info-cache.json';
559 if (file_exists($cacheFile)) {
560 unlink($cacheFile);
561 }
562 return TRUE;
563 }
564
fb1f3850
DRJ
565 /**
566 * CRM-17669 and CRM-17686, make scheduled jobs more flexible, disable the 4.6 extension if installed
567 *
568 * @param \CRM_Queue_TaskContext $ctx
569 *
570 * @return bool
571 */
5c9edd99 572 public static function disableFlexibleJobsExtension(CRM_Queue_TaskContext $ctx) {
d357221c
DRJ
573 try {
574 civicrm_api3('Extension', 'disable', array('key' => 'com.klangsoft.flexiblejobs'));
575 }
576 catch (CiviCRM_API3_Exception $e) {
577 // just ignore if the extension isn't installed
578 }
fb1f3850
DRJ
579
580 return TRUE;
581 }
582
20d5377e 583 /**
584 * CRM-17752 add index to civicrm_financial_trxn.trxn_id (deliberately non-unique).
585 *
586 * @param \CRM_Queue_TaskContext $ctx
587 *
588 * @return bool
589 */
5c9edd99 590 public static function addIndexFinancialTrxnTrxnID(CRM_Queue_TaskContext $ctx) {
20d5377e 591 $tables = array('civicrm_financial_trxn' => array('trxn_id'));
592 CRM_Core_BAO_SchemaHandler::createIndexes($tables);
593 return TRUE;
594 }
595
8ca47f5c 596 /**
597 * CRM-17882 Add index to civicrm_contribution.credit_note_id.
598 *
599 * @param \CRM_Queue_TaskContext $ctx
600 *
601 * @return bool
602 */
5c9edd99 603 public static function addIndexContributionCreditNoteID(CRM_Queue_TaskContext $ctx) {
8ca47f5c 604 $tables = array('civicrm_contribution' => array('creditnote_id'));
605 CRM_Core_BAO_SchemaHandler::createIndexes($tables);
606 return TRUE;
607 }
608
2179c899 609 /**
610 * CRM-17775 Add correct index for table civicrm_financial_item.
611 *
612 * Note that the entity ID should always precede the entity_table as
613 * it is more unique. This is better for performance and does not cause fallback
614 * to no index if table it omitted.
615 *
616 * @return bool
617 */
5c9edd99 618 public static function addCombinedIndexFinancialItemEntityIDEntityType() {
2179c899 619 CRM_Core_BAO_SchemaHandler::dropIndexIfExists('civicrm_financial_item', 'UI_id');
620 CRM_Core_BAO_SchemaHandler::dropIndexIfExists('civicrm_financial_item', 'IX_Entity');
621 CRM_Core_BAO_SchemaHandler::createIndexes(array(
622 'civicrm_financial_item' => array(array('entity_id', 'entity_table')),
623 ));
624 return TRUE;
625 }
626
1f395432 627 /**
628 * CRM-17951 Add accounts option values for refund and chargeback.
629 *
630 * Add Chargeback contribution status and Chargeback and Contra account relationships,
631 * checking first if one exists.
632 */
5c9edd99 633 public static function addRefundAndChargeBackAccountsIfNotExist() {
1f395432 634 // First we enable and edit the record for Credit contra - this exists but is disabled for most sites.
635 // Using the ensure function (below) will not enabled a disabled option (by design).
636 CRM_Core_DAO::executeQuery("UPDATE civicrm_option_value v
637 INNER JOIN civicrm_option_group g on v.option_group_id=g.id and g.name='account_relationship'
638 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'
639 WHERE v.name = 'Credit/Contra Account is';");
640
641 CRM_Core_BAO_OptionValue::ensureOptionValueExists(array(
642 'option_group_id' => 'account_relationship',
4a907feb
EM
643 'name' => 'Chargeback Account is',
644 'label' => ts('Chargeback Account is'),
1f395432 645 'is_active' => TRUE,
646 'component_id' => 'CiviContribute',
647 ));
648
649 CRM_Core_BAO_OptionValue::ensureOptionValueExists(array(
650 'option_group_id' => 'contribution_status',
651 'name' => 'Chargeback',
652 'label' => ts('Chargeback'),
653 'is_active' => TRUE,
654 'component_id' => 'CiviContribute',
655 ));
656 return TRUE;
657 }
658
3fe26f4c 659 /**
660 * CRM-17999 Add index to civicrm_contribution.source.
661 *
662 * @param \CRM_Queue_TaskContext $ctx
663 *
664 * @return bool
665 */
5c9edd99 666 public static function addIndexContributionSource(CRM_Queue_TaskContext $ctx) {
3fe26f4c 667 CRM_Core_BAO_SchemaHandler::createIndexes(array('civicrm_contribution' => array('source')));
668 return TRUE;
669 }
670
fd28b6a0 671 /**
672 * CRM-18124 Add index to civicrm_contribution.total_amount.
673 *
674 * Note that I made this a combined index with receive_date because the issue included
675 * both criteria and they seemed likely to be used in conjunction to me in other cases.
676 *
677 * @param \CRM_Queue_TaskContext $ctx
678 *
679 * @return bool
680 */
5c9edd99 681 public static function addIndexContributionAmount(CRM_Queue_TaskContext $ctx) {
fd28b6a0 682 CRM_Core_BAO_SchemaHandler::createIndexes(array(
683 'civicrm_contribution' => array(array('total_amount', 'receive_date')),
684 ));
685 return TRUE;
686 }
687
6eb752fa 688 /**
689 * CRM-18124 Add index to civicrm_contribution.total_amount.
690 *
691 * Note that I made this a combined index with receive_date because the issue included
692 * both criteria and they seemed likely to be used in conjunction to me in other cases.
693 *
694 * @param \CRM_Queue_TaskContext $ctx
695 *
696 * @return bool
697 */
5c9edd99 698 public static function addDeletedByMergeActivityType(CRM_Queue_TaskContext $ctx) {
6eb752fa 699 CRM_Core_BAO_OptionValue::ensureOptionValueExists(array(
700 'option_group_id' => 'activity_type',
701 'name' => 'Contact Deleted by Merge',
702 'label' => ts('Contact Deleted by Merge'),
703 'description' => ts('Contact was merged into another contact'),
704 'is_active' => TRUE,
e14e412b 705 'filter' => 1,
6eb752fa 706 ));
707 return TRUE;
708 }
709
da1ecd73
SL
710 /**
711 * CRM-12252 Add Help Pre and Help Post Fields for Price Field Value Table.
712 *
713 * @param \CRM_Queue_TaskContext $ctx
714 *
715 * @return bool
716 */
5c9edd99 717 public static function addHelpPreAndHelpPostFieldsPriceFieldValue(CRM_Queue_TaskContext $ctx) {
da1ecd73
SL
718 $domain = new CRM_Core_DAO_Domain();
719 $domain->find(TRUE);
720 if ($domain->locales) {
721 $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);
722 foreach ($locales as $locale) {
01ee8ba6 723 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists("civicrm_price_field_value", "help_pre_{$locale}")) {
3dc870a2
SL
724 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_price_field_value`
725 ADD COLUMN `help_pre_{$locale}` text COLLATE utf8_unicode_ci COMMENT 'Price field option pre help text.'", array(), TRUE, NULL, FALSE, FALSE);
da1ecd73 726 }
01ee8ba6 727 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists("civicrm_price_field_value", "help_post_{$locale}")) {
3dc870a2
SL
728 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_price_field_value`
729 ADD COLUMN `help_post_{$locale}` text COLLATE utf8_unicode_ci COMMENT 'Price field option post help text.'", array(), TRUE, NULL, FALSE, FALSE);
da1ecd73
SL
730 }
731 }
01ee8ba6 732 CRM_Core_I18n_Schema::rebuildMultilingualSchema($locales, NULL);
da1ecd73
SL
733 }
734 else {
735 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_price_field_value', 'help_pre')) {
3dc870a2
SL
736 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_price_field_value`
737 ADD COLUMN `help_pre` text COLLATE utf8_unicode_ci COMMENT 'Price field option pre help text.'");
da1ecd73
SL
738 }
739 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_price_field_value', 'help_post')) {
3dc870a2
SL
740 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_price_field_value`
741 ADD COLUMN `help_post` text COLLATE utf8_unicode_ci COMMENT 'Price field option post help text.'");
da1ecd73
SL
742 }
743 }
744 return TRUE;
745 }
746
2cbdd085
J
747 /**
748 * CRM-18345 Don't delete mailing data on email/phone deletion
749 * Implemented here in CRM-18526
750 *
751 * @param \CRM_Queue_TaskContext $ctx
752 *
753 * @return bool
754 */
5c9edd99 755 public static function upgradeMailingFKs(CRM_Queue_TaskContext $ctx) {
2cbdd085
J
756
757 // Safely drop the foreign keys
169475b7
SL
758 CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_mailing_event_queue', 'FK_civicrm_mailing_event_queue_email_id');
759 CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_mailing_event_queue', 'FK_civicrm_mailing_event_queue_phone_id');
760 CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_mailing_recipients', 'FK_civicrm_mailing_recipients_email_id');
761 CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_mailing_recipients', 'FK_civicrm_mailing_recipients_phone_id');
2cbdd085
J
762
763 // Set up the new foreign keys
764 CRM_Core_DAO::executeQuery("SET FOREIGN_KEY_CHECKS = 0;");
765
766 CRM_Core_DAO::executeQuery("
767 ALTER TABLE `civicrm_mailing_event_queue`
768 ADD CONSTRAINT `FK_civicrm_mailing_event_queue_email_id`
769 FOREIGN KEY (`email_id`)
770 REFERENCES `civicrm_email`(`id`)
771 ON DELETE SET NULL
772 ON UPDATE RESTRICT;
773 ");
774
775 CRM_Core_DAO::executeQuery("
776 ALTER TABLE `civicrm_mailing_event_queue`
777 ADD CONSTRAINT `FK_civicrm_mailing_event_queue_phone_id`
778 FOREIGN KEY (`phone_id`)
779 REFERENCES `civicrm_phone`(`id`)
780 ON DELETE SET NULL
781 ON UPDATE RESTRICT;
782 ");
783
784 CRM_Core_DAO::executeQuery("
785 ALTER TABLE `civicrm_mailing_recipients`
786 ADD CONSTRAINT `FK_civicrm_mailing_recipients_email_id`
787 FOREIGN KEY (`email_id`)
788 REFERENCES `civicrm_email`(`id`)
789 ON DELETE SET NULL
790 ON UPDATE RESTRICT;
791 ");
792
793 CRM_Core_DAO::executeQuery("
794 ALTER TABLE `civicrm_mailing_recipients`
795 ADD CONSTRAINT `FK_civicrm_mailing_recipients_phone_id`
796 FOREIGN KEY (`phone_id`)
797 REFERENCES `civicrm_phone`(`id`)
798 ON DELETE SET NULL
799 ON UPDATE RESTRICT;
800 ");
801
802 CRM_Core_DAO::executeQuery("SET FOREIGN_KEY_CHECKS = 1;");
803
804 return TRUE;
805 }
806
00c27b41
CW
807 /**
808 * CRM-17663 - Dashboard schema changes
809 *
810 * @param \CRM_Queue_TaskContext $ctx
811 *
812 * @return bool
813 */
5c9edd99 814 public static function dashboardSchemaUpdate(CRM_Queue_TaskContext $ctx) {
00c27b41
CW
815 if (!CRM_Core_BAO_SchemaHandler::checkIfIndexExists('civicrm_dashboard_contact', 'index_dashboard_id_contact_id')) {
816 // Delete any stray duplicate rows and add unique index to prevent new dupes and enable INSERT/UPDATE combo query
817 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');
818 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_dashboard_contact ADD UNIQUE INDEX index_dashboard_id_contact_id (dashboard_id, contact_id);');
819 }
87568e34
SL
820 $domain = new CRM_Core_DAO_Domain();
821 $domain->find(TRUE);
242055d3
CW
822 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard_contact', 'content');
823 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard_contact', 'is_minimized');
824 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard_contact', 'is_fullscreen');
825 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard_contact', 'created_date');
826 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard', 'is_fullscreen');
827 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard', 'is_minimized');
828 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard', 'column_no');
829 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard', 'weight');
830
831 CRM_Core_DAO::executeQuery('UPDATE civicrm_dashboard SET url = REPLACE(url, "&snippet=5", ""), fullscreen_url = REPLACE(fullscreen_url, "&snippet=5", "")');
a8f56d71
CW
832
833 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_dashboard', 'cache_minutes')) {
8c3f9072
SL
834 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."',
835 array(), TRUE, NULL, FALSE, FALSE);
836 }
837 if ($domain->locales) {
838 $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);
839 CRM_Core_I18n_Schema::rebuildMultilingualSchema($locales, NULL);
a8f56d71
CW
840 }
841
842 CRM_Core_DAO::executeQuery('UPDATE civicrm_dashboard SET cache_minutes = 1440 WHERE name = "blog"');
843 CRM_Core_DAO::executeQuery('UPDATE civicrm_dashboard SET cache_minutes = 7200 WHERE name IN ("activity","getting-started")');
242055d3 844 return TRUE;
00c27b41
CW
845 }
846
8e2e96a5 847 /**
848 * CRM-19100 - Alter Index and Type for Image URL
849 * @return bool
850 */
851 public static function alterIndexAndTypeForImageURL() {
98daafd5 852 $length = array();
853 CRM_Core_BAO_SchemaHandler::dropIndexIfExists('civicrm_contact', 'index_image_url');
8e2e96a5 854 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 855
856 $length['civicrm_contact']['image_URL'] = 128;
857 CRM_Core_BAO_SchemaHandler::createIndexes(array('civicrm_contact' => array('image_URL')), 'index', $length);
8e2e96a5 858
859 return TRUE;
860 }
861
d0e7e124
SL
862 /**
863 * CRM-18651 Add DataType column to Option Group Table
864 * @return bool
865 */
866 public static function addDataTypeColumnToOptionGroupTable() {
7c61320c 867 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_option_group', 'data_type')) {
a37e4e6c
SL
868 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.'",
869 array(), TRUE, NULL, FALSE, FALSE);
870 }
871 $domain = new CRM_Core_DAO_Domain();
872 $domain->find(TRUE);
873 if ($domain->locales) {
874 $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);
875 CRM_Core_I18n_Schema::rebuildMultilingualSchema($locales, NULL);
d0e7e124 876 }
a37e4e6c 877
d0e7e124
SL
878 CRM_Core_DAO::executeQuery("UPDATE `civicrm_option_group` SET `data_type` = 'Integer'
879 WHERE name IN ('activity_type', 'gender', 'payment_instrument', 'participant_role', 'event_type')");
880 return TRUE;
881 }
882
cb5962bd
SL
883 /**
884 * CRM-19372 Add field to store accepted credit credit cards for a payment processor.
885 * @return bool
886 */
887 public static function addAcceptedCardTypesField() {
888 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_payment_processor', 'accepted_credit_cards')) {
889 CRM_Core_DAO::executeQuery("ALTER TABLE civicrm_payment_processor ADD COLUMN `accepted_credit_cards` text DEFAULT NULL COMMENT 'array of accepted credit card types'");
890 }
891 return TRUE;
892 }
893
7ad5ae6a
CW
894 /**
895 * CRM-19372 Add field to store accepted credit credit cards for a payment processor.
896 * @return bool
897 */
898 public static function addWysiwygPresets() {
899 CRM_Core_BAO_OptionGroup::ensureOptionGroupExists(array(
900 'name' => 'wysiwyg_presets',
901 'title' => ts('WYSIWYG Editor Presets'),
902 'is_reserved' => 1,
903 ));
904 $values = array(
905 'default' => array('label' => ts('Default'), 'is_default' => 1),
906 'civimail' => array('label' => ts('CiviMail'), 'component_id' => 'CiviMail'),
907 'civievent' => array('label' => ts('CiviEvent'), 'component_id' => 'CiviEvent'),
908 );
909 foreach ($values as $name => $value) {
910 civicrm_api3('OptionValue', 'create', $value + array(
911 'options' => array('match' => array('name', 'option_group_id')),
912 'name' => $name,
913 'option_group_id' => 'wysiwyg_presets',
914 ));
915 }
916 $fileName = Civi::paths()->getPath('[civicrm.files]/persist/crm-ckeditor-config.js');
99316116 917 // Ensure the config file contains the allowedContent setting
7ad5ae6a
CW
918 if (file_exists($fileName)) {
919 $config = file_get_contents($fileName);
920 $pos = strrpos($config, '};');
921 $setting = "\n\tconfig.allowedContent = true;\n";
922 $config = substr_replace($config, $setting, $pos, 0);
923 unlink($fileName);
949a87e8
CW
924 $newFileName = Civi::paths()->getPath('[civicrm.files]/persist/crm-ckeditor-default.js');
925 file_put_contents($newFileName, $config);
7ad5ae6a 926 }
7ad5ae6a
CW
927 return TRUE;
928 }
929
6cc25669 930}