Merge pull request #10166 from aydun/CRM-19464-upgrade
[civicrm-core.git] / CRM / Upgrade / Incremental / php / FourSeven.php
... / ...
CommitLineData
1<?php
2/*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2017 |
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/**
28 * Upgrade logic for 4.7
29 */
30class CRM_Upgrade_Incremental_php_FourSeven extends CRM_Upgrade_Incremental_Base {
31
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 *
38 * @param string $preUpgradeMessage
39 * @param string $rev
40 * a version number, e.g. '4.4.alpha1', '4.4.beta3', '4.4.0'.
41 * @param null $currentVer
42 */
43 public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL) {
44 if ($rev == '4.7.alpha1') {
45 // CRM-16478 Remove custom fatal error template path option
46 $config = CRM_Core_Config::singleton();
47 if (!empty($config->fatalErrorTemplate) && $config->fatalErrorTemplate != 'CRM/common/fatal.tpl') {
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 }
50 }
51 if ($rev == '4.7.alpha4') {
52 // CRM-17004 Warn of Moneris removal
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')) {
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 }
62 if ($rev == '4.7.13') {
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 }
65 }
66
67 /**
68 * Compute any messages which should be displayed after upgrade.
69 *
70 * @param string $postUpgradeMessage
71 * alterable.
72 * @param string $rev
73 * an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs.
74 */
75 public function setPostUpgradeMessage(&$postUpgradeMessage, $rev) {
76 if ($rev == '4.7.alpha1') {
77 $config = CRM_Core_Config::singleton();
78 // FIXME: Performing an upgrade step during postUpgrade message phase is probably bad
79 $editor_id = self::updateWysiwyg();
80 $msg = NULL;
81 $ext_href = 'href="' . CRM_Utils_System::url('civicrm/admin/extensions', 'reset=1') . '"';
82 $dsp_href = 'href="' . CRM_Utils_System::url('civicrm/admin/setting/preferences/display', 'reset=1') . '"';
83 $blog_href = 'href="https://civicrm.org/blogs/colemanw/big-changes-wysiwyg-editing-47"';
84 switch ($editor_id) {
85 // TinyMCE
86 case 1:
87 $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));
88 break;
89
90 // Drupal/Joomla editor
91 case 3:
92 case 4:
93 $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));
94 break;
95 }
96 if ($msg) {
97 $postUpgradeMessage .= '<p>' . $msg . '</p>';
98 }
99 $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>';
100
101 $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).');
102
103 $postUpgradeMessage .= '<p>' . ts('The custom fatal error template setting has been removed.') . '</p>';
104 }
105 //if ($rev == '4.7.11') {
106 // $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'");
107 //}
108 if ($rev == '4.7.11') {
109 $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'.");
110 }
111 if ($rev == '4.7.14') {
112 $ck_href = 'href="' . CRM_Utils_System::url('civicrm/admin/ckeditor') . '"';
113 $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.')
114 . '<br />' . ts('You can re-enable it by visitng the <a %1>CKEditor Config</a> screen and setting "fullPage = true" under the Advanced Options of the CiviMail preset.', array(1 => $ck_href))
115 . '</p>';
116 }
117 if ($rev == '4.7.19') {
118 $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></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).');
119 $check = CRM_Core_DAO::singleValueQuery("SELECT count(id) FROM civicrm_domain");
120 $smsCheck = CRM_Core_DAO::singleValueQuery("SELECT count(id) FROM civicrm_sms_provider");
121 if ($check > 1 && (bool) $smsCheck) {
122 $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>';
123 }
124 }
125 }
126
127 /**
128 * Upgrade function.
129 *
130 * @param string $rev
131 */
132 public function upgrade_4_7_alpha1($rev) {
133 $this->addTask('Drop action scheudle mapping foreign key', 'dropActionScheudleMappingForeignKey');
134 $this->addTask('Migrate \'on behalf of\' information to module_data', 'migrateOnBehalfOfInfo');
135 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
136 $this->addTask(ts('Migrate Settings to %1', array(1 => $rev)), 'migrateSettings', $rev);
137 $this->addTask('Add Getting Started dashlet', 'addGettingStartedDashlet', $rev);
138 }
139
140 /**
141 * Upgrade function.
142 *
143 * @param string $rev
144 */
145 public function upgrade_4_7_alpha4($rev) {
146 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
147 $this->addTask(ts('Remove %1', array(1 => 'Moneris')), 'removePaymentProcessorType', 'Moneris');
148 $this->addTask('Update Smart Groups', 'fixContactTypeInSmartGroups');
149 }
150
151 /**
152 * Upgrade function.
153 *
154 * @param string $rev
155 */
156 public function upgrade_4_7_beta2($rev) {
157 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
158 $this->addTask('Delete unused file', 'deleteVersionCheckCacheFile');
159 }
160
161 /**
162 * Upgrade function.
163 *
164 * @param string $rev
165 */
166 public function upgrade_4_7_beta6($rev) {
167 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
168 $this->addTask('Disable flexible jobs extension', 'disableFlexibleJobsExtension');
169 $this->addTask('Add Index to financial_trxn trxn_id field', 'addIndexFinancialTrxnTrxnID');
170 }
171
172 /**
173 * Upgrade function.
174 *
175 * @param string $rev
176 */
177 public function upgrade_4_7_1($rev) {
178 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
179 $this->addTask('Add Index to civicrm_contribution creditnote_id field', 'addIndexContributionCreditNoteID');
180 }
181
182 /**
183 * Upgrade function.
184 *
185 * @param string $rev
186 */
187 public function upgrade_4_7_2($rev) {
188 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
189 $this->addTask('Fix Index on civicrm_financial_item combined entity_id + entity_table', 'addCombinedIndexFinancialItemEntityIDEntityType');
190 $this->addTask('enable financial account relationships for chargeback & refund', 'addRefundAndChargeBackAccountsIfNotExist');
191 $this->addTask('Add Index to civicrm_contribution.source', 'addIndexContributionSource');
192 }
193
194 /**
195 * Upgrade function.
196 *
197 * @param string $rev
198 */
199 public function upgrade_4_7_3($rev) {
200 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
201 $this->addTask('Add Index to civicrm_contribution.total_amount', 'addIndexContributionAmount');
202 }
203
204 /**
205 * Upgrade function.
206 *
207 * @param string $rev
208 */
209 public function upgrade_4_7_4($rev) {
210 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
211 $this->addTask('Add Contact Deleted by Merge Activity Type', 'addDeletedByMergeActivityType');
212 }
213
214 /**
215 * Upgrade function.
216 *
217 * @param string $rev
218 */
219 public function upgrade_4_7_7($rev) {
220 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
221 // https://issues.civicrm.org/jira/browse/CRM-18006
222 if (CRM_Core_DAO::checkTableExists('civicrm_install_canary')) {
223 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_install_canary ENGINE=InnoDB');
224 }
225 }
226
227 /**
228 * Upgrade function.
229 *
230 * @param string $rev
231 */
232 public function upgrade_4_7_8($rev) {
233 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
234 $this->addTask('Upgrade mailing foreign key constraints', 'upgradeMailingFKs');
235 }
236
237 /**
238 * Upgrade function.
239 *
240 * @param string $rev
241 */
242 public function upgrade_4_7_10($rev) {
243 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
244 $this->addTask('Upgrade Add Help Pre and Post Fields to price value table', 'addHelpPreAndHelpPostFieldsPriceFieldValue');
245 $this->addTask('Alter index and type for image URL', 'alterIndexAndTypeForImageURL');
246 }
247
248 /**
249 * Upgrade function.
250 *
251 * @param string $rev
252 */
253 public function upgrade_4_7_11($rev) {
254 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
255 $this->addTask('Dashboard schema updates', 'dashboardSchemaUpdate');
256 $this->addTask('Fill in setting "remote_profile_submissions"', 'migrateRemoteSubmissionsSetting');
257 }
258
259 /**
260 * Upgrade function.
261 *
262 * @param string $rev
263 */
264 public function upgrade_4_7_12($rev) {
265 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
266 $this->addTask('Add Data Type column to civicrm_option_group', 'addDataTypeColumnToOptionGroupTable');
267 }
268 /**
269 * Upgrade function.
270 *
271 * @param string $rev
272 */
273 public function upgrade_4_7_13($rev) {
274 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
275 $this->addTask('CRM-19372 - Add column to allow for payment processors to set what card types are accepted', 'addColumn',
276 'civicrm_payment_processor', 'accepted_credit_cards', "text DEFAULT NULL COMMENT 'array of accepted credit card types'");
277 }
278
279 /**
280 * Upgrade function.
281 *
282 * @param string $rev
283 */
284 public function upgrade_4_7_14($rev) {
285 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
286 $this->addTask('Add WYSIWYG Editor Presets', 'addWysiwygPresets');
287 }
288
289 /**
290 * Upgrade function.
291 *
292 * @param string $rev
293 */
294 public function upgrade_4_7_15($rev) {
295 $this->addTask('CRM-19626 - Add min_amount column to civicrm_price_set', 'addColumn',
296 'civicrm_price_set', 'min_amount', "INT(10) UNSIGNED DEFAULT '0' COMMENT 'Minimum Amount required for this set.'");
297 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
298 }
299
300 /**
301 * Upgrade function.
302 *
303 * @param string $rev
304 */
305 public function upgrade_4_7_16($rev) {
306 $this->addTask('CRM-19723 - Add icon column to civicrm_option_value', 'addColumn',
307 'civicrm_option_value', 'icon', "varchar(255) COMMENT 'crm-i icon class' DEFAULT NULL");
308 $this->addTask('CRM-19769 - Add color column to civicrm_tag', 'addColumn',
309 'civicrm_tag', 'color', "varchar(255) COMMENT 'Hex color value e.g. #ffffff' DEFAULT NULL");
310 $this->addTask('CRM-19779 - Add color column to civicrm_option_value', 'addColumn',
311 'civicrm_option_value', 'color', "varchar(255) COMMENT 'Hex color value e.g. #ffffff' DEFAULT NULL");
312 $this->addTask('Add new CiviMail fields', 'addMailingTemplateType');
313 $this->addTask('CRM-19770 - Add is_star column to civicrm_activity', 'addColumn',
314 'civicrm_activity', 'is_star', "tinyint DEFAULT '0' COMMENT 'Activity marked as favorite.'");
315 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
316 }
317
318 /**
319 * Upgrade function.
320 *
321 * @param string $rev
322 */
323 public function upgrade_4_7_18($rev) {
324 $this->addTask('Update Kenyan Provinces', 'updateKenyanProvinces');
325 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
326 }
327
328 /**
329 * Upgrade function.
330 *
331 * @param string $rev
332 */
333 public function upgrade_4_7_19($rev) {
334 $query = "SELECT id FROM civicrm_financial_account WHERE opening_balance <> 0 OR current_period_opening_balance <> 0";
335 $result = CRM_Core_DAO::executeQuery($query);
336 if (!$result->N) {
337 $this->addTask('Drop Column current_period_opening_balance From civicrm_financial_account table.', 'dropColumn', 'civicrm_financial_account', 'current_period_opening_balance');
338 $this->addTask('Drop Column opening_balance From civicrm_financial_account table.', 'dropColumn', 'civicrm_financial_account', 'opening_balance');
339 }
340 $this->addTask('CRM-19961 - Add domain_id column to civicrm_sms_provider', 'addColumn',
341 'civicrm_sms_provider', 'domain_id', 'int(10) unsigned', "Which Domain is this sms provier for");
342 $this->addTask('CRM-19961 - Populate domain id table and perhaps add foreign key', 'populateSMSProviderDomainId');
343 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
344 $this->addTask('CRM-16633 - Add "Change Case Subject" activity', 'addChangeCaseSubjectActivityType');
345 $this->addTask('Add is_public column to civicrm_custom_group', 'addColumn',
346 'civicrm_custom_group', 'is_public', "boolean DEFAULT '1' COMMENT 'Is this property public?'");
347 }
348
349 /*
350 * Important! All upgrade functions MUST add a 'runSql' task.
351 * Uncomment and use the following template for a new upgrade version
352 * (change the x in the function name):
353 */
354
355 // /**
356 // * Upgrade function.
357 // *
358 // * @param string $rev
359 // */
360 // public function upgrade_4_7_x($rev) {
361 // $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
362 // // Additional tasks here...
363 // // Note: do not use ts() in the addTask description because it adds unnecessary strings to transifex.
364 // // The above is an exception because 'Upgrade DB to %1: SQL' is generic & reusable.
365 // }
366
367 /**
368 * CRM-16354
369 *
370 * @return int
371 */
372 public static function updateWysiwyg() {
373 $editorID = Civi::settings()->get('editor_id');
374 // Previously a numeric value indicated one of 4 wysiwyg editors shipped in core, and no value indicated 'Textarea'
375 // Now the options are "Textarea", "CKEditor", and the rest have been dropped from core.
376 $newEditor = $editorID ? "CKEditor" : "Textarea";
377 Civi::settings()->set('editor_id', $newEditor);
378
379 return $editorID;
380 }
381
382 /**
383 * Migrate any last remaining options from `civicrm_domain.config_backend` to `civicrm_setting`.
384 * Cleanup setting schema.
385 *
386 * @param CRM_Queue_TaskContext $ctx
387 * @return bool
388 */
389 public static function migrateSettings(CRM_Queue_TaskContext $ctx) {
390 // Tip: If there are problems with adding the new uniqueness index, try inspecting:
391 // SELECT name, domain_id, contact_id, count(*) AS dupes FROM civicrm_setting cs GROUP BY name, domain_id, contact_id HAVING dupes > 1;
392
393 // Nav records are expendable. https://forum.civicrm.org/index.php?topic=36933.0
394 CRM_Core_DAO::executeQuery('DELETE FROM civicrm_setting WHERE contact_id IS NOT NULL AND name = "navigation"');
395
396 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_setting DROP INDEX index_group_name');
397 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_setting DROP COLUMN group_name');
398
399 // Handle Strange activity_tab_filter settings.
400 CRM_Core_DAO::executeQuery('CREATE TABLE civicrm_activity_setting LIKE civicrm_setting');
401 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_activity_setting ADD UNIQUE INDEX index_domain_contact_name (domain_id, contact_id, name)');
402 CRM_Core_DAO::executeQuery('INSERT INTO civicrm_activity_setting (name, contact_id, domain_id, value)
403 SELECT DISTINCT name, contact_id, domain_id, value
404 FROM civicrm_setting
405 WHERE name = "activity_tab_filter"
406 AND value is not NULL');
407 CRM_Core_DAO::executeQuery('DELETE FROM civicrm_setting WHERE name = "activity_tab_filter"');
408
409 $date = CRM_Utils_Time::getTime('Y-m-d H:i:s');
410 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_setting ADD UNIQUE INDEX index_domain_contact_name (domain_id, contact_id, name)');
411 CRM_Core_DAO::executeQuery("INSERT INTO civicrm_setting (name, contact_id, domain_id, value, is_domain, created_id, created_date)
412 SELECT name, contact_id, domain_id, value, 0, contact_id,'$date'
413 FROM civicrm_activity_setting
414 WHERE name = 'activity_tab_filter'
415 AND value is not NULL"
416 );
417 CRM_Core_DAO::executeQuery('DROP TABLE civicrm_activity_setting');
418
419 $domainDao = CRM_Core_DAO::executeQuery('SELECT id, config_backend FROM civicrm_domain');
420 while ($domainDao->fetch()) {
421 $settings = CRM_Upgrade_Incremental_php_FourSeven::convertBackendToSettings($domainDao->id, $domainDao->config_backend);
422 CRM_Core_Error::debug_var('convertBackendToSettings', array(
423 'domainId' => $domainDao->id,
424 'backend' => $domainDao->config_backend,
425 'settings' => $settings,
426 ));
427
428 foreach ($settings as $name => $value) {
429 $rowParams = array(
430 1 => array($domainDao->id, 'Positive'),
431 2 => array($name, 'String'),
432 3 => array(serialize($value), 'String'),
433 );
434 $settingId = CRM_Core_DAO::singleValueQuery(
435 'SELECT id FROM civicrm_setting WHERE domain_id = %1 AND name = %2',
436 $rowParams);
437 if (!$settingId) {
438 CRM_Core_DAO::executeQuery(
439 'INSERT INTO civicrm_setting (domain_id, name, value, is_domain) VALUES (%1,%2,%3,1)',
440 $rowParams);
441 }
442 }
443 }
444
445 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_domain DROP COLUMN config_backend');
446
447 return TRUE;
448 }
449
450 /**
451 * Take a config_backend blob and produce an equivalent list of settings.
452 *
453 * @param int $domainId
454 * Domain ID.
455 * @param string $config_backend
456 * Serialized blob.
457 * @return array
458 */
459 public static function convertBackendToSettings($domainId, $config_backend) {
460 if (!$config_backend) {
461 return array();
462 }
463
464 $backend = unserialize($config_backend);
465 if (!$backend) {
466 return array();
467 }
468
469 $mappings = \CRM_Core_Config_MagicMerge::getPropertyMap();
470 $settings = array();
471 foreach ($backend as $propertyName => $propertyValue) {
472 if (isset($mappings[$propertyName][0]) && preg_match('/^setting/', $mappings[$propertyName][0])) {
473 // $mapping format: $propertyName => Array(0 => $type, 1 => $setting|NULL).
474 $settingName = isset($mappings[$propertyName][1]) ? $mappings[$propertyName][1] : $propertyName;
475 $settings[$settingName] = $propertyValue;
476 }
477 }
478
479 return $settings;
480 }
481
482 /**
483 * Add Getting Started dashlet to dashboard
484 *
485 * @param \CRM_Queue_TaskContext $ctx
486 *
487 * @return bool
488 */
489 public static function addGettingStartedDashlet(CRM_Queue_TaskContext $ctx) {
490 $sql = "SELECT count(*) FROM civicrm_dashboard WHERE name='getting-started'";
491 $res = CRM_Core_DAO::singleValueQuery($sql);
492 $domainId = CRM_Core_Config::domainID();
493 if ($res <= 0) {
494 $sql = "INSERT INTO `civicrm_dashboard`
495 ( `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)";
496 CRM_Core_DAO::executeQuery($sql);
497 // Add default position for Getting Started Dashlet ( left column)
498 $sql = "INSERT INTO `civicrm_dashboard_contact` (dashboard_id, contact_id, column_no, is_active)
499SELECT (SELECT MAX(id) FROM `civicrm_dashboard`), contact_id, 0, IF (SUM(is_active) > 0, 1, 0)
500FROM `civicrm_dashboard_contact` JOIN `civicrm_contact` WHERE civicrm_dashboard_contact.contact_id = civicrm_contact.id GROUP BY contact_id";
501 CRM_Core_DAO::executeQuery($sql);
502 }
503 return TRUE;
504 }
505
506 /**
507 * Migrate on-behalf information to uf_join.module_data as on-behalf columns will be dropped
508 * on DB upgrade
509 *
510 * @param CRM_Queue_TaskContext $ctx
511 *
512 * @return bool
513 * TRUE for success
514 */
515 public static function migrateOnBehalfOfInfo(CRM_Queue_TaskContext $ctx) {
516 $domain = new CRM_Core_DAO_Domain();
517 $domain->find(TRUE);
518
519 // fetch onBehalf entry in UFJoin table
520 $ufGroupDAO = new CRM_Core_DAO_UFJoin();
521 $ufGroupDAO->module = 'OnBehalf';
522 $ufGroupDAO->find(TRUE);
523
524 $forOrgColums = array('is_for_organization');
525 if ($domain->locales) {
526 $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);
527 foreach ($locales as $locale) {
528 $forOrgColums[] = "for_organization_{$locale}";
529 }
530 }
531 else {
532 $forOrgColums[] = "for_organization";
533 }
534
535 $query = "
536 SELECT " . implode(", ", $forOrgColums) . ", uj.id as join_id, uj.uf_group_id as uf_group_id
537 FROM civicrm_contribution_page cp
538 INNER JOIN civicrm_uf_join uj ON uj.entity_id = cp.id AND uj.module = 'OnBehalf'";
539 $dao = CRM_Core_DAO::executeQuery($query, array(), TRUE, NULL, FALSE, FALSE);
540
541 if ($dao->N) {
542 while ($dao->fetch()) {
543 $onBehalfParams['on_behalf'] = array('is_for_organization' => $dao->is_for_organization);
544 if ($domain->locales) {
545 foreach ($locales as $locale) {
546 $for_organization = "for_organization_{$locale}";
547 $onBehalfParams['on_behalf'] += array(
548 $locale => array(
549 'for_organization' => $dao->$for_organization,
550 ),
551 );
552 }
553 }
554 else {
555 $onBehalfParams['on_behalf'] += array(
556 'default' => array(
557 'for_organization' => $dao->for_organization,
558 ),
559 );
560 }
561 $ufJoinParam = array(
562 'id' => $dao->join_id,
563 'module' => 'on_behalf',
564 'uf_group_id' => $dao->uf_group_id,
565 'module_data' => json_encode($onBehalfParams),
566 );
567 CRM_Core_BAO_UFJoin::create($ufJoinParam);
568 }
569 }
570
571 return TRUE;
572 }
573
574 /**
575 * v4.7.11 adds a new setting "remote_profile_submissions". This is
576 * long-standing feature that existing sites may be using; however, it's
577 * a bit prone to abuse. For new sites, the default is to disable it
578 * (since that is more secure). For existing sites, the default is to
579 * enable it (since that is more compatible).
580 *
581 * @param \CRM_Queue_TaskContext $ctx
582 *
583 * @return bool
584 */
585 public static function migrateRemoteSubmissionsSetting(CRM_Queue_TaskContext $ctx) {
586 $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");
587 while ($domains->fetch()) {
588 CRM_Core_DAO::executeQuery(
589 "INSERT INTO civicrm_setting (`name`, `value`, `domain_id`, `is_domain`, `contact_id`, `component_id`, `created_date`, `created_id`)
590 VALUES (%2, %3, %4, %5, NULL, NULL, %6, NULL)",
591 array(
592 2 => array('remote_profile_submissions', 'String'),
593 3 => array('s:1:"1";', 'String'),
594 4 => array($domains->id, 'Integer'),
595 5 => array(1, 'Integer'),
596 6 => array(date('Y-m-d H:i:s'), 'String'),
597 )
598 );
599 }
600 return TRUE;
601 }
602
603 /**
604 * CRM-11782 - Get rid of VALUE_SEPARATOR character in saved search form values
605 *
606 * @param \CRM_Queue_TaskContext $ctx
607 *
608 * @return bool
609 */
610 public static function fixContactTypeInSmartGroups(CRM_Queue_TaskContext $ctx) {
611 $sep = CRM_Core_DAO::VALUE_SEPARATOR;
612 $dao = CRM_Core_DAO::executeQuery("SELECT id, form_values FROM civicrm_saved_search WHERE form_values LIKE '%$sep%'");
613 while ($dao->fetch()) {
614 $formValues = unserialize($dao->form_values);
615 if (isset($formValues['contact_type']) && is_array($formValues['contact_type'])) {
616 $newVals = array();
617 foreach ($formValues['contact_type'] as $key => $val) {
618 $newVals[str_replace($sep, '__', $key)] = is_string($val) ? str_replace($sep, '__', $val) : $val;
619 }
620 $formValues['contact_type'] = $newVals;
621 }
622 CRM_Core_DAO::executeQuery("UPDATE civicrm_saved_search SET form_values = %1 WHERE id = {$dao->id}", array(1 => array(serialize($formValues), 'String')));
623 }
624
625 return TRUE;
626 }
627
628 /**
629 * CRM-17637 - Ths file location has been moved; delete the old one
630 *
631 * @param \CRM_Queue_TaskContext $ctx
632 *
633 * @return bool
634 */
635 public static function deleteVersionCheckCacheFile(CRM_Queue_TaskContext $ctx) {
636 $config = CRM_Core_Config::singleton();
637 $cacheFile = $config->uploadDir . 'version-info-cache.json';
638 if (file_exists($cacheFile)) {
639 unlink($cacheFile);
640 }
641 return TRUE;
642 }
643
644 /**
645 * CRM-17669 and CRM-17686, make scheduled jobs more flexible, disable the 4.6 extension if installed
646 *
647 * @param \CRM_Queue_TaskContext $ctx
648 *
649 * @return bool
650 */
651 public static function disableFlexibleJobsExtension(CRM_Queue_TaskContext $ctx) {
652 try {
653 civicrm_api3('Extension', 'disable', array('key' => 'com.klangsoft.flexiblejobs'));
654 }
655 catch (CiviCRM_API3_Exception $e) {
656 // just ignore if the extension isn't installed
657 }
658
659 return TRUE;
660 }
661
662 /**
663 * CRM-17752 add index to civicrm_financial_trxn.trxn_id (deliberately non-unique).
664 *
665 * @param \CRM_Queue_TaskContext $ctx
666 *
667 * @return bool
668 */
669 public static function addIndexFinancialTrxnTrxnID(CRM_Queue_TaskContext $ctx) {
670 $tables = array('civicrm_financial_trxn' => array('trxn_id'));
671 CRM_Core_BAO_SchemaHandler::createIndexes($tables);
672 return TRUE;
673 }
674
675 /**
676 * CRM-17882 Add index to civicrm_contribution.credit_note_id.
677 *
678 * @param \CRM_Queue_TaskContext $ctx
679 *
680 * @return bool
681 */
682 public static function addIndexContributionCreditNoteID(CRM_Queue_TaskContext $ctx) {
683 $tables = array('civicrm_contribution' => array('creditnote_id'));
684 CRM_Core_BAO_SchemaHandler::createIndexes($tables);
685 return TRUE;
686 }
687
688 /**
689 * CRM-17775 Add correct index for table civicrm_financial_item.
690 *
691 * Note that the entity ID should always precede the entity_table as
692 * it is more unique. This is better for performance and does not cause fallback
693 * to no index if table it omitted.
694 *
695 * @return bool
696 */
697 public static function addCombinedIndexFinancialItemEntityIDEntityType() {
698 CRM_Core_BAO_SchemaHandler::dropIndexIfExists('civicrm_financial_item', 'UI_id');
699 CRM_Core_BAO_SchemaHandler::dropIndexIfExists('civicrm_financial_item', 'IX_Entity');
700 CRM_Core_BAO_SchemaHandler::createIndexes(array(
701 'civicrm_financial_item' => array(array('entity_id', 'entity_table')),
702 ));
703 return TRUE;
704 }
705
706 /**
707 * CRM-17951 Add accounts option values for refund and chargeback.
708 *
709 * Add Chargeback contribution status and Chargeback and Contra account relationships,
710 * checking first if one exists.
711 */
712 public static function addRefundAndChargeBackAccountsIfNotExist() {
713 // First we enable and edit the record for Credit contra - this exists but is disabled for most sites.
714 // Using the ensure function (below) will not enabled a disabled option (by design).
715 CRM_Core_DAO::executeQuery("UPDATE civicrm_option_value v
716 INNER JOIN civicrm_option_group g on v.option_group_id=g.id and g.name='account_relationship'
717 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'
718 WHERE v.name = 'Credit/Contra Account is';");
719
720 CRM_Core_BAO_OptionValue::ensureOptionValueExists(array(
721 'option_group_id' => 'account_relationship',
722 'name' => 'Chargeback Account is',
723 'label' => ts('Chargeback Account is'),
724 'is_active' => TRUE,
725 'component_id' => 'CiviContribute',
726 ));
727
728 CRM_Core_BAO_OptionValue::ensureOptionValueExists(array(
729 'option_group_id' => 'contribution_status',
730 'name' => 'Chargeback',
731 'label' => ts('Chargeback'),
732 'is_active' => TRUE,
733 'component_id' => 'CiviContribute',
734 ));
735 return TRUE;
736 }
737
738 /**
739 * CRM-17999 Add index to civicrm_contribution.source.
740 *
741 * @param \CRM_Queue_TaskContext $ctx
742 *
743 * @return bool
744 */
745 public static function addIndexContributionSource(CRM_Queue_TaskContext $ctx) {
746 CRM_Core_BAO_SchemaHandler::createIndexes(array('civicrm_contribution' => array('source')));
747 return TRUE;
748 }
749
750 /**
751 * CRM-18124 Add index to civicrm_contribution.total_amount.
752 *
753 * Note that I made this a combined index with receive_date because the issue included
754 * both criteria and they seemed likely to be used in conjunction to me in other cases.
755 *
756 * @param \CRM_Queue_TaskContext $ctx
757 *
758 * @return bool
759 */
760 public static function addIndexContributionAmount(CRM_Queue_TaskContext $ctx) {
761 CRM_Core_BAO_SchemaHandler::createIndexes(array(
762 'civicrm_contribution' => array(array('total_amount', 'receive_date')),
763 ));
764 return TRUE;
765 }
766
767 /**
768 * CRM-18124 Add index to civicrm_contribution.total_amount.
769 *
770 * Note that I made this a combined index with receive_date because the issue included
771 * both criteria and they seemed likely to be used in conjunction to me in other cases.
772 *
773 * @param \CRM_Queue_TaskContext $ctx
774 *
775 * @return bool
776 */
777 public static function addDeletedByMergeActivityType(CRM_Queue_TaskContext $ctx) {
778 CRM_Core_BAO_OptionValue::ensureOptionValueExists(array(
779 'option_group_id' => 'activity_type',
780 'name' => 'Contact Deleted by Merge',
781 'label' => ts('Contact Deleted by Merge'),
782 'description' => ts('Contact was merged into another contact'),
783 'is_active' => TRUE,
784 'filter' => 1,
785 ));
786 return TRUE;
787 }
788
789 /**
790 * CRM-12252 Add Help Pre and Help Post Fields for Price Field Value Table.
791 *
792 * @param \CRM_Queue_TaskContext $ctx
793 *
794 * @return bool
795 */
796 public static function addHelpPreAndHelpPostFieldsPriceFieldValue(CRM_Queue_TaskContext $ctx) {
797 $domain = new CRM_Core_DAO_Domain();
798 $domain->find(TRUE);
799 if ($domain->locales) {
800 $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);
801 foreach ($locales as $locale) {
802 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists("civicrm_price_field_value", "help_pre_{$locale}")) {
803 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_price_field_value`
804 ADD COLUMN `help_pre_{$locale}` text COLLATE utf8_unicode_ci COMMENT 'Price field option pre help text.'", array(), TRUE, NULL, FALSE, FALSE);
805 }
806 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists("civicrm_price_field_value", "help_post_{$locale}")) {
807 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_price_field_value`
808 ADD COLUMN `help_post_{$locale}` text COLLATE utf8_unicode_ci COMMENT 'Price field option post help text.'", array(), TRUE, NULL, FALSE, FALSE);
809 }
810 }
811 CRM_Core_I18n_Schema::rebuildMultilingualSchema($locales, NULL);
812 }
813 else {
814 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_price_field_value', 'help_pre')) {
815 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_price_field_value`
816 ADD COLUMN `help_pre` text COLLATE utf8_unicode_ci COMMENT 'Price field option pre help text.'");
817 }
818 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_price_field_value', 'help_post')) {
819 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_price_field_value`
820 ADD COLUMN `help_post` text COLLATE utf8_unicode_ci COMMENT 'Price field option post help text.'");
821 }
822 }
823 return TRUE;
824 }
825
826 /**
827 * CRM-18464 Check if Foreign key exists and also drop any index of same name accidentially created.
828 *
829 * @param \CRM_Queue_TaskContext $ctx
830 *
831 * @return bool
832 */
833 public static function dropActionScheudleMappingForeignKey(CRM_Queue_TaskContext $ctx) {
834 CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_action_schedule', 'FK_civicrm_action_schedule_mapping_id');
835 return TRUE;
836 }
837
838 /**
839 * CRM-18345 Don't delete mailing data on email/phone deletion
840 * Implemented here in CRM-18526
841 *
842 * @param \CRM_Queue_TaskContext $ctx
843 *
844 * @return bool
845 */
846 public static function upgradeMailingFKs(CRM_Queue_TaskContext $ctx) {
847
848 // Safely drop the foreign keys
849 CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_mailing_event_queue', 'FK_civicrm_mailing_event_queue_email_id');
850 CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_mailing_event_queue', 'FK_civicrm_mailing_event_queue_phone_id');
851 CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_mailing_recipients', 'FK_civicrm_mailing_recipients_email_id');
852 CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_mailing_recipients', 'FK_civicrm_mailing_recipients_phone_id');
853
854 // Set up the new foreign keys
855 CRM_Core_DAO::executeQuery("SET FOREIGN_KEY_CHECKS = 0;");
856
857 CRM_Core_DAO::executeQuery("
858 ALTER TABLE `civicrm_mailing_event_queue`
859 ADD CONSTRAINT `FK_civicrm_mailing_event_queue_email_id`
860 FOREIGN KEY (`email_id`)
861 REFERENCES `civicrm_email`(`id`)
862 ON DELETE SET NULL
863 ON UPDATE RESTRICT;
864 ");
865
866 CRM_Core_DAO::executeQuery("
867 ALTER TABLE `civicrm_mailing_event_queue`
868 ADD CONSTRAINT `FK_civicrm_mailing_event_queue_phone_id`
869 FOREIGN KEY (`phone_id`)
870 REFERENCES `civicrm_phone`(`id`)
871 ON DELETE SET NULL
872 ON UPDATE RESTRICT;
873 ");
874
875 CRM_Core_DAO::executeQuery("
876 ALTER TABLE `civicrm_mailing_recipients`
877 ADD CONSTRAINT `FK_civicrm_mailing_recipients_email_id`
878 FOREIGN KEY (`email_id`)
879 REFERENCES `civicrm_email`(`id`)
880 ON DELETE SET NULL
881 ON UPDATE RESTRICT;
882 ");
883
884 CRM_Core_DAO::executeQuery("
885 ALTER TABLE `civicrm_mailing_recipients`
886 ADD CONSTRAINT `FK_civicrm_mailing_recipients_phone_id`
887 FOREIGN KEY (`phone_id`)
888 REFERENCES `civicrm_phone`(`id`)
889 ON DELETE SET NULL
890 ON UPDATE RESTRICT;
891 ");
892
893 CRM_Core_DAO::executeQuery("SET FOREIGN_KEY_CHECKS = 1;");
894
895 return TRUE;
896 }
897
898 /**
899 * CRM-17663 - Dashboard schema changes
900 *
901 * @param \CRM_Queue_TaskContext $ctx
902 *
903 * @return bool
904 */
905 public static function dashboardSchemaUpdate(CRM_Queue_TaskContext $ctx) {
906 if (!CRM_Core_BAO_SchemaHandler::checkIfIndexExists('civicrm_dashboard_contact', 'index_dashboard_id_contact_id')) {
907 // Delete any stray duplicate rows and add unique index to prevent new dupes and enable INSERT/UPDATE combo query
908 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');
909 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_dashboard_contact ADD UNIQUE INDEX index_dashboard_id_contact_id (dashboard_id, contact_id);');
910 }
911 $domain = new CRM_Core_DAO_Domain();
912 $domain->find(TRUE);
913 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard_contact', 'content');
914 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard_contact', 'is_minimized');
915 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard_contact', 'is_fullscreen');
916 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard_contact', 'created_date');
917 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard', 'is_fullscreen');
918 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard', 'is_minimized');
919 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard', 'column_no');
920 CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard', 'weight');
921
922 CRM_Core_DAO::executeQuery('UPDATE civicrm_dashboard SET url = REPLACE(url, "&snippet=5", ""), fullscreen_url = REPLACE(fullscreen_url, "&snippet=5", "")');
923
924 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_dashboard', 'cache_minutes')) {
925 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."',
926 array(), TRUE, NULL, FALSE, FALSE);
927 }
928 if ($domain->locales) {
929 $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);
930 CRM_Core_I18n_Schema::rebuildMultilingualSchema($locales, NULL);
931 }
932
933 CRM_Core_DAO::executeQuery('UPDATE civicrm_dashboard SET cache_minutes = 1440 WHERE name = "blog"');
934 CRM_Core_DAO::executeQuery('UPDATE civicrm_dashboard SET cache_minutes = 7200 WHERE name IN ("activity","getting-started")');
935 return TRUE;
936 }
937
938 /**
939 * CRM-19100 - Alter Index and Type for Image URL
940 * @return bool
941 */
942 public static function alterIndexAndTypeForImageURL() {
943 $length = array();
944 CRM_Core_BAO_SchemaHandler::dropIndexIfExists('civicrm_contact', 'index_image_url');
945 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.'");
946
947 $length['civicrm_contact']['image_URL'] = 128;
948 CRM_Core_BAO_SchemaHandler::createIndexes(array('civicrm_contact' => array('image_URL')), 'index', $length);
949
950 return TRUE;
951 }
952
953 /**
954 * Add mailing template type.
955 *
956 * @return bool
957 */
958 public static function addMailingTemplateType() {
959 if (!CRM_Core_DAO::checkFieldExists('civicrm_mailing', 'template_type', FALSE)) {
960 CRM_Core_DAO::executeQuery('
961 ALTER TABLE civicrm_mailing
962 ADD COLUMN `template_type` varchar(64) NOT NULL DEFAULT \'traditional\' COMMENT \'The language/processing system used for email templates.\',
963 ADD COLUMN `template_options` longtext COMMENT \'Advanced options used by the email templating system. (JSON encoded)\'
964 ');
965 }
966 return TRUE;
967 }
968
969 /**
970 * CRM-18651 Add DataType column to Option Group Table
971 * @return bool
972 */
973 public static function addDataTypeColumnToOptionGroupTable() {
974 if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_option_group', 'data_type')) {
975 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.'",
976 array(), TRUE, NULL, FALSE, FALSE);
977 }
978 $domain = new CRM_Core_DAO_Domain();
979 $domain->find(TRUE);
980 if ($domain->locales) {
981 $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);
982 CRM_Core_I18n_Schema::rebuildMultilingualSchema($locales, NULL);
983 }
984
985 CRM_Core_DAO::executeQuery("UPDATE `civicrm_option_group` SET `data_type` = 'Integer'
986 WHERE name IN ('activity_type', 'gender', 'payment_instrument', 'participant_role', 'event_type')");
987 return TRUE;
988 }
989
990 /**
991 * CRM-19372 Add field to store accepted credit credit cards for a payment processor.
992 * @return bool
993 */
994 public static function addWysiwygPresets() {
995 CRM_Core_BAO_OptionGroup::ensureOptionGroupExists(array(
996 'name' => 'wysiwyg_presets',
997 'title' => ts('WYSIWYG Editor Presets'),
998 'is_reserved' => 1,
999 ));
1000 $values = array(
1001 'default' => array('label' => ts('Default'), 'is_default' => 1),
1002 'civimail' => array('label' => ts('CiviMail'), 'component_id' => 'CiviMail'),
1003 'civievent' => array('label' => ts('CiviEvent'), 'component_id' => 'CiviEvent'),
1004 );
1005 foreach ($values as $name => $value) {
1006 CRM_Core_BAO_OptionValue::ensureOptionValueExists($value + array(
1007 'name' => $name,
1008 'option_group_id' => 'wysiwyg_presets',
1009 ));
1010 }
1011 $fileName = Civi::paths()->getPath('[civicrm.files]/persist/crm-ckeditor-config.js');
1012 // Ensure the config file contains the allowedContent setting
1013 if (file_exists($fileName)) {
1014 $config = file_get_contents($fileName);
1015 $pos = strrpos($config, '};');
1016 $setting = "\n\tconfig.allowedContent = true;\n";
1017 $config = substr_replace($config, $setting, $pos, 0);
1018 unlink($fileName);
1019 $newFileName = Civi::paths()->getPath('[civicrm.files]/persist/crm-ckeditor-default.js');
1020 file_put_contents($newFileName, $config);
1021 }
1022 return TRUE;
1023 }
1024
1025 /**
1026 * Update Kenyan Provinces to reflect changes per CRM-20062
1027 *
1028 * @param \CRM_Queue_TaskContext $ctx
1029 */
1030 public function updateKenyanProvinces(CRM_Queue_TaskContext $ctx) {
1031 $kenyaCountryID = CRM_Core_DAO::singleValueQuery('SELECT max(id) from civicrm_country where iso_code = "KE"');
1032 $oldProvinces = array(
1033 'Nairobi Municipality',
1034 'Coast',
1035 'North-Eastern Kaskazini Mashariki',
1036 'Rift Valley',
1037 'Western Magharibi',
1038 );
1039 self::deprecateStateProvinces($kenyaCountryID, $oldProvinces);
1040 return TRUE;
1041 }
1042
1043 /**
1044 * Deprecate provinces that no longer exist.
1045 *
1046 * @param int $countryID
1047 * @param array $provinces
1048 */
1049 public static function deprecateStateProvinces($countryID, $provinces) {
1050 foreach ($provinces as $province) {
1051 $existingStateID = CRM_Core_DAO::singleValueQuery("
1052 SELECT id FROM civicrm_state_province
1053 WHERE country_id = %1
1054 AND name = %2
1055 ",
1056 array(1 => array($countryID, 'Int'), 2 => array($province, 'String')));
1057
1058 if (!$existingStateID) {
1059 continue;
1060 }
1061 if (!CRM_Core_DAO::singleValueQuery("
1062 SELECT count(*) FROM civicrm_address
1063 WHERE state_province_id = %1
1064 ", array(1 => array($existingStateID, 'Int')))
1065 ) {
1066 CRM_Core_DAO::executeQuery("DELETE FROM civicrm_state_province WHERE id = %1", array(1 => array($existingStateID, 'Int')));
1067 }
1068 else {
1069 $params = array('1' => array(ts("Former - $province"), 'String'));
1070 CRM_Core_DAO::executeQuery("
1071 UPDATE civicrm_state_province SET name = %1 WHERE id = $existingStateID
1072 ", $params);
1073 }
1074 }
1075 }
1076
1077 /**
1078 * CRM-19961
1079 * Poputate newly added domain id column and add foriegn key onto table.
1080 */
1081 public static function populateSMSProviderDomainId() {
1082 $count = CRM_Core_DAO::singleValueQuery("SELECT count(id) FROM civicrm_domain");
1083 if ($count = 1) {
1084 CRM_Core_DAO::executeQuery("UPDATE civicrm_sms_provider SET domain_id = (SELECT id FROM civicrm_domain)");
1085 }
1086 CRM_Core_DAO::executeQuery("SET FOREIGN_KEY_CHECKS = 0;");
1087 CRM_Core_DAO::executeQuery("ALTER TABLE `civicrm_sms_provider`
1088 ADD CONSTRAINT FK_civicrm_sms_provider_domain_id
1089 FOREIGN KEY (`domain_id`) REFERENCES `civicrm_domain`(`id`)
1090 ON DELETE SET NULL");
1091
1092 CRM_Core_DAO::executeQuery("SET FOREIGN_KEY_CHECKS = 1;");
1093 return TRUE;
1094 }
1095
1096 /**
1097 * CRM-16633 - Add activity type for Change Case Status
1098 *
1099 * @param \CRM_Queue_TaskContext $ctx
1100 *
1101 * @return bool
1102 */
1103 public static function addChangeCaseSubjectActivityType(CRM_Queue_TaskContext $ctx) {
1104 CRM_Core_BAO_OptionValue::ensureOptionValueExists(array(
1105 'option_group_id' => 'activity_type',
1106 'name' => 'Change Case Subject',
1107 'label' => ts('Change Case Subject'),
1108 'is_active' => TRUE,
1109 'component_id' => 'CiviCase',
1110 'icon' => 'fa-pencil-square-o',
1111 ));
1112 return TRUE;
1113 }
1114
1115}