Merge pull request #4896 from totten/master-movedep
[civicrm-core.git] / CRM / Upgrade / Incremental / php / FourThree.php
CommitLineData
6a488035
TO
1<?php
2
3/*
4 +--------------------------------------------------------------------+
39de6fd5 5 | CiviCRM version 4.6 |
6a488035 6 +--------------------------------------------------------------------+
06b69b18 7 | Copyright CiviCRM LLC (c) 2004-2014 |
6a488035
TO
8 +--------------------------------------------------------------------+
9 | This file is a part of CiviCRM. |
10 | |
11 | CiviCRM is free software; you can copy, modify, and distribute it |
12 | under the terms of the GNU Affero General Public License |
13 | Version 3, 19 November 2007. |
14 | |
15 | CiviCRM is distributed in the hope that it will be useful, but |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
18 | See the GNU Affero General Public License for more details. |
19 | |
20 | You should have received a copy of the GNU Affero General Public |
21 | License along with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26*/
27
28/**
29 *
30 * @package CRM
06b69b18 31 * @copyright CiviCRM LLC (c) 2004-2014
6a488035
TO
32 * $Id$
33 *
34 */
35class CRM_Upgrade_Incremental_php_FourThree {
36 const BATCH_SIZE = 5000;
37
624e56fa
EM
38 /**
39 * @param $errors
40 *
41 * @return bool
42 */
00be9182 43 public function verifyPreDBstate(&$errors) {
6a488035
TO
44 return TRUE;
45 }
46
505cf9f9
PJ
47 /**
48 * Compute any messages which should be displayed beforeupgrade
49 *
50 * Note: This function is called iteratively for each upcoming
51 * revision to the database.
52 *
77b97be7 53 * @param $preUpgradeMessage
5a4f6742
CW
54 * @param string $rev
55 * a version number, e.g. '4.3.alpha1', '4.3.beta3', '4.3.0'.
77b97be7
EM
56 * @param null $currentVer
57 *
ce4b9629 58 * @return void|bool
505cf9f9 59 */
00be9182 60 public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL) {
7402727c 61 if ($rev == '4.3.beta3') {
505cf9f9
PJ
62 //CRM-12084
63 //sql for checking orphaned contribution records
64 $sql = "SELECT COUNT(ct.id) FROM civicrm_contribution ct LEFT JOIN civicrm_contact c ON ct.contact_id = c.id WHERE c.id IS NULL";
65 $count = CRM_Core_DAO::singleValueQuery($sql, array(), TRUE, FALSE);
66
67 if ($count > 0) {
33421d01 68 $error = ts("There is a data integrity issue with this CiviCRM database. It contains %1 contribution records which are linked to contact records that have been deleted. You will need to correct this manually before you can run the upgrade. Use the following MySQL query to identify the problem records: %2 These records will need to be deleted or linked to an existing contact record.", array(
353ffa53
TO
69 1 => $count,
70 2 => '<em>SELECT ct.* FROM civicrm_contribution ct LEFT JOIN civicrm_contact c ON ct.contact_id = c.id WHERE c.id IS NULL;</em>',
71 ));
505cf9f9
PJ
72 CRM_Core_Error::fatal($error);
73 return FALSE;
74 }
75 }
de65d43e 76 if ($rev == '4.3.beta4' && CRM_Utils_Constant::value('CIVICRM_UF', FALSE) == 'Drupal6') {
70ec93e4
CB
77 // CRM-11823 - Make sure the D6 HTML HEAD technique will work on
78 // upgrade pages ... except when we're in Drush.
79 if (!function_exists('drush_main')) {
80 theme('item_list', array()); // force-load theme registry
81 $theme_registry = theme_get_registry();
82 if (!isset($theme_registry['page']['preprocess functions']) || FALSE === array_search('civicrm_preprocess_page_inject', $theme_registry['page']['preprocess functions'])) {
83 CRM_Core_Error::fatal('Please reset the Drupal cache (Administer => Site Configuration => Performance => Clear cached data))');
84 }
de65d43e
TO
85 }
86 }
77b97be7 87
ce4b9629
CW
88 if ($rev == '4.3.6') {
89 $constraintArray = array(
90 'civicrm_contact' => 'contact_id',
77b97be7 91 'civicrm_payment_processor' => 'payment_processor_id',
ce4b9629 92 );
77b97be7
EM
93
94 if (version_compare('4.1alpha1', $currentVer) <= 0) {
9e1a3f4f
PN
95 $constraintArray['civicrm_campaign'] = 'campaign_id';
96 }
77b97be7
EM
97
98 if (version_compare('4.3alpha1', $currentVer) <= 0) {
9e1a3f4f
PN
99 $constraintArray['civicrm_financial_type'] = 'financial_type_id';
100 }
77b97be7 101
ce4b9629
CW
102 foreach ($constraintArray as $key => $value) {
103 $query = "SELECT contri_recur.id FROM civicrm_contribution_recur contri_recur LEFT JOIN {$key} ON contri_recur.{$value} = {$key}.id
104WHERE {$key}.id IS NULL";
133b8445
PN
105 if ($value != 'contact_id') {
106 $query .= " AND contri_recur.{$value} IS NOT NULL ";
ce4b9629
CW
107 }
108 $dao = CRM_Core_DAO::executeQuery($query);
109 if ($dao->N) {
050743aa 110 $invalidDataMessage = '<strong>Oops, it looks like you have orphaned recurring contribution records in your database. Before this upgrade can complete they will need to be fixed or deleted. <a href="http://wiki.civicrm.org/confluence/display/CRMDOC/Fixing+Orphaned+Contribution+Recur+Records" target="_blank">You can review steps to correct this situation on the documentation wiki.</a></strong>';
ce4b9629
CW
111 CRM_Core_Error::fatal($invalidDataMessage);
112 return FALSE;
113 }
114 }
115 }
505cf9f9
PJ
116 }
117
6a488035
TO
118 /**
119 * Compute any messages which should be displayed after upgrade
120 *
5a4f6742
CW
121 * @param string $postUpgradeMessage
122 * alterable.
123 * @param string $rev
124 * an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs.
6a488035
TO
125 * @return void
126 */
00be9182 127 public function setPostUpgradeMessage(&$postUpgradeMessage, $rev) {
6a488035
TO
128 if ($rev == '4.3.alpha1') {
129 // check if CiviMember component is enabled
130 $config = CRM_Core_Config::singleton();
131 if (in_array('CiviMember', $config->enableComponents)) {
132 $postUpgradeMessage .= '<br />' . ts('Membership renewal reminders must now be configured using the Schedule Reminders feature, which supports multiple renewal reminders (Administer > Communications > Schedule Reminders). The Update Membership Statuses scheduled job will no longer send membershp renewal reminders. You can use your existing renewal reminder message template(s) with the Schedule Reminders feature.');
133 $postUpgradeMessage .= '<br />' . ts('The Set Membership Reminder Dates scheduled job has been deleted since membership reminder dates stored in the membership table are no longer in use.');
134 }
c28241be 135
6a488035 136 //CRM-11636
c28241be 137 //here we do the financial type check and migration
6a488035 138 $isDefaultsModified = self::_checkAndMigrateDefaultFinancialTypes();
22e263ad 139 if ($isDefaultsModified) {
6a488035 140 $postUpgradeMessage .= '<br />' . ts('Please review all price set financial type assignments.');
c28241be 141 }
6a488035
TO
142 list($context, $orgName) = self::createDomainContacts();
143 if ($context == 'added') {
10a5be27 144 $postUpgradeMessage .= '<br />' . ts("A new organization contact has been added as the default domain contact using the information from your Organization Address and Contact Info settings: '%1'.", array(1 => $orgName));
6a488035
TO
145 }
146 elseif ($context == 'merged') {
10a5be27 147 $postUpgradeMessage .= '<br />' . ts("The existing organization contact record for '%1' has been marked as the default domain contact, and has been updated with information from your Organization Address and Contact Info settings.", array(1 => $orgName));
6a488035 148 }
24571eea
DS
149
150 $providerExists = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_sms_provider LIMIT 1");
151 if ($providerExists) {
152 $postUpgradeMessage .= '<br />' . ts('SMS providers were found to setup. Please note Clickatell / Twilio are now shipped as extensions and will require installing them to continue working. Extension could be downloaded and installed from <a href="%1">github</a>.', array(1 => 'https://github.com/civicrm/civicrm-core/tree/master/tools/extensions'));
153 }
6a488035
TO
154 }
155
156 if ($rev == '4.3.alpha2') {
157 $sql = "
158SELECT title, id
159FROM civicrm_action_schedule
160WHERE entity_value = '' OR entity_value IS NULL
161";
c28241be 162
6a488035
TO
163 $dao = CRM_Core_DAO::executeQuery($sql);
164 $reminder = array();
165 $list = '';
166 while ($dao->fetch()) {
33421d01
TO
167 $reminder[$dao->id] = $dao->title;
168 $list .= "<li>{$dao->title}</li>";
6a488035 169 }
c28241be 170 if (!empty($reminder)) {
6a488035 171 $list = "<br /><ul>" . $list . "</ul>";
33421d01 172 $postUpgradeMessage .= '<br />' . ts("Scheduled Reminders must be linked to one or more 'entities' (Events, Event Templates, Activity Types, Membership Types). The following reminders are not configured properly and will not be run. Please review them and update or delete them: %1", array(1 => $list));
6a488035
TO
173 }
174 }
2cf0e58d 175 if ($rev == '4.3.beta2') {
6a488035
TO
176 $postUpgradeMessage .= '<br />' . ts('Default versions of the following System Workflow Message Templates have been modified to handle new functionality: <ul><li>Events - Registration Confirmation and Receipt (on-line)</li><li>Events - Registration Confirmation and Receipt (off-line)</li><li>Pledges - Acknowledgement</li><li>Pledges - Payment Reminder</li><li>Contributions - Receipt (off-line)</li><li>Contributions - Receipt (on-line)</li><li>Memberships - Signup and Renewal Receipts (off-line)</li><li>Memberships - Receipt (on-line)</li><li>Personal Campaign Pages - Admin 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).');
177 }
e3a96c9b
DG
178
179 if ($rev == '4.3.beta5') {
180 $postUpgradeMessage .= '<br />' . ts("If you are interested in trying out the new Accounting Integration features, please review user permissions and assign the new 'manual batch' permissions as appropriate.");
181
182 // CRM-12155
22bf3365
DL
183 $query = "
184SELECT ceft.id FROM `civicrm_financial_trxn` cft
185LEFT JOIN civicrm_entity_financial_trxn ceft
186 ON ceft.financial_trxn_id = cft.id AND ceft.entity_table = 'civicrm_contribution'
187LEFT JOIN civicrm_contribution cc
188 ON cc.id = ceft.entity_id AND ceft.entity_table = 'civicrm_contribution'
189WHERE cc.id IS NULL
190";
e3a96c9b
DG
191
192 $dao = CRM_Core_DAO::executeQuery($query);
193 $isOrphanData = TRUE;
194 if (!$dao->N) {
22bf3365
DL
195 $query = "
196SELECT cli.id FROM civicrm_line_item cli
e3a96c9b
DG
197LEFT JOIN civicrm_contribution cc ON cli.entity_id = cc.id AND cli.entity_table = 'civicrm_contribution'
198LEFT JOIN civicrm_participant cp ON cli.entity_id = cp.id AND cli.entity_table = 'civicrm_participant'
199WHERE CASE WHEN cli.entity_table = 'civicrm_contribution'
22bf3365
DL
200 THEN cc.id IS NULL
201 ELSE cp.id IS NULL
202END
203";
e3a96c9b 204 $dao = CRM_Core_DAO::executeQuery($query);
22bf3365 205 if (!$dao->N) {
e3a96c9b
DG
206 $revPattern = '/^((\d{1,2})\.\d{1,2})\.(\d{1,2}|\w{4,7})?$/i';
207 preg_match($revPattern, $currentVer, $version);
208 if ($version[1] >= 4.3) {
22bf3365
DL
209 $query = "
210SELECT cfi.id
211FROM civicrm_financial_item cfi
e3a96c9b 212LEFT JOIN civicrm_entity_financial_trxn ceft ON ceft.entity_table = 'civicrm_financial_item' and cfi.id = ceft.entity_id
22bf3365
DL
213WHERE ceft.entity_id IS NULL;
214";
e3a96c9b 215 $dao = CRM_Core_DAO::executeQuery($query);
22bf3365 216 if (!$dao->N) {
e3a96c9b
DG
217 $isOrphanData = FALSE;
218 }
219 }
220 else {
22bf3365 221 $isOrphanData = FALSE;
e3a96c9b
DG
222 }
223 }
224 }
225
226 if ($isOrphanData) {
56181f67 227 $postUpgradeMessage .= "</br> <strong>" . ts('Your database contains extraneous financial records related to deleted contacts and contributions. These records should not affect the site and will not appear in reports, search results or exports. However you may wish to clean them up. Refer to <a href="%1" target="_blank">this wiki page for details</a>.
481a74f4 228 ', array(1 => 'http://wiki.civicrm.org/confluence/display/CRMDOC/Clean+up+extraneous+financial+data+-+4.3+upgrades')) . "</strong>";
e3a96c9b
DG
229 }
230 }
56181f67
DG
231 if ($rev == '4.3.4') {
232 $postUpgradeMessage .= '<br />' . ts('System Administrator Alert: If you are running scheduled jobs using CLI.php, you will need to reconfigure cron tasks to include a password. Scheduled jobs will no longer run if the password is not provided (<a href="%1" target="_blank">learn more</a>).',
33421d01 233 array(1 => 'http://wiki.civicrm.org/confluence/display/CRMDOC/Managing+Scheduled+Jobs'));
56181f67 234 }
5d9ebb64
PJ
235 if ($rev == '4.3.5') {
236 $postUpgradeMessage .= '<br />' . ts('Default versions of the following System Workflow Message Templates have been modified to handle new functionality: <ul><li>Events - Registration Confirmation and Receipt (on-line)</li><li>Events - Registration Confirmation and Receipt (off-line)</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).');
237 }
b9810330
DG
238 if ($rev == '4.3.6') {
239 $flag = CRM_Core_DAO::singleValueQuery('SELECT count(ccp.id) FROM civicrm_contribution_product ccp
240INNER JOIN civicrm_product cp ON ccp.product_id = cp.id
241WHERE ccp.financial_type_id IS NULL and cp.cost > 0');
242 if ($flag) {
243 $postUpgradeMessage .= '<br />' . ts('Your database contains one or more premiums which have a cost but are not linked to a financial type. If you are exporting transations to an accounting package, this will result in unbalanced transactions. <a href="%1" target="_blank">You can review steps to correct this situation on the wiki.</a>',
33421d01 244 array(1 => 'http://wiki.civicrm.org/confluence/display/CRMDOC/Fixing+Issues+Caused+by+Missing+Cost+of+Goods+Account+-+4.3+Upgrades'));
b9810330
DG
245 }
246 }
6a488035
TO
247 }
248
624e56fa
EM
249 /**
250 * @param $rev
251 *
252 * @return bool
253 */
00be9182 254 public function upgrade_4_3_alpha1($rev) {
6a488035 255 self::task_4_3_alpha1_checkDBConstraints();
c28241be 256
b676923b
PN
257 // add indexes for civicrm_entity_financial_trxn
258 // CRM-12141
d1401e86 259 $this->addTask('Check/Add indexes for civicrm_entity_financial_trxn', 'task_4_3_x_checkIndexes', $rev);
6a488035 260 // task to process sql
d1401e86 261 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.3.alpha1')), 'task_4_3_x_runSql', $rev);
c28241be 262
6a488035 263 //CRM-11636
d1401e86 264 $this->addTask('Populate financial type values for price records', 'assignFinancialTypeToPriceRecords');
6a488035 265 //CRM-11514 create financial records for contributions
d1401e86 266 $this->addTask('Create financial records for contributions', 'createFinancialRecords');
c28241be 267
6a488035
TO
268 $minId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(min(id),0) FROM civicrm_contact');
269 $maxId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(max(id),0) FROM civicrm_contact');
270 for ($startId = $minId; $startId <= $maxId; $startId += self::BATCH_SIZE) {
271 $endId = $startId + self::BATCH_SIZE - 1;
10a5be27 272 $title = ts('Upgrade timestamps (%1 => %2)', array(1 => $startId, 2 => $endId));
6a488035
TO
273 $this->addTask($title, 'convertTimestamps', $startId, $endId);
274 }
275
276 // CRM-10893
277 // fix WP access control
481a74f4 278 $config = CRM_Core_Config::singleton();
6a488035 279 if ($config->userFramework == 'WordPress') {
481a74f4 280 civicrm_wp_set_capabilities();
6a488035
TO
281 }
282
283 // Update phones CRM-11292.
d1401e86 284 $this->addTask('Upgrade Phone Numbers', 'phoneNumeric');
c28241be 285
6a488035
TO
286 return TRUE;
287 }
288
624e56fa
EM
289 /**
290 * @param $rev
291 */
00be9182 292 public function upgrade_4_3_alpha2($rev) {
6a488035
TO
293 //CRM-11847
294 $isColumnPresent = CRM_Core_DAO::checkFieldExists('civicrm_dedupe_rule_group', 'is_default');
295 if ($isColumnPresent) {
296 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_dedupe_rule_group DROP COLUMN is_default');
297 }
d1401e86 298 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.3.alpha2')), 'task_4_3_x_runSql', $rev);
6a488035
TO
299 }
300
624e56fa
EM
301 /**
302 * @param $rev
303 */
00be9182 304 public function upgrade_4_3_alpha3($rev) {
d1401e86 305 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.3.alpha3')), 'task_4_3_x_runSql', $rev);
6a488035
TO
306 }
307
624e56fa
EM
308 /**
309 * @param $rev
310 */
00be9182 311 public function upgrade_4_3_beta2($rev) {
d1401e86 312 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.3.beta2')), 'task_4_3_x_runSql', $rev);
ab00f69d 313
c28241be
DL
314 // CRM-12002
315 if (
316 CRM_Core_DAO::checkTableExists('log_civicrm_line_item') &&
317 CRM_Core_DAO::checkFieldExists('log_civicrm_line_item', 'label')
318 ) {
319 CRM_Core_DAO::executeQuery('ALTER TABLE `log_civicrm_line_item` CHANGE `label` `label` VARCHAR(255) NULL DEFAULT NULL');
320 }
321 }
322
624e56fa
EM
323 /**
324 * @param $rev
325 */
00be9182 326 public function upgrade_4_3_beta3($rev) {
d1401e86 327 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.3.beta3')), 'task_4_3_x_runSql', $rev);
d20145bc
PN
328 // CRM-12065
329 $query = "SELECT id, form_values FROM civicrm_report_instance WHERE form_values LIKE '%contribution_type%'";
330 $this->addTask('Replace contribution_type to financial_type in table civicrm_report_instance', 'replaceContributionTypeId', $query, 'reportInstance');
331 $query = "SELECT * FROM civicrm_saved_search WHERE form_values LIKE '%contribution_type%'";
332 $this->addTask('Replace contribution_type to financial_type in table civicrm_saved_search', 'replaceContributionTypeId', $query, 'savedSearch');
333 }
558ccc27 334
624e56fa
EM
335 /**
336 * @param $rev
337 */
00be9182 338 public function upgrade_4_3_beta4($rev) {
d1401e86 339 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.3.beta4')), 'task_4_3_x_runSql', $rev);
b676923b
PN
340 // add indexes for civicrm_entity_financial_trxn
341 // CRM-12141
d1401e86 342 $this->addTask('Check/Add indexes for civicrm_entity_financial_trxn', 'task_4_3_x_checkIndexes', $rev);
558ccc27
DL
343 }
344
624e56fa
EM
345 /**
346 * @param $rev
347 */
00be9182 348 public function upgrade_4_3_beta5($rev) {
ab00f69d
DL
349 // CRM-12205
350 if (
351 CRM_Core_DAO::checkTableExists('log_civicrm_financial_trxn') &&
352 CRM_Core_DAO::checkFieldExists('log_civicrm_financial_trxn', 'trxn_id')
353 ) {
354 CRM_Core_DAO::executeQuery('ALTER TABLE `log_civicrm_financial_trxn` CHANGE `trxn_id` `trxn_id` VARCHAR(255) NULL DEFAULT NULL');
355 }
35fe5ae1 356 // CRM-12142 - some sites didn't get this column added yet, and sites which installed 4.3 from scratch will already have it
be996105
PJ
357 // CRM-12367 - add this column to single lingual sites only
358 $upgrade = new CRM_Upgrade_Form();
359 if (!$upgrade->multilingual &&
35fe5ae1
DG
360 !CRM_Core_DAO::checkFieldExists('civicrm_premiums', 'premiums_nothankyou_label')
361 ) {
22bf3365
DL
362 $query = "
363ALTER TABLE civicrm_premiums
364ADD COLUMN premiums_nothankyou_label varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL
365 COMMENT 'Label displayed for No Thank-you option in premiums block (e.g. No thank you)'
366";
be996105 367 CRM_Core_DAO::executeQuery($query, array(), TRUE, NULL, FALSE, FALSE);
22bf3365 368 }
d1401e86 369 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.3.beta5')), 'task_4_3_x_runSql', $rev);
ab00f69d
DL
370 }
371
624e56fa
EM
372 /**
373 * @param $rev
374 */
00be9182 375 public function upgrade_4_3_4($rev) {
d1401e86 376 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.3.4')), 'task_4_3_x_runSql', $rev);
56181f67 377 }
2efcf0c2 378
624e56fa
EM
379 /**
380 * @param $rev
381 */
00be9182 382 public function upgrade_4_3_5($rev) {
d2e8983d
PN
383 // CRM-12156
384 $config = CRM_Core_Config::singleton();
33421d01 385 $dbname = DB::parseDSN($config->dsn);
d2e8983d
PN
386 $sql = "SELECT DELETE_RULE
387FROM information_schema.REFERENTIAL_CONSTRAINTS
388WHERE CONSTRAINT_NAME = 'FK_civicrm_financial_item_contact_id'
389AND CONSTRAINT_SCHEMA = %1";
390 $params = array(1 => array($dbname['database'], 'String'));
391 $onDelete = CRM_Core_DAO::singleValueQuery($sql, $params, TRUE, FALSE);
2efcf0c2 392
d2e8983d
PN
393 if ($onDelete != 'CASCADE') {
394 $query = "ALTER TABLE `civicrm_financial_item`
395DROP FOREIGN KEY FK_civicrm_financial_item_contact_id,
396DROP INDEX FK_civicrm_financial_item_contact_id;";
397 CRM_Core_DAO::executeQuery($query, array(), TRUE, NULL, FALSE, FALSE);
398 $query = "
399ALTER TABLE `civicrm_financial_item`
400ADD CONSTRAINT `FK_civicrm_financial_item_contact_id` FOREIGN KEY (`contact_id`) REFERENCES `civicrm_contact` (`id`) ON DELETE CASCADE;
401";
402 CRM_Core_DAO::executeQuery($query, array(), TRUE, NULL, FALSE, FALSE);
403 }
d1401e86 404 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.3.5')), 'task_4_3_x_runSql', $rev);
d2e8983d 405 }
56181f67 406
624e56fa
EM
407 /**
408 * @param $rev
409 */
00be9182 410 public function upgrade_4_3_6($rev) {
5beb1de0 411 //CRM-13094
0947d54d 412 $this->addTask(ts('Add missing constraints'), 'addMissingConstraints', $rev);
bdbf899f 413 //CRM-13088
d1401e86
ML
414 $this->addTask('Add ON DELETE Options for constraints', 'task_4_3_x_checkConstraints', $rev);
415 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.3.6')), 'task_4_3_x_runSql', $rev);
bf45dbe8
PN
416 // CRM-12844
417 // update line_item, financial_trxn and financial_item table for recurring contributions
d1401e86
ML
418 $this->addTask('Update financial_account_id in financial_trxn table', 'updateFinancialTrxnData', $rev);
419 $this->addTask('Update Line Item Data', 'updateLineItemData', $rev);
bf45dbe8 420 }
77b97be7 421
6a488035 422 //CRM-11636
624e56fa
EM
423 /**
424 * @return bool
425 */
00be9182 426 public function assignFinancialTypeToPriceRecords() {
6a488035
TO
427 $upgrade = new CRM_Upgrade_Form();
428 //here we update price set entries
22bf3365 429 $sqlFinancialIds = "
abe9581c 430SELECT id, LCASE(name) name
22bf3365
DL
431FROM civicrm_financial_type
432WHERE name IN ('Donation', 'Event Fee', 'Member Dues');
433";
6a488035 434 $daoFinancialIds = CRM_Core_DAO::executeQuery($sqlFinancialIds);
22e263ad 435 while ($daoFinancialIds->fetch()) {
6a488035
TO
436 $financialIds[$daoFinancialIds->name] = $daoFinancialIds->id;
437 }
22bf3365
DL
438 $sqlPriceSetUpdate = "
439UPDATE civicrm_price_set ps
440SET ps.financial_type_id =
441 CASE
abe9581c
PN
442 WHEN ps.extends LIKE '%1%' THEN {$financialIds['event fee']}
443 WHEN ps.extends LIKE '2' THEN {$financialIds['donation']}
444 WHEN ps.extends LIKE '3' THEN {$financialIds['member dues']}
6a488035 445 END
22bf3365
DL
446WHERE financial_type_id IS NULL
447";
6a488035
TO
448 CRM_Core_DAO::executeQuery($sqlPriceSetUpdate);
449
450 //here we update price field value rows
22bf3365
DL
451 $sqlPriceFieldValueUpdate = "
452UPDATE civicrm_price_field_value pfv
453LEFT JOIN civicrm_membership_type mt ON (pfv.membership_type_id = mt.id)
454INNER JOIN civicrm_price_field pf ON (pfv.price_field_id = pf.id)
455INNER JOIN civicrm_price_set ps ON (pf.price_set_id = ps.id)
456 SET pfv.financial_type_id =
457 CASE
458 WHEN pfv.membership_type_id IS NOT NULL THEN mt.financial_type_id
459 WHEN pfv.membership_type_id IS NULL THEN ps.financial_type_id
460 END
461";
6a488035 462 CRM_Core_DAO::executeQuery($sqlPriceFieldValueUpdate);
c28241be 463
6a488035
TO
464 return TRUE;
465 }
c28241be 466
624e56fa
EM
467 /**
468 * @return bool
469 */
00be9182 470 public static function _checkAndMigrateDefaultFinancialTypes() {
6a488035
TO
471 $modifiedDefaults = FALSE;
472 //insert types if not exists
22bf3365
DL
473 $sqlFetchTypes = "
474SELECT id, name
475FROM civicrm_contribution_type
476WHERE name IN ('Donation', 'Event Fee', 'Member Dues') AND is_active =1
477";
6a488035
TO
478 $daoFetchTypes = CRM_Core_DAO::executeQuery($sqlFetchTypes);
479
480 if ($daoFetchTypes->N < 3) {
481 $modifiedDefaults = TRUE;
def009f6 482 $insertStatments = array(
6a488035
TO
483 'Donation' => "('Donation', 0, 1, 1)",
484 'Member' => "('Member Dues', 0, 1, 1)",
485 'Event Fee' => "('Event Fee', 0, 1, 0)",
486 );
487 foreach ($insertStatments as $values) {
22bf3365
DL
488 $query = "
489INSERT INTO civicrm_contribution_type (name, is_reserved, is_active, is_deductible)
490VALUES $values
491ON DUPLICATE KEY UPDATE is_active = 1
492";
6a488035 493 CRM_Core_DAO::executeQuery($query);
c28241be 494 }
6a488035
TO
495 }
496 return $modifiedDefaults;
497 }
c28241be 498
624e56fa
EM
499 /**
500 * @return bool
501 */
00be9182 502 public function createFinancialRecords() {
6a488035
TO
503 $upgrade = new CRM_Upgrade_Form();
504
505 // update civicrm_entity_financial_trxn.amount = civicrm_financial_trxn.total_amount
22bf3365
DL
506 $query = "
507UPDATE civicrm_entity_financial_trxn ceft
508LEFT JOIN civicrm_financial_trxn cft ON cft.id = ceft.financial_trxn_id
509SET ceft.amount = total_amount
510WHERE cft.net_amount IS NOT NULL
511AND ceft.entity_table = 'civicrm_contribution'
512";
6a488035 513 CRM_Core_DAO::executeQuery($query);
c28241be 514
6a488035
TO
515 $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
516 $completedStatus = array_search('Completed', $contributionStatus);
517 $pendingStatus = array_search('Pending', $contributionStatus);
518 $cancelledStatus = array_search('Cancelled', $contributionStatus);
519 $queryParams = array(
520 1 => array($completedStatus, 'Integer'),
521 2 => array($pendingStatus, 'Integer'),
21dfd5f5 522 3 => array($cancelledStatus, 'Integer'),
6a488035 523 );
c28241be 524
f743a6eb 525 $accountType = key(CRM_Core_PseudoConstant::accountOptionValues('financial_account_type', NULL, " AND v.name = 'Asset' "));
909a777b 526 $query = "
22bf3365
DL
527SELECT id
528FROM civicrm_financial_account
529WHERE is_default = 1
530AND financial_account_type_id = {$accountType}
531";
909a777b 532 $financialAccountId = CRM_Core_DAO::singleValueQuery($query);
c28241be 533
cc405f4e 534 $accountRelationsips = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_EntityFinancialAccount',
535 'account_relationship', CRM_Core_DAO::$_nullArray, 'validate');
c28241be 536
6a488035
TO
537 $accountsReceivableAccount = array_search('Accounts Receivable Account is', $accountRelationsips);
538 $incomeAccountIs = array_search('Income Account is', $accountRelationsips);
539 $assetAccountIs = array_search('Asset Account is', $accountRelationsips);
540 $expenseAccountIs = array_search('Expense Account is', $accountRelationsips);
c28241be 541
cc405f4e 542 $financialItemStatus = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_FinancialItem', 'status_id',
543 CRM_Core_DAO::$_nullArray, 'validate');
6a488035
TO
544 $unpaidStatus = array_search('Unpaid', $financialItemStatus);
545 $paidStatus = array_search('Paid', $financialItemStatus);
c28241be 546
6a488035
TO
547 $validCurrencyCodes = CRM_Core_PseudoConstant::currencyCode();
548 $validCurrencyCodes = implode("','", $validCurrencyCodes);
549 $config = CRM_Core_Config::singleton();
550 $defaultCurrency = $config->defaultCurrency;
481a74f4 551 $now = date('YmdHis');
6a488035
TO
552
553 //adding financial_trxn records and entity_financial_trxn records related to contribution
554 //Add temp column for easy entry in entity_financial_trxn
555 $sql = "ALTER TABLE civicrm_financial_trxn ADD COLUMN contribution_id INT DEFAULT NULL";
556 CRM_Core_DAO::executeQuery($sql);
c28241be
DL
557
558 //pending pay later status handling
6a488035
TO
559 $sql = "
560INSERT INTO civicrm_financial_trxn
561 (contribution_id, payment_instrument_id, currency, total_amount, net_amount, fee_amount, trxn_id, status_id,
562 check_number, to_financial_account_id, from_financial_account_id, trxn_date)
22bf3365
DL
563SELECT con.id as contribution_id, con.payment_instrument_id,
564 IF(con.currency IN ('{$validCurrencyCodes}'), con.currency, '{$defaultCurrency}') as currency,
565 con.total_amount, con.net_amount, con.fee_amount, con.trxn_id, con.contribution_status_id,
566 con.check_number, efa.financial_account_id as to_financial_account_id, NULL as from_financial_account_id,
6a488035 567 REPLACE(REPLACE(REPLACE(
c28241be
DL
568 CASE
569 WHEN con.receive_date IS NOT NULL THEN
6a488035 570 con.receive_date
c28241be 571 WHEN con.receipt_date IS NOT NULL THEN
6a488035
TO
572 con.receipt_date
573 ELSE
c28241be 574 {$now}
6a488035
TO
575 END
576 , '-', ''), ':', ''), ' ', '') as trxn_date
577FROM civicrm_contribution con
c28241be 578 LEFT JOIN civicrm_entity_financial_account efa
6a488035
TO
579 ON (con.financial_type_id = efa.entity_id AND efa.entity_table = 'civicrm_financial_type'
580 AND efa.account_relationship = {$accountsReceivableAccount})
22bf3365
DL
581WHERE con.is_pay_later = 1
582AND con.contribution_status_id = {$pendingStatus}
583";
6a488035 584 CRM_Core_DAO::executeQuery($sql);
c28241be 585
6a488035
TO
586 //create a temp table to hold financial account id related to payment instruments
587 $tempTableName1 = CRM_Core_DAO::createTempTableName();
c28241be 588
33421d01 589 $sql = "
c75e8bb2 590CREATE TEMPORARY TABLE {$tempTableName1}
22bf3365
DL
591SELECT ceft.financial_account_id financial_account_id, cov.value as instrument_id
592FROM civicrm_entity_financial_account ceft
593INNER JOIN civicrm_option_value cov ON cov.id = ceft.entity_id AND ceft.entity_table = 'civicrm_option_value'
594INNER JOIN civicrm_option_group cog ON cog.id = cov.option_group_id
c75e8bb2
DL
595WHERE cog.name = 'payment_instrument'
596";
6a488035 597 CRM_Core_DAO::executeQuery($sql);
22bf3365 598
b676923b 599 //CRM-12141
1b1d8be3 600 $sql = "ALTER TABLE {$tempTableName1} ADD INDEX index_instrument_id (instrument_id(200));";
b676923b 601 CRM_Core_DAO::executeQuery($sql);
6a488035 602
c28241be 603 //create temp table to process completed / cancelled contribution
6a488035 604 $tempTableName2 = CRM_Core_DAO::createTempTableName();
22bf3365 605 $sql = "
c75e8bb2 606CREATE TEMPORARY TABLE {$tempTableName2}
22bf3365
DL
607SELECT con.id as contribution_id, con.payment_instrument_id,
608 IF(con.currency IN ('{$validCurrencyCodes}'), con.currency, '{$defaultCurrency}') as currency,
609 con.total_amount, con.net_amount, con.fee_amount, con.trxn_id, con.contribution_status_id,
610 con.check_number, NULL as from_financial_account_id,
c28241be
DL
611 REPLACE(REPLACE(REPLACE(
612 CASE
613 WHEN con.receive_date IS NOT NULL THEN
6a488035 614 con.receive_date
c28241be 615 WHEN con.receipt_date IS NOT NULL THEN
6a488035
TO
616 con.receipt_date
617 ELSE
c28241be 618 {$now}
6a488035
TO
619 END
620 , '-', ''), ':', ''), ' ', '') as trxn_date,
c28241be 621 CASE
6a488035
TO
622 WHEN con.payment_instrument_id IS NULL THEN
623 {$financialAccountId}
624 WHEN con.payment_instrument_id IS NOT NULL THEN
625 tpi.financial_account_id
626 END as to_financial_account_id,
627 IF(eft.financial_trxn_id IS NULL, 'insert', eft.financial_trxn_id) as action
22bf3365
DL
628FROM civicrm_contribution con
629LEFT JOIN civicrm_entity_financial_trxn eft
630 ON (eft.entity_table = 'civicrm_contribution' AND eft.entity_id = con.id)
631LEFT JOIN {$tempTableName1} tpi
632 ON con.payment_instrument_id = tpi.instrument_id
633WHERE con.contribution_status_id IN ({$completedStatus}, {$cancelledStatus})
634";
6a488035 635 CRM_Core_DAO::executeQuery($sql);
22bf3365 636
b676923b
PN
637 // CRM-12141
638 $sql = "ALTER TABLE {$tempTableName2} ADD INDEX index_action (action);";
639 CRM_Core_DAO::executeQuery($sql);
c28241be 640
6a488035
TO
641 //handling for completed contribution and cancelled contribution
642 //insertion of new records
643 $sql = "
c28241be 644INSERT INTO civicrm_financial_trxn
6a488035 645 (contribution_id, payment_instrument_id, currency, total_amount, net_amount, fee_amount, trxn_id, status_id, check_number,
c28241be 646 to_financial_account_id, from_financial_account_id, trxn_date)
6a488035
TO
647SELECT tempI.contribution_id, tempI.payment_instrument_id, tempI.currency, tempI.total_amount, tempI.net_amount,
648 tempI.fee_amount, tempI.trxn_id, tempI.contribution_status_id, tempI.check_number,
c28241be 649 tempI.to_financial_account_id, tempI.from_financial_account_id, tempI.trxn_date
6a488035 650FROM {$tempTableName2} tempI
c75e8bb2
DL
651WHERE tempI.action = 'insert'
652";
6a488035
TO
653 CRM_Core_DAO::executeQuery($sql);
654
655 //update of existing records
656 $sql = "
657UPDATE civicrm_financial_trxn ft
c28241be 658 INNER JOIN {$tempTableName2} tempU
6a488035
TO
659 ON (tempU.action != 'insert' AND ft.id = tempU.action)
660SET ft.from_financial_account_id = NULL,
661 ft.to_financial_account_id = tempU.to_financial_account_id,
c28241be 662 ft.status_id = tempU.contribution_status_id,
6a488035
TO
663 ft.payment_instrument_id = tempU.payment_instrument_id,
664 ft.check_number = tempU.check_number,
665 ft.contribution_id = tempU.contribution_id;";
666 CRM_Core_DAO::executeQuery($sql);
667
668 //insert the -ve transaction rows for cancelled contributions
669 $sql = "
670INSERT INTO civicrm_financial_trxn
c28241be
DL
671 (contribution_id, payment_instrument_id, currency, total_amount, net_amount, fee_amount, trxn_id, status_id,
672 check_number, to_financial_account_id, from_financial_account_id, trxn_date)
673SELECT ft.contribution_id, ft.payment_instrument_id, ft.currency, -ft.total_amount, ft.net_amount, ft.fee_amount, ft.trxn_id,
6a488035 674 ft.status_id, ft.check_number, ft.to_financial_account_id, ft.from_financial_account_id, ft.trxn_date
c28241be 675FROM civicrm_financial_trxn ft
6a488035
TO
676WHERE ft.status_id = {$cancelledStatus};";
677 CRM_Core_DAO::executeQuery($sql);
678
679 //inserting entity financial trxn entries if its not present in entity_financial_trxn for completed and pending contribution statuses
680 //this also handles +ve and -ve both transaction entries for a cancelled contribution
681 $sql = "
682INSERT INTO civicrm_entity_financial_trxn (entity_table, entity_id, financial_trxn_id, amount)
683SELECT 'civicrm_contribution', ft.contribution_id, ft.id, ft.total_amount as amount
684FROM civicrm_financial_trxn ft
c28241be
DL
685WHERE contribution_id IS NOT NULL AND
686 ft.id NOT IN (SELECT financial_trxn_id
687 FROM civicrm_entity_financial_trxn
6a488035
TO
688 WHERE entity_table = 'civicrm_contribution'
689 AND entity_id = ft.contribution_id)";
690 CRM_Core_DAO::executeQuery($sql);
691 //end of adding financial_trxn records and entity_financial_trxn records related to contribution
692
693 //update all linked line_item rows
694 // set line_item.financial_type_id = contribution.financial_type_id if contribution page id is null and not participant line item
695 // set line_item.financial_type_id = price_field_value.financial_type_id if contribution page id is set and not participant line item
696 // set line_item.financial_type_id = event.financial_type_id if its participant line item and line_item.price_field_value_id is null
697 // set line_item.financial_type_id = price_field_value.financial_type_id if its participant line item and line_item.price_field_value_id is set
698 $updateLineItemSql = "
699UPDATE civicrm_line_item li
700 LEFT JOIN civicrm_contribution con
701 ON (li.entity_id = con.id AND li.entity_table = 'civicrm_contribution')
702 LEFT JOIN civicrm_price_field_value cpfv
703 ON li.price_field_value_id = cpfv.id
704 LEFT JOIN civicrm_participant cp
705 ON (li.entity_id = cp.id AND li.entity_table = 'civicrm_participant')
706 LEFT JOIN civicrm_event ce
c28241be 707 ON ce.id = cp.event_id
6a488035 708SET li.financial_type_id = CASE
c28241be 709 WHEN (con.contribution_page_id IS NULL || li.price_field_value_id IS NULL) AND cp.id IS NULL THEN
6a488035
TO
710 con.financial_type_id
711 WHEN (con.contribution_page_id IS NOT NULL AND cp.id IS NULL) || (cp.id IS NOT NULL AND li.price_field_value_id IS NOT NULL) THEN
712 cpfv.financial_type_id
c28241be 713 WHEN cp.id IS NOT NULL AND li.price_field_value_id IS NULL THEN
6a488035
TO
714 ce.financial_type_id
715 END";
716 CRM_Core_DAO::executeQuery($updateLineItemSql, $queryParams);
c28241be
DL
717
718 //add the financial_item entries
6a488035
TO
719 //add a temp column so that inserting entity_financial_trxn entries gets easy
720 $sql = "ALTER TABLE civicrm_financial_item ADD COLUMN f_trxn_id INT DEFAULT NULL";
721 CRM_Core_DAO::executeQuery($sql);
c28241be 722
6a488035
TO
723 //add financial_item entries for contribution completed / pending pay later / cancelled
724 $contributionlineItemSql = "
c28241be 725INSERT INTO civicrm_financial_item
6a488035
TO
726 (transaction_date, contact_id, amount, currency, entity_table, entity_id, description, status_id, financial_account_id, f_trxn_id)
727
728SELECT REPLACE(REPLACE(REPLACE(ft.trxn_date, '-', ''), ':', ''), ' ', ''), con.contact_id,
c28241be 729 IF(ft.total_amount < 0 AND con.contribution_status_id = %3, -li.line_total, li.line_total) as line_total, con.currency, 'civicrm_line_item',
6a488035
TO
730 li.id as line_item_id, li.label as line_item_label,
731 IF(con.contribution_status_id = {$pendingStatus}, {$unpaidStatus}, {$paidStatus}) as status_id, efa.financial_account_id as financial_account_id,
732 ft.id as f_trxn_id
733FROM civicrm_line_item li
c28241be 734 INNER JOIN civicrm_contribution con
6a488035
TO
735 ON (li.entity_id = con.id AND li.entity_table = 'civicrm_contribution')
736 INNER JOIN civicrm_financial_trxn ft
737 ON (con.id = ft.contribution_id)
738 LEFT JOIN civicrm_entity_financial_account efa
739 ON (li.financial_type_id = efa.entity_id AND efa.entity_table = 'civicrm_financial_type'
740 AND efa.account_relationship = {$incomeAccountIs})
741WHERE con.contribution_status_id IN (%1, %3) OR (con.is_pay_later = 1 AND con.contribution_status_id = %2)";
742 CRM_Core_DAO::executeQuery($contributionlineItemSql, $queryParams);
c28241be 743
6a488035
TO
744 //add financial_item entries for event
745 $participantLineItemSql = "
c28241be 746INSERT INTO civicrm_financial_item
6a488035
TO
747 (transaction_date, contact_id, amount, currency, entity_table, entity_id, description, status_id, financial_account_id, f_trxn_id)
748
749SELECT REPLACE(REPLACE(REPLACE(ft.trxn_date, '-', ''), ':', ''), ' ', ''), con.contact_id,
750 IF(ft.total_amount < 0 AND con.contribution_status_id = %3, -li.line_total, li.line_total) as line_total,
c28241be 751 con.currency, 'civicrm_line_item', li.id as line_item_id, li.label as line_item_label,
6a488035
TO
752 IF(con.contribution_status_id = {$pendingStatus}, {$unpaidStatus}, {$paidStatus}) as status_id,
753 efa.financial_account_id as financial_account_id, ft.id as f_trxn_id
754FROM civicrm_line_item li
755 INNER JOIN civicrm_participant par
756 ON (li.entity_id = par.id AND li.entity_table = 'civicrm_participant')
c28241be
DL
757 INNER JOIN civicrm_participant_payment pp
758 ON (pp.participant_id = par.id)
6a488035
TO
759 INNER JOIN civicrm_contribution con
760 ON (pp.contribution_id = con.id)
c28241be 761 INNER JOIN civicrm_financial_trxn ft
6a488035
TO
762 ON (con.id = ft.contribution_id)
763 LEFT JOIN civicrm_entity_financial_account efa
764 ON (li.financial_type_id = efa.entity_id AND
765 efa.entity_table = 'civicrm_financial_type' AND efa.account_relationship = {$incomeAccountIs})
766WHERE con.contribution_status_id IN (%1, %3) OR (con.is_pay_later = 1 AND con.contribution_status_id = %2)";
767 CRM_Core_DAO::executeQuery($participantLineItemSql, $queryParams);
c28241be 768
6a488035
TO
769 //fee handling for contributions
770 //insert fee entries in financial_trxn for contributions
771 $sql = "ALTER TABLE civicrm_financial_trxn ADD COLUMN is_fee TINYINT DEFAULT NULL";
772 CRM_Core_DAO::executeQuery($sql);
c28241be 773
6a488035 774 $sql = "
c28241be 775INSERT INTO civicrm_financial_trxn
6a488035
TO
776 (contribution_id, payment_instrument_id, currency, total_amount, net_amount, fee_amount, trxn_id, status_id, check_number,
777 to_financial_account_id, from_financial_account_id, trxn_date, payment_processor_id, is_fee)
778
779SELECT con.id, ft.payment_instrument_id, ft.currency, ft.fee_amount, NULL, NULL, ft.trxn_id, %1 as status_id,
780 ft.check_number, efaFT.financial_account_id as to_financial_account_id, CASE
781 WHEN efaPP.financial_account_id IS NOT NULL THEN
782 efaPP.financial_account_id
783 WHEN tpi.financial_account_id IS NOT NULL THEN
c28241be
DL
784 tpi.financial_account_id
785 ELSE
786 {$financialAccountId}
6a488035
TO
787 END as from_financial_account_id, ft.trxn_date, ft.payment_processor_id, 1 as is_fee
788FROM civicrm_contribution con
789 INNER JOIN civicrm_financial_trxn ft
790 ON (ft.contribution_id = con.id)
791 LEFT JOIN civicrm_entity_financial_account efaFT
792 ON (con.financial_type_id = efaFT.entity_id AND efaFT.entity_table = 'civicrm_financial_type'
793 AND efaFT.account_relationship = {$expenseAccountIs})
c28241be 794 LEFT JOIN civicrm_entity_financial_account efaPP
6a488035
TO
795 ON (ft.payment_processor_id = efaPP.entity_id AND efaPP.entity_table = 'civicrm_payment_processor'
796 AND efaPP.account_relationship = {$assetAccountIs})
c28241be 797 LEFT JOIN {$tempTableName1} tpi
6a488035 798 ON ft.payment_instrument_id = tpi.instrument_id
368d2a88 799WHERE ft.fee_amount IS NOT NULL AND ft.fee_amount != 0 AND (con.contribution_status_id IN (%1, %3) OR (con.contribution_status_id =%2 AND con.is_pay_later = 1))
6a488035
TO
800GROUP BY con.id";
801 CRM_Core_DAO::executeQuery($sql, $queryParams);
802
c28241be 803 //link financial_trxn to contribution
6a488035
TO
804 $sql = "
805INSERT INTO civicrm_entity_financial_trxn
806 (entity_table, entity_id, financial_trxn_id, amount)
807SELECT 'civicrm_contribution', ft.contribution_id, ft.id, ft.total_amount
808FROM civicrm_financial_trxn ft
809WHERE ft.is_fee = 1";
810 CRM_Core_DAO::executeQuery($sql);
c28241be 811
6a488035
TO
812 //add fee related entries to financial item table
813 $domainId = CRM_Core_Config::domainID();
814 $domainContactId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Domain', $domainId, 'contact_id');
815 $sql = "
c28241be 816INSERT INTO civicrm_financial_item
6a488035 817 (transaction_date, contact_id, amount, currency, entity_table, entity_id, description, status_id, financial_account_id, f_trxn_id)
c28241be 818SELECT ft.trxn_date, {$domainContactId} as contact_id, ft.total_amount, ft.currency, 'civicrm_financial_trxn', ft.id,
6a488035 819 'Fee', {$paidStatus} as status_id, ft.to_financial_account_id as financial_account_id, ft.id as f_trxn_id
c28241be 820FROM civicrm_financial_trxn ft
6a488035
TO
821WHERE ft.is_fee = 1;";
822 CRM_Core_DAO::executeQuery($sql);
c28241be 823
6a488035
TO
824 //add entries to entity_financial_trxn table
825 $sql = "
826INSERT INTO civicrm_entity_financial_trxn (entity_table, entity_id, financial_trxn_id, amount)
827SELECT 'civicrm_financial_item' as entity_table, fi.id as entity_id, fi.f_trxn_id as financial_trxn_id, fi.amount
828FROM civicrm_financial_item fi";
829 CRM_Core_DAO::executeQuery($sql);
830
831 //drop the temparory columns
832 $sql = "ALTER TABLE civicrm_financial_trxn
833 DROP COLUMN contribution_id,
834 DROP COLUMN is_fee;";
835 CRM_Core_DAO::executeQuery($sql);
836
837 $sql = "ALTER TABLE civicrm_financial_item DROP f_trxn_id";
838 CRM_Core_DAO::executeQuery($sql);
c28241be 839
6a488035
TO
840 return TRUE;
841 }
842
624e56fa
EM
843 /**
844 * @return array
845 */
00be9182 846 public function createDomainContacts() {
6a488035
TO
847 $domainParams = $context = array();
848 $query = "
22bf3365
DL
849ALTER TABLE civicrm_domain ADD contact_id INT( 10 ) UNSIGNED NULL DEFAULT NULL COMMENT 'FK to Contact ID. This is specifically not an FK to avoid circular constraints',
850 ADD CONSTRAINT FK_civicrm_domain_contact_id FOREIGN KEY (contact_id) REFERENCES civicrm_contact(id);";
6a488035 851 CRM_Core_DAO::executeQuery($query, CRM_Core_DAO::$_nullArray, TRUE, NULL, FALSE, FALSE);
c28241be 852
22bf3365
DL
853 $query = '
854SELECT cd.id, cd.name, ce.email FROM civicrm_domain cd
6a488035 855LEFT JOIN civicrm_loc_block clb ON clb.id = cd. loc_block_id
22bf3365 856LEFT JOIN civicrm_email ce ON ce.id = clb.email_id ;
33421d01 857';
6a488035 858 $dao = CRM_Core_DAO::executeQuery($query);
22e263ad 859 while ($dao->fetch()) {
22bf3365
DL
860 $query = "
861SELECT cc.id FROM civicrm_contact cc
6a488035 862LEFT JOIN civicrm_email ce ON ce.contact_id = cc.id
22bf3365
DL
863WHERE cc.contact_type = 'Organization' AND cc.organization_name = %1
864";
865 $params = array(1 => array($dao->name, 'String'));
6a488035 866 if ($dao->email) {
22bf3365
DL
867 $query .= " AND ce.email = %2 ";
868 $params[2] = array($dao->email, 'String');
6a488035 869 }
22bf3365 870 $contactID = CRM_Core_DAO::singleValueQuery($query, $params);
6a488035
TO
871 $context[1] = $dao->name;
872 if (empty($contactID)) {
d8e9fe86
PD
873 $params = array(
874 'sort_name' => $dao->name,
875 'display_name' => $dao->name,
876 'legal_name' => $dao->name,
877 'organization_name' => $dao->name,
21dfd5f5 878 'contact_type' => 'Organization',
d8e9fe86 879 );
6a488035
TO
880 $contact = CRM_Contact_BAO_Contact::add($params);
881 $contactID = $contact->id;
882 $context[0] = 'added';
c28241be 883 }
6a488035
TO
884 else {
885 $context[0] = 'merged';
886 }
887 $domainParams['contact_id'] = $contactID;
888 CRM_Core_BAO_Domain::edit($domainParams, $dao->id);
889 }
890 return $context;
891 }
892
00be9182 893 public function task_4_3_alpha1_checkDBConstraints() {
6a488035
TO
894 //checking whether the foreign key exists before dropping it CRM-11260
895 $config = CRM_Core_Config::singleton();
896 $dbUf = DB::parseDSN($config->dsn);
6a488035 897 $tables = array(
33421d01
TO
898 'autorenewal_msg_id' => array(
899 'tableName' => 'civicrm_membership_type',
900 'fkey' => 'FK_civicrm_membership_autorenewal_msg_id',
901 ),
902 'to_account_id' => array(
903 'tableName' => 'civicrm_financial_trxn',
904 'constraintName' => 'civicrm_financial_trxn_ibfk_2',
905 ),
906 'from_account_id' => array(
907 'tableName' => 'civicrm_financial_trxn',
908 'constraintName' => 'civicrm_financial_trxn_ibfk_1',
909 ),
910 'contribution_type_id' => array(
911 'tableName' => 'civicrm_contribution_recur',
912 'fkey' => 'FK_civicrm_contribution_recur_contribution_type_id',
913 ),
6a488035 914 );
22bf3365
DL
915 $query = "
916SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
6a488035
TO
917WHERE table_name = 'civicrm_contribution_recur'
918AND constraint_name = 'FK_civicrm_contribution_recur_contribution_type_id'
22bf3365
DL
919AND TABLE_SCHEMA = %1
920";
921 $params = array(1 => array($dbUf['database'], 'String'));
6a488035 922 $dao = CRM_Core_DAO::executeQuery($query, $params, TRUE, NULL, FALSE, FALSE);
9b873358 923 foreach ($tables as $columnName => $value) {
6a488035
TO
924 if ($value['tableName'] == 'civicrm_membership_type' || $value['tableName'] == 'civicrm_contribution_recur') {
925 $foreignKeyExists = CRM_Core_DAO::checkConstraintExists($value['tableName'], $value['fkey']);
926 $fKey = $value['fkey'];
0db6c3e1
TO
927 }
928 else {
fbeab178 929 $foreignKeyExists = CRM_Core_DAO::checkFKConstraintInFormat($value['tableName'], $columnName);
6a488035
TO
930 $fKey = "`FK_{$value['tableName']}_{$columnName}`";
931 }
932 if ($foreignKeyExists || $value['tableName'] == 'civicrm_financial_trxn') {
933 if ($value['tableName'] != 'civicrm_contribution_recur' || ($value['tableName'] == 'civicrm_contribution_recur' && $dao->N)) {
33421d01 934 $constraintName = $foreignKeyExists ? $fKey : $value['constraintName'];
22bf3365
DL
935 $query = "ALTER TABLE {$value['tableName']} DROP FOREIGN KEY {$constraintName}";
936 CRM_Core_DAO::executeQuery($query, $params, TRUE, NULL, FALSE, FALSE);
6a488035 937 }
22bf3365
DL
938 $query = "ALTER TABLE {$value['tableName']} DROP INDEX {$fKey}";
939 CRM_Core_DAO::executeQuery($query, $params, TRUE, NULL, FALSE, FALSE);
6a488035
TO
940 }
941 }
942 // check if column contact_id is present or not in civicrm_financial_account
943 $fieldExists = CRM_Core_DAO::checkFieldExists('civicrm_financial_account', 'contact_id', FALSE);
944 if (!$fieldExists) {
22bf3365
DL
945 $query = "
946ALTER TABLE civicrm_financial_account
947 ADD contact_id int(10) unsigned DEFAULT NULL COMMENT 'Version identifier of financial_type' AFTER name,
948 ADD CONSTRAINT FK_civicrm_financial_account_contact_id FOREIGN KEY (contact_id) REFERENCES civicrm_contact(id);
949";
6a488035
TO
950 CRM_Core_DAO::executeQuery($query, $params, TRUE, NULL, FALSE, FALSE);
951 }
952 }
953
954 /**
955 * Read creation and modification times from civicrm_log; add
956 * them to civicrm_contact.
957 */
00be9182 958 public function convertTimestamps(CRM_Queue_TaskContext $ctx, $startId, $endId) {
6a488035
TO
959 $sql = "
960 SELECT entity_id, min(modified_date) AS created, max(modified_date) AS modified
961 FROM civicrm_log
962 WHERE entity_table = 'civicrm_contact'
963 AND entity_id BETWEEN %1 AND %2
964 GROUP BY entity_id
965 ";
966 $params = array(
967 1 => array($startId, 'Integer'),
968 2 => array($endId, 'Integer'),
969 );
970 $dao = CRM_Core_DAO::executeQuery($sql, $params);
971 while ($dao->fetch()) {
972 // FIXME civicrm_log.modified_date is DATETIME; civicrm_contact.modified_date is TIMESTAMP
973 CRM_Core_DAO::executeQuery(
16aa2ccd 974 'UPDATE civicrm_contact SET created_date = FROM_UNIXTIME(UNIX_TIMESTAMP(%1)), modified_date = FROM_UNIXTIME(UNIX_TIMESTAMP(%2)) WHERE id = %3',
6a488035
TO
975 array(
976 1 => array($dao->created, 'String'),
977 2 => array($dao->modified, 'String'),
978 3 => array($dao->entity_id, 'Integer'),
979 )
980 );
981 }
982
983 return TRUE;
984 }
77b97be7 985
5beb1de0 986 /**
100fef9d 987 * Change index and add missing constraints for civicrm_contribution_recur
5beb1de0 988 */
00be9182 989 public function addMissingConstraints(CRM_Queue_TaskContext $ctx) {
5beb1de0
PN
990 $query = "SHOW KEYS FROM `civicrm_contribution_recur` WHERE key_name = 'UI_contrib_payment_instrument_id'";
991 $dao = CRM_Core_DAO::executeQuery($query);
992 if ($dao->N) {
993 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_contribution_recur DROP INDEX UI_contrib_payment_instrument_id');
994 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_contribution_recur ADD INDEX UI_contribution_recur_payment_instrument_id (payment_instrument_id)');
995 }
996 $constraintArray = array(
77b97be7
EM
997 'contact_id' => " ADD CONSTRAINT `FK_civicrm_contribution_recur_contact_id` FOREIGN KEY (`contact_id`) REFERENCES `civicrm_contact` (`id`) ON DELETE CASCADE ",
998 'payment_processor_id' => " ADD CONSTRAINT `FK_civicrm_contribution_recur_payment_processor_id` FOREIGN KEY (`payment_processor_id`) REFERENCES `civicrm_payment_processor` (`id`) ON DELETE SET NULL ",
999 'financial_type_id' => " ADD CONSTRAINT `FK_civicrm_contribution_recur_financial_type_id` FOREIGN KEY (`financial_type_id`) REFERENCES `civicrm_financial_type` (`id`) ON DELETE SET NULL ",
5beb1de0
PN
1000 'campaign_id' => " ADD CONSTRAINT `FK_civicrm_contribution_recur_campaign_id` FOREIGN KEY (`campaign_id`) REFERENCES `civicrm_campaign` (`id`) ON DELETE SET NULL ",
1001 );
1002 $constraint = array();
1003 foreach ($constraintArray as $constraintKey => $value) {
1004 $foreignKeyExists = CRM_Core_DAO::checkFKConstraintInFormat('civicrm_contribution_recur', $constraintKey);
1005 if (!$foreignKeyExists) {
1006 $constraint[] = $value;
1007 }
1008 }
1009 if (!empty($constraint)) {
1010 $query = "ALTER TABLE civicrm_contribution_recur " . implode(' , ', $constraint);
1011 CRM_Core_DAO::executeQuery($query);
1012 }
77b97be7 1013 return TRUE;
5beb1de0
PN
1014 }
1015
bf45dbe8
PN
1016 /**
1017 * Update financial_account_id for bad data in financial_trxn table
1018 * CRM-12844
bf45dbe8 1019 */
00be9182 1020 public function updateFinancialTrxnData(CRM_Queue_TaskContext $ctx) {
5beb1de0 1021 $upgrade = new CRM_Upgrade_Form();
77b97be7 1022 $sql = "SELECT cc.id contribution_id, cc.contribution_recur_id, cft.payment_processor_id,
bf45dbe8
PN
1023cft.id financial_trxn_id, cfi.entity_table, cft.from_financial_account_id, cft.to_financial_account_id
1024
1025FROM `civicrm_contribution` cc
1026LEFT JOIN civicrm_entity_financial_trxn ceft ON ceft.entity_id = cc.id
1027LEFT JOIN civicrm_financial_trxn cft ON cft.id = ceft.financial_trxn_id
77b97be7 1028LEFT JOIN civicrm_entity_financial_trxn ceft1 ON ceft1.financial_trxn_id = ceft.financial_trxn_id
bf45dbe8
PN
1029LEFT JOIN civicrm_financial_item cfi ON cfi.id = ceft1.entity_id
1030WHERE ceft.entity_table = 'civicrm_contribution' AND cc.contribution_recur_id IS NOT NULL
1031AND ceft1.entity_table = 'civicrm_financial_item' AND cft.id IS NOT NULL AND cft.payment_instrument_id = %1
1032
1033ORDER BY cft.id ";
47b19837 1034 $paymentInstrument = CRM_Contribute_PseudoConstant::paymentInstrument('name');
bf45dbe8
PN
1035 $param = array(1 => array(array_search('Credit Card', $paymentInstrument), 'Integer'));
1036 $dao = CRM_Core_DAO::executeQuery($sql, $param);
1037 $financialTrxn = array();
1038 $subsequentPayments = array();
1039 while ($dao->fetch()) {
1040 if (!array_key_exists($dao->contribution_recur_id, $financialTrxn)) {
1041 $financialTrxn[$dao->contribution_recur_id] = array(
33421d01
TO
1042 'from_financial_account_id' => $dao->to_financial_account_id,
1043 'payment_processor_id' => $dao->payment_processor_id,
1044 $dao->contribution_id => 1,
bf45dbe8
PN
1045 );
1046 if (!is_null($dao->from_financial_account_id)) {
1047 $sql = 'UPDATE civicrm_financial_trxn SET from_financial_account_id = NULL WHERE id = %1';
1048 $params = array(1 => array($dao->financial_trxn_id, 'Integer'));
1049 CRM_Core_DAO::executeQuery($sql, $params);
1050 }
1051 }
1052 elseif (!array_key_exists($dao->contribution_id, $financialTrxn[$dao->contribution_recur_id])) {
77b97be7 1053 if (($dao->entity_table == 'civicrm_line_item' && $dao->to_financial_account_id == $financialTrxn[$dao->contribution_recur_id]['from_financial_account_id'])
33421d01
TO
1054 || ($dao->entity_table == 'civicrm_financial_trxn' && $dao->from_financial_account_id == $financialTrxn[$dao->contribution_recur_id]['from_financial_account_id'])
1055 ) {
bf45dbe8
PN
1056 continue;
1057 }
33421d01 1058 $subsequentPayments[$dao->contribution_recur_id][$dao->entity_table][] = $dao->financial_trxn_id;
bf45dbe8
PN
1059 }
1060 }
1061 foreach ($subsequentPayments as $key => $value) {
1062 foreach ($value as $table => $val) {
1063 if ($table == 'civicrm_financial_trxn') {
1064 $field = 'from_financial_account_id';
1065 }
1066 else {
1067 $field = 'to_financial_account_id';
1068 }
77b97be7
EM
1069 $sql = "UPDATE civicrm_financial_trxn SET $field = " . $financialTrxn[$dao->contribution_recur_id]['from_financial_account_id'] . ',
1070payment_processor_id = ' . $financialTrxn[$dao->contribution_recur_id]['payment_processor_id'] . ' WHERE
bf45dbe8
PN
1071id IN (' . implode(',', $val) . ')';
1072 CRM_Core_DAO::executeQuery($sql);
1073 }
1074 }
1075 return TRUE;
1076 }
1077
1078 /**
1079 * Update financial_account_id for bad data in financial_trxn table
1080 * CRM-12844
bf45dbe8 1081 */
00be9182 1082 public function updateLineItemData(CRM_Queue_TaskContext $ctx) {
5beb1de0 1083 $sql = "SELECT cc.id contribution_id, cc.contribution_recur_id,
77b97be7 1084cc.financial_type_id contribution_financial_type,
bf45dbe8
PN
1085cli.financial_type_id line_financial_type_id,
1086cli.price_field_id, cli.price_field_value_id, cli.label, cli.id line_item_id,
1087cfi.financial_account_id
1088FROM `civicrm_line_item` cli
1089LEFT JOIN civicrm_contribution cc ON cc.id = cli.entity_id
1090LEFT JOIN civicrm_financial_item cfi ON cfi.entity_id = cli.id
1091LEFT JOIN civicrm_price_field cpf ON cpf.id = cli.price_field_id
1092LEFT JOIN civicrm_price_set cps ON cps.id = cpf.price_set_id
1093LEFT JOIN civicrm_price_field_value cpfv ON cpfv.id = cli.price_field_value_id
77b97be7 1094WHERE cfi.entity_table = 'civicrm_line_item'
bf45dbe8 1095AND cli.entity_table = 'civicrm_contribution'
77b97be7 1096AND cps.is_quick_config = 1 AND cc.contribution_recur_id IS NOT NULL
bf45dbe8
PN
1097ORDER BY cli.id";
1098 $dao = CRM_Core_DAO::executeQuery($sql);
1099 $financialTrxn = $subsequentPayments = array();
1100 while ($dao->fetch()) {
1101 if (!array_key_exists($dao->contribution_recur_id, $financialTrxn)) {
1102 $financialTrxn[$dao->contribution_recur_id] = array(
33421d01
TO
1103 'price_field_id' => $dao->price_field_id,
1104 'price_field_value_id' => $dao->price_field_value_id,
1105 'label' => strval($dao->label),
1106 'financial_account_id' => $dao->financial_account_id,
1107 $dao->contribution_id => 1,
bf45dbe8
PN
1108 );
1109 }
1110 else {
1111 if ($dao->price_field_value_id == $financialTrxn[$dao->contribution_recur_id]['price_field_value_id']) {
1112 continue;
1113 }
33421d01 1114 $subsequentPayments[$dao->contribution_recur_id][] = $dao->line_item_id;
bf45dbe8
PN
1115 }
1116 }
1117 foreach ($subsequentPayments as $key => $value) {
1118 $sql = "UPDATE civicrm_line_item cli
1119LEFT JOIN civicrm_financial_item cfi ON cli.id = cfi.entity_id
77b97be7 1120SET
bf45dbe8
PN
1121cli.label = %1,
1122cli.price_field_id = %2,
1123cli.price_field_value_id = %3,
1124cfi.financial_account_id = %4,
1125cfi.description = %5,
1126cli.financial_type_id = %6
77b97be7 1127WHERE cfi.entity_table = 'civicrm_line_item'
86bfa4f6 1128AND cli.entity_table = 'civicrm_contribution' AND cli.id IN (" . implode(',', $value) . ');';
33421d01 1129 $params = array(
bf45dbe8
PN
1130 1 => array($financialTrxn[$key]['label'], 'String'),
1131 2 => array($financialTrxn[$key]['price_field_id'], 'Integer'),
1132 3 => array($financialTrxn[$key]['price_field_value_id'], 'Integer'),
1133 4 => array($financialTrxn[$key]['financial_account_id'], 'Integer'),
1134 5 => array($financialTrxn[$key]['label'], 'String'),
1135 6 => array($dao->contribution_financial_type, 'Integer'),
1136 );
1137 CRM_Core_DAO::executeQuery($sql, $params);
1138 }
1139 return TRUE;
1140 }
6a488035 1141
d20145bc 1142 /**
100fef9d 1143 * Replace contribution_type to financial_type in table
d20145bc
PN
1144 * civicrm_saved_search and Structure civicrm_report_instance
1145 */
00be9182 1146 public function replaceContributionTypeId(CRM_Queue_TaskContext $ctx, $query, $table) {
d20145bc
PN
1147 $dao = CRM_Core_DAO::executeQuery($query);
1148 while ($dao->fetch()) {
1149 $formValues = unserialize($dao->form_values);
1150 foreach (array('contribution_type_id_op', 'contribution_type_id_value', 'contribution_type_id') as $value) {
1151 if (array_key_exists($value, $formValues)) {
1152 $key = preg_replace('/contribution/', 'financial', $value);
1153 $formValues[$key] = $formValues[$value];
1154 unset($formValues[$value]);
1155 }
1156 }
1157 if ($table != 'savedSearch') {
1158 foreach (array('fields', 'group_bys') as $value) {
1159 if (array_key_exists($value, $formValues)) {
1160 if (array_key_exists('contribution_type_id', $formValues[$value])) {
1161 $formValues[$value]['financial_type_id'] = $formValues[$value]['contribution_type_id'];
1162 unset($formValues[$value]['contribution_type_id']);
1163 }
4c9b6178 1164 elseif (array_key_exists('contribution_type', $formValues[$value])) {
d20145bc
PN
1165 $formValues[$value]['financial_type'] = $formValues[$value]['contribution_type'];
1166 unset($formValues[$value]['contribution_type']);
1167 }
1168 }
1169 }
1170 if (array_key_exists('order_bys', $formValues)) {
1171 foreach ($formValues['order_bys'] as $key => $values) {
1172 if (preg_grep('/contribution_type/', $values)) {
1173 $formValues['order_bys'][$key]['column'] = preg_replace('/contribution_type/', 'financial_type', $values['column']);
1174 }
1175 }
1176 }
1177 }
1178
1179 if ($table == 'savedSearch') {
1180 $saveDao = new CRM_Contact_DAO_SavedSearch();
1181 }
1182 else {
0b25329b 1183 $saveDao = new CRM_Report_DAO_ReportInstance();
d20145bc
PN
1184 }
1185 $saveDao->id = $dao->id;
1186
1187 if ($table == 'savedSearch') {
558ccc27 1188 if (array_key_exists('mapper', $formValues)) {
d20145bc
PN
1189 foreach ($formValues['mapper'] as $key => $values) {
1190 foreach ($values as $k => $v) {
1191 if (preg_grep('/contribution_/', $v)) {
1192 $formValues['mapper'][$key][$k] = preg_replace('/contribution_type/', 'financial_type', $v);
1193 }
1194 }
1195 }
1196 }
1197 foreach (array('select_tables', 'where_tables') as $value) {
1198 if (preg_match('/contribution_type/', $dao->$value)) {
1199 $tempValue = unserialize($dao->$value);
1200 if (array_key_exists('civicrm_contribution_type', $tempValue)) {
1201 $tempValue['civicrm_financial_type'] = $tempValue['civicrm_contribution_type'];
1202 unset($tempValue['civicrm_contribution_type']);
1203 }
1204 $saveDao->$value = serialize($tempValue);
1205 }
1206 }
1207 if (preg_match('/contribution_type/', $dao->where_clause)) {
1208 $saveDao->where_clause = preg_replace('/contribution_type/', 'financial_type', $dao->where_clause);
558ccc27 1209 }
d20145bc
PN
1210 }
1211 $saveDao->form_values = serialize($formValues);
1212
1213 $saveDao->save();
1214 }
1215 return TRUE;
1216 }
1217
bdbf899f
PN
1218 /**
1219 * Add ON DELETE options for constraint if not present
1220 * CRM-13088 && CRM-12156
1221 *
77b97be7
EM
1222 * @param CRM_Queue_TaskContext $ctx
1223 *
a6c01b45
CW
1224 * @return bool
1225 * TRUE for success
bdbf899f 1226 */
00be9182 1227 public function task_4_3_x_checkConstraints(CRM_Queue_TaskContext $ctx) {
49ddb59d 1228 CRM_Core_DAO::executeQuery('ALTER TABLE `civicrm_financial_account` CHANGE `contact_id` `contact_id` INT( 10 ) UNSIGNED NULL DEFAULT NULL');
bdbf899f 1229 $config = CRM_Core_Config::singleton();
33421d01 1230 $dbname = DB::parseDSN($config->dsn);
bdbf899f
PN
1231 $constraintArray = array(
1232 "'FK_civicrm_financial_account_contact_id'",
1233 "'FK_civicrm_financial_item_contact_id'",
1234 "'FK_civicrm_contribution_recur_financial_type_id'",
1235 "'FK_civicrm_line_item_financial_type_id'",
1236 "'FK_civicrm_product_financial_type_id'",
1237 "'FK_civicrm_premiums_product_financial_type_id'",
1238 "'FK_civicrm_price_field_value_financial_type_id'",
1239 "'FK_civicrm_contribution_product_financial_type_id'",
1240 "'FK_civicrm_price_set_financial_type_id'",
d4b17c97 1241 "'FK_civicrm_grant_financial_type_id'",
bdbf899f
PN
1242 );
1243
77b97be7 1244 $sql = "SELECT DELETE_RULE, TABLE_NAME, CONSTRAINT_NAME
bdbf899f
PN
1245FROM information_schema.REFERENTIAL_CONSTRAINTS
1246WHERE CONSTRAINT_NAME IN (" . implode(',', $constraintArray) . ")
1247AND CONSTRAINT_SCHEMA = %1";
1248 $params = array(1 => array($dbname['database'], 'String'));
1249 $onDelete = CRM_Core_DAO::executeQuery($sql, $params, TRUE, FALSE);
1250 while ($onDelete->fetch()) {
77b97be7 1251 if (($onDelete->TABLE_NAME != 'civicrm_financial_item' && $onDelete->DELETE_RULE != 'SET NULL') ||
33421d01
TO
1252 ($onDelete->TABLE_NAME == 'civicrm_financial_item' && $onDelete->DELETE_RULE != 'CASCADE')
1253 ) {
bdbf899f
PN
1254 $tableName = 'civicrm_financial_type';
1255 $onDeleteOption = ' SET NULL ';
1256 $columnName = 'financial_type_id';
1257 if (preg_match('/contact_id/', $onDelete->CONSTRAINT_NAME)) {
1258 $tableName = 'civicrm_contact';
1259 $columnName = 'contact_id';
1260 if ($onDelete->TABLE_NAME == 'civicrm_financial_item') {
1261 $onDeleteOption = 'CASCADE';
1262 }
1263 }
1264 }
1265 else {
1266 continue;
1267 }
1268 $query = "ALTER TABLE {$onDelete->TABLE_NAME}
1269 DROP FOREIGN KEY {$onDelete->CONSTRAINT_NAME},
1270 DROP INDEX {$onDelete->CONSTRAINT_NAME};";
1271 CRM_Core_DAO::executeQuery($query, array(), TRUE, NULL, FALSE, FALSE);
1272 $query = " ALTER TABLE {$onDelete->TABLE_NAME}
1273 ADD CONSTRAINT {$onDelete->CONSTRAINT_NAME} FOREIGN KEY (`" . $columnName . "`) REFERENCES {$tableName} (`id`) ON DELETE {$onDeleteOption};
1274 ";
1275 CRM_Core_DAO::executeQuery($query, array(), TRUE, NULL, FALSE, FALSE);
1276 }
1277 return TRUE;
1278 }
1279
b676923b
PN
1280 /**
1281 * Check/Add INDEX CRM-12141
1282 *
77b97be7
EM
1283 * @param CRM_Queue_TaskContext $ctx
1284 *
a6c01b45
CW
1285 * @return bool
1286 * TRUE for success
b676923b 1287 */
00be9182 1288 public function task_4_3_x_checkIndexes(CRM_Queue_TaskContext $ctx) {
22bf3365
DL
1289 $query = "
1290SHOW KEYS
1291FROM civicrm_entity_financial_trxn
1292WHERE key_name IN ('UI_entity_financial_trxn_entity_table', 'UI_entity_financial_trxn_entity_id')
1293";
b676923b
PN
1294 $dao = CRM_Core_DAO::executeQuery($query);
1295 if (!$dao->N) {
22bf3365
DL
1296 $query = "
1297ALTER TABLE civicrm_entity_financial_trxn
b676923b 1298ADD INDEX UI_entity_financial_trxn_entity_table (entity_table),
22bf3365
DL
1299ADD INDEX UI_entity_financial_trxn_entity_id (entity_id);
1300";
1301 CRM_Core_DAO::executeQuery($query);
b676923b
PN
1302 }
1303 return TRUE;
1304 }
1305
6a488035
TO
1306 /**
1307 * Update phones CRM-11292
1308 *
77b97be7
EM
1309 * @param CRM_Queue_TaskContext $ctx
1310 *
a6c01b45
CW
1311 * @return bool
1312 * TRUE for success
6a488035 1313 */
00be9182 1314 public static function phoneNumeric(CRM_Queue_TaskContext $ctx) {
6a488035
TO
1315 CRM_Core_DAO::executeQuery(CRM_Contact_BAO_Contact::DROP_STRIP_FUNCTION_43);
1316 CRM_Core_DAO::executeQuery(CRM_Contact_BAO_Contact::CREATE_STRIP_FUNCTION_43);
1317 CRM_Core_DAO::executeQuery("UPDATE civicrm_phone SET phone_numeric = civicrm_strip_non_numeric(phone)");
1318 return TRUE;
1319 }
1320
1321 /**
1322 * (Queue Task Callback)
1323 */
00be9182 1324 public static function task_4_3_x_runSql(CRM_Queue_TaskContext $ctx, $rev) {
6a488035
TO
1325 $upgrade = new CRM_Upgrade_Form();
1326 $upgrade->processSQL($rev);
1327
1328 return TRUE;
1329 }
1330
1331 /**
1332 * Syntatic sugar for adding a task which (a) is in this class and (b) has
1333 * a high priority.
1334 *
1335 * After passing the $funcName, you can also pass parameters that will go to
1336 * the function. Note that all params must be serializable.
1337 */
1338 protected function addTask($title, $funcName) {
1339 $queue = CRM_Queue_Service::singleton()->load(array(
1340 'type' => 'Sql',
1341 'name' => CRM_Upgrade_Form::QUEUE_NAME,
1342 ));
1343
1344 $args = func_get_args();
1345 $title = array_shift($args);
1346 $funcName = array_shift($args);
1347 $task = new CRM_Queue_Task(
1348 array(get_class($this), $funcName),
1349 $args,
1350 $title
1351 );
1352 $queue->createItem($task, array('weight' => -1));
1353 }
10a5be27 1354}