Merge pull request #258 from colemanw/groupEdit
[civicrm-core.git] / CRM / Upgrade / Incremental / php / FourThree.php
1 <?php
2
3 /*
4 +--------------------------------------------------------------------+
5 | CiviCRM version 4.3 |
6 +--------------------------------------------------------------------+
7 | Copyright CiviCRM LLC (c) 2004-2013 |
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
31 * @copyright CiviCRM LLC (c) 2004-2013
32 * $Id$
33 *
34 */
35 class CRM_Upgrade_Incremental_php_FourThree {
36 const BATCH_SIZE = 5000;
37
38 function verifyPreDBstate(&$errors) {
39 return TRUE;
40 }
41
42 /**
43 * Compute any messages which should be displayed beforeupgrade
44 *
45 * Note: This function is called iteratively for each upcoming
46 * revision to the database.
47 *
48 * @param $postUpgradeMessage string, alterable
49 * @param $rev string, a version number, e.g. '4.3.alpha1', '4.3.beta3', '4.3.0'
50 * @return void
51 */
52 function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL) {
53 if ($rev == '4.3.beta3') {
54 //CRM-12084
55 //sql for checking orphaned contribution records
56 $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";
57 $count = CRM_Core_DAO::singleValueQuery($sql, array(), TRUE, FALSE);
58
59 if ($count > 0) {
60 $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(1 => $count, 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>'));
61 CRM_Core_Error::fatal($error);
62 return FALSE;
63 }
64 }
65 if ($rev == '4.3.beta4' && CRM_Utils_Constant::value('CIVICRM_UF', FALSE) == 'Drupal6') {
66 // CRM-11823 - Make sure the D6 HTML HEAD technique will work on upgrade pages
67 theme('item_list', array()); // force-load theme registry
68 $theme_registry = theme_get_registry();
69 if (
70 !isset($theme_registry['page']['preprocess functions']) ||
71 FALSE === array_search('civicrm_preprocess_page_inject', $theme_registry['page']['preprocess functions'])
72 ) {
73 CRM_Core_Error::fatal('Please reset the Drupal cache (Administer => Site Configuration => Performance => Clear cached data))');
74 }
75 }
76 }
77
78 /**
79 * Compute any messages which should be displayed after upgrade
80 *
81 * @param $postUpgradeMessage string, alterable
82 * @param $rev string, an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs
83 * @return void
84 */
85 function setPostUpgradeMessage(&$postUpgradeMessage, $rev) {
86 if ($rev == '4.3.alpha1') {
87 // check if CiviMember component is enabled
88 $config = CRM_Core_Config::singleton();
89 if (in_array('CiviMember', $config->enableComponents)) {
90 $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.');
91 $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.');
92 }
93
94 //CRM-11636
95 //here we do the financial type check and migration
96 $isDefaultsModified = self::_checkAndMigrateDefaultFinancialTypes();
97 if($isDefaultsModified) {
98 $postUpgradeMessage .= '<br />' . ts('Please review all price set financial type assignments.');
99 }
100 list($context, $orgName) = self::createDomainContacts();
101 if ($context == 'added') {
102 $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: '{$orgName}'.");
103 }
104 elseif ($context == 'merged') {
105 $postUpgradeMessage .= '<br />' . ts("The existing organization contact record for '{$orgName}' has been marked as the default domain contact, and has been updated with information from your Organization Address and Contact Info settings.");
106 }
107
108 $providerExists = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_sms_provider LIMIT 1");
109 if ($providerExists) {
110 $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'));
111 }
112 }
113
114 if ($rev == '4.3.alpha2') {
115 $sql = "
116 SELECT title, id
117 FROM civicrm_action_schedule
118 WHERE entity_value = '' OR entity_value IS NULL
119 ";
120
121 $dao = CRM_Core_DAO::executeQuery($sql);
122 $reminder = array();
123 $list = '';
124 while ($dao->fetch()) {
125 $reminder[$dao->id] = $dao->title;
126 $list .= "<li>{$dao->title}</li>";
127 }
128 if (!empty($reminder)) {
129 $list = "<br /><ul>" . $list . "</ul>";
130 $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));
131 }
132 }
133
134 if ($rev == '4.3.beta2') {
135 $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).');
136 }
137
138 if ($rev == '4.3.beta5') {
139 $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.");
140
141 // CRM-12155
142 $query = "SELECT ceft.id FROM `civicrm_financial_trxn` cft
143 LEFT JOIN civicrm_entity_financial_trxn ceft
144 ON ceft.financial_trxn_id = cft.id AND ceft.entity_table = 'civicrm_contribution'
145 LEFT JOIN civicrm_contribution cc ON cc.id = ceft.entity_id AND ceft.entity_table = 'civicrm_contribution'
146 WHERE cc.id IS NULL";
147
148 $dao = CRM_Core_DAO::executeQuery($query);
149 $isOrphanData = TRUE;
150 if (!$dao->N) {
151 $query = "SELECT cli.id FROM civicrm_line_item cli
152 LEFT JOIN civicrm_contribution cc ON cli.entity_id = cc.id AND cli.entity_table = 'civicrm_contribution'
153 LEFT JOIN civicrm_participant cp ON cli.entity_id = cp.id AND cli.entity_table = 'civicrm_participant'
154 WHERE CASE WHEN cli.entity_table = 'civicrm_contribution'
155 THEN cc.id IS NULL
156 ELSE cp.id IS NULL
157 END";
158 $dao = CRM_Core_DAO::executeQuery($query);
159 if (!$dao->N) {
160 $revPattern = '/^((\d{1,2})\.\d{1,2})\.(\d{1,2}|\w{4,7})?$/i';
161 preg_match($revPattern, $currentVer, $version);
162 if ($version[1] >= 4.3) {
163 $query = "SELECT cfi.id FROM civicrm_financial_item cfi
164 LEFT JOIN civicrm_entity_financial_trxn ceft ON ceft.entity_table = 'civicrm_financial_item' and cfi.id = ceft.entity_id
165 WHERE ceft.entity_id IS NULL;";
166 $dao = CRM_Core_DAO::executeQuery($query);
167 if (!$dao->N) {
168 $isOrphanData = FALSE;
169 }
170 }
171 else {
172 $isOrphanData = FALSE;
173 }
174 }
175 }
176
177 if ($isOrphanData) {
178 $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">this wiki page for details</a>.
179 ', array( 1 => 'http://wiki.civicrm.org/confluence/display/CRMDOC/Clean+up+extraneous+financial+data+-+4.3+upgrades')) . "</strong>";
180 }
181 }
182 }
183
184 function upgrade_4_3_alpha1($rev) {
185 self::task_4_3_alpha1_checkDBConstraints();
186
187 // add indexes for civicrm_entity_financial_trxn
188 // CRM-12141
189 $this->addTask(ts('Check/Add indexes for civicrm_entity_financial_trxn'), 'task_4_3_x_checkIndexes', $rev);
190 // task to process sql
191 $this->addTask(ts('Upgrade DB to 4.3.alpha1: SQL'), 'task_4_3_x_runSql', $rev);
192
193 //CRM-11636
194 $this->addTask(ts('Populate financial type values for price records'), 'assignFinancialTypeToPriceRecords');
195 //CRM-11514 create financial records for contributions
196 $this->addTask(ts('Create financial records for contributions'), 'createFinancialRecords');
197
198 $minId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(min(id),0) FROM civicrm_contact');
199 $maxId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(max(id),0) FROM civicrm_contact');
200 for ($startId = $minId; $startId <= $maxId; $startId += self::BATCH_SIZE) {
201 $endId = $startId + self::BATCH_SIZE - 1;
202 $title = ts('Upgrade timestamps (%1 => %2)', array(
203 1 => $startId,
204 2 => $endId,
205 ));
206 $this->addTask($title, 'convertTimestamps', $startId, $endId);
207 }
208
209 // CRM-10893
210 // fix WP access control
211 $config = CRM_Core_Config::singleton( );
212 if ($config->userFramework == 'WordPress') {
213 civicrm_wp_set_capabilities( );
214 }
215
216 // Update phones CRM-11292.
217 $this->addTask(ts('Upgrade Phone Numbers'), 'phoneNumeric');
218
219 return TRUE;
220 }
221
222 function upgrade_4_3_alpha2($rev) {
223 //CRM-11847
224 $isColumnPresent = CRM_Core_DAO::checkFieldExists('civicrm_dedupe_rule_group', 'is_default');
225 if ($isColumnPresent) {
226 CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_dedupe_rule_group DROP COLUMN is_default');
227 }
228 $this->addTask(ts('Upgrade DB to 4.3.alpha2: SQL'), 'task_4_3_x_runSql', $rev);
229 }
230
231 function upgrade_4_3_alpha3($rev) {
232 $this->addTask(ts('Upgrade DB to 4.3.alpha3: SQL'), 'task_4_3_x_runSql', $rev);
233 }
234
235 function upgrade_4_3_beta2($rev) {
236 $this->addTask(ts('Upgrade DB to 4.3.beta2: SQL'), 'task_4_3_x_runSql', $rev);
237
238 // CRM-12002
239 if (
240 CRM_Core_DAO::checkTableExists('log_civicrm_line_item') &&
241 CRM_Core_DAO::checkFieldExists('log_civicrm_line_item', 'label')
242 ) {
243 CRM_Core_DAO::executeQuery('ALTER TABLE `log_civicrm_line_item` CHANGE `label` `label` VARCHAR(255) NULL DEFAULT NULL');
244 }
245 }
246
247 function upgrade_4_3_beta3($rev) {
248 $this->addTask(ts('Upgrade DB to 4.3.beta3: SQL'), 'task_4_3_x_runSql', $rev);
249 // CRM-12065
250 $query = "SELECT id, form_values FROM civicrm_report_instance WHERE form_values LIKE '%contribution_type%'";
251 $this->addTask('Replace contribution_type to financial_type in table civicrm_report_instance', 'replaceContributionTypeId', $query, 'reportInstance');
252 $query = "SELECT * FROM civicrm_saved_search WHERE form_values LIKE '%contribution_type%'";
253 $this->addTask('Replace contribution_type to financial_type in table civicrm_saved_search', 'replaceContributionTypeId', $query, 'savedSearch');
254 }
255
256 function upgrade_4_3_beta4($rev) {
257 $this->addTask(ts('Upgrade DB to 4.3.beta4: SQL'), 'task_4_3_x_runSql', $rev);
258 // add indexes for civicrm_entity_financial_trxn
259 // CRM-12141
260 $this->addTask(ts('Check/Add indexes for civicrm_entity_financial_trxn'), 'task_4_3_x_checkIndexes', $rev);
261 }
262
263 function upgrade_4_3_beta5($rev) {
264 // CRM-12205
265 if (
266 CRM_Core_DAO::checkTableExists('log_civicrm_financial_trxn') &&
267 CRM_Core_DAO::checkFieldExists('log_civicrm_financial_trxn', 'trxn_id')
268 ) {
269 CRM_Core_DAO::executeQuery('ALTER TABLE `log_civicrm_financial_trxn` CHANGE `trxn_id` `trxn_id` VARCHAR(255) NULL DEFAULT NULL');
270 }
271 // CRM-12142 - some sites didn't get this column added yet, and sites which installed 4.3 from scratch will already have it
272 if (
273 !CRM_Core_DAO::checkFieldExists('civicrm_premiums', 'premiums_nothankyou_label')
274 ) {
275 CRM_Core_DAO::executeQuery('ALTER TABLE `civicrm_premiums` ADD COLUMN premiums_nothankyou_label varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT "Label displayed for No Thank-you option in premiums block (e.g. No thank you)"');
276 }
277 $this->addTask(ts('Upgrade DB to 4.3.beta5: SQL'), 'task_4_3_x_runSql', $rev);
278 }
279
280 //CRM-11636
281 function assignFinancialTypeToPriceRecords() {
282 $upgrade = new CRM_Upgrade_Form();
283 //here we update price set entries
284 $sqlFinancialIds = "SELECT id, name FROM civicrm_financial_type
285 WHERE name IN ('Donation', 'Event Fee', 'Member Dues');";
286 $daoFinancialIds = CRM_Core_DAO::executeQuery($sqlFinancialIds);
287 while($daoFinancialIds->fetch()) {
288 $financialIds[$daoFinancialIds->name] = $daoFinancialIds->id;
289 }
290 $sqlPriceSetUpdate = "UPDATE civicrm_price_set ps
291 SET ps.financial_type_id = CASE
292 WHEN ps.extends LIKE '%1%' THEN {$financialIds['Event Fee']}
293 WHEN ps.extends LIKE '2' THEN {$financialIds['Donation']}
294 WHEN ps.extends LIKE '3' THEN {$financialIds['Member Dues']}
295 END
296 WHERE financial_type_id IS NULL";
297 CRM_Core_DAO::executeQuery($sqlPriceSetUpdate);
298
299 //here we update price field value rows
300 $sqlPriceFieldValueUpdate = "UPDATE civicrm_price_field_value pfv
301 LEFT JOIN civicrm_membership_type mt ON (pfv.membership_type_id = mt.id)
302 INNER JOIN civicrm_price_field pf ON (pfv.price_field_id = pf.id)
303 INNER JOIN civicrm_price_set ps ON (pf.price_set_id = ps.id)
304 SET pfv.financial_type_id = CASE
305 WHEN pfv.membership_type_id IS NOT NULL THEN mt.financial_type_id
306 WHEN pfv.membership_type_id IS NULL THEN ps.financial_type_id
307 END";
308 CRM_Core_DAO::executeQuery($sqlPriceFieldValueUpdate);
309
310 return TRUE;
311 }
312
313 static function _checkAndMigrateDefaultFinancialTypes() {
314 $modifiedDefaults = FALSE;
315 //insert types if not exists
316 $sqlFetchTypes = "SELECT id, name FROM civicrm_contribution_type
317 WHERE name IN ('Donation', 'Event Fee', 'Member Dues') AND is_active =1;";
318 $daoFetchTypes = CRM_Core_DAO::executeQuery($sqlFetchTypes);
319
320 if ($daoFetchTypes->N < 3) {
321 $modifiedDefaults = TRUE;
322 $insertStatments = array (
323 'Donation' => "('Donation', 0, 1, 1)",
324 'Member' => "('Member Dues', 0, 1, 1)",
325 'Event Fee' => "('Event Fee', 0, 1, 0)",
326 );
327 foreach ($insertStatments as $values) {
328 $query = "INSERT INTO civicrm_contribution_type (name, is_reserved, is_active, is_deductible)
329 VALUES $values
330 ON DUPLICATE KEY UPDATE is_active = 1;";
331 CRM_Core_DAO::executeQuery($query);
332 }
333 }
334 return $modifiedDefaults;
335 }
336
337 function createFinancialRecords() {
338 $upgrade = new CRM_Upgrade_Form();
339
340 // update civicrm_entity_financial_trxn.amount = civicrm_financial_trxn.total_amount
341 $query = "UPDATE civicrm_entity_financial_trxn ceft
342 LEFT JOIN civicrm_financial_trxn cft ON cft.id = ceft.financial_trxn_id
343 SET ceft.amount = total_amount
344 WHERE cft.net_amount IS NOT NULL AND ceft.entity_table = 'civicrm_contribution';";
345 CRM_Core_DAO::executeQuery($query);
346
347 $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
348 $completedStatus = array_search('Completed', $contributionStatus);
349 $pendingStatus = array_search('Pending', $contributionStatus);
350 $cancelledStatus = array_search('Cancelled', $contributionStatus);
351 $queryParams = array(
352 1 => array($completedStatus, 'Integer'),
353 2 => array($pendingStatus, 'Integer'),
354 3 => array($cancelledStatus, 'Integer')
355 );
356
357 $accountType = key(CRM_Core_PseudoConstant::accountOptionValues('financial_account_type', NULL, " AND v.name = 'Asset' "));
358 $financialAccountId =
359 CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_financial_account WHERE is_default = 1 AND financial_account_type_id = {$accountType}");
360
361 $accountRelationsips = CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL);
362
363 $accountsReceivableAccount = array_search('Accounts Receivable Account is', $accountRelationsips);
364 $incomeAccountIs = array_search('Income Account is', $accountRelationsips);
365 $assetAccountIs = array_search('Asset Account is', $accountRelationsips);
366 $expenseAccountIs = array_search('Expense Account is', $accountRelationsips);
367
368 $financialItemStatus = CRM_Core_PseudoConstant::accountOptionValues('financial_item_status');
369 $unpaidStatus = array_search('Unpaid', $financialItemStatus);
370 $paidStatus = array_search('Paid', $financialItemStatus);
371
372 $validCurrencyCodes = CRM_Core_PseudoConstant::currencyCode();
373 $validCurrencyCodes = implode("','", $validCurrencyCodes);
374 $config = CRM_Core_Config::singleton();
375 $defaultCurrency = $config->defaultCurrency;
376 $now = date( 'YmdHis' );
377
378 //adding financial_trxn records and entity_financial_trxn records related to contribution
379 //Add temp column for easy entry in entity_financial_trxn
380 $sql = "ALTER TABLE civicrm_financial_trxn ADD COLUMN contribution_id INT DEFAULT NULL";
381 CRM_Core_DAO::executeQuery($sql);
382
383 //pending pay later status handling
384 $sql = "
385 INSERT INTO civicrm_financial_trxn
386 (contribution_id, payment_instrument_id, currency, total_amount, net_amount, fee_amount, trxn_id, status_id,
387 check_number, to_financial_account_id, from_financial_account_id, trxn_date)
388
389 SELECT con.id as contribution_id, con.payment_instrument_id, IF(con.currency IN ('{$validCurrencyCodes}'), con.currency, '{$defaultCurrency}')
390 as currency, con.total_amount, con.net_amount, con.fee_amount, con.trxn_id, con.contribution_status_id,
391 con.check_number, efa.financial_account_id as to_financial_account_id, NULL as from_financial_account_id,
392 REPLACE(REPLACE(REPLACE(
393 CASE
394 WHEN con.receive_date IS NOT NULL THEN
395 con.receive_date
396 WHEN con.receipt_date IS NOT NULL THEN
397 con.receipt_date
398 ELSE
399 {$now}
400 END
401 , '-', ''), ':', ''), ' ', '') as trxn_date
402 FROM civicrm_contribution con
403 LEFT JOIN civicrm_entity_financial_account efa
404 ON (con.financial_type_id = efa.entity_id AND efa.entity_table = 'civicrm_financial_type'
405 AND efa.account_relationship = {$accountsReceivableAccount})
406 WHERE con.is_pay_later = 1 AND con.contribution_status_id = {$pendingStatus}";
407 CRM_Core_DAO::executeQuery($sql);
408
409 //create a temp table to hold financial account id related to payment instruments
410 $tempTableName1 = CRM_Core_DAO::createTempTableName();
411
412 $sql = "CREATE TEMPORARY TABLE {$tempTableName1}
413
414 SELECT ceft.financial_account_id financial_account_id, cov.value as instrument_id
415 FROM civicrm_entity_financial_account ceft
416 INNER JOIN civicrm_option_value cov ON cov.id = ceft.entity_id AND ceft.entity_table = 'civicrm_option_value'
417 INNER JOIN civicrm_option_group cog ON cog.id = cov.option_group_id
418 WHERE cog.name = 'payment_instrument'";
419 CRM_Core_DAO::executeQuery($sql);
420 //CRM-12141
421 $sql = "ALTER TABLE {$tempTableName1} ADD INDEX index_instrument_id (instrument_id);";
422 CRM_Core_DAO::executeQuery($sql);
423
424 //create temp table to process completed / cancelled contribution
425 $tempTableName2 = CRM_Core_DAO::createTempTableName();
426 $sql = "CREATE TEMPORARY TABLE {$tempTableName2}
427
428 SELECT con.id as contribution_id, con.payment_instrument_id, IF(con.currency IN ('{$validCurrencyCodes}'), con.currency, '{$defaultCurrency}') as currency,
429 con.total_amount, con.net_amount, con.fee_amount, con.trxn_id, con.contribution_status_id, con.check_number, NULL as from_financial_account_id,
430 REPLACE(REPLACE(REPLACE(
431 CASE
432 WHEN con.receive_date IS NOT NULL THEN
433 con.receive_date
434 WHEN con.receipt_date IS NOT NULL THEN
435 con.receipt_date
436 ELSE
437 {$now}
438 END
439 , '-', ''), ':', ''), ' ', '') as trxn_date,
440 CASE
441 WHEN con.payment_instrument_id IS NULL THEN
442 {$financialAccountId}
443 WHEN con.payment_instrument_id IS NOT NULL THEN
444 tpi.financial_account_id
445 END as to_financial_account_id,
446 IF(eft.financial_trxn_id IS NULL, 'insert', eft.financial_trxn_id) as action
447 FROM civicrm_contribution con
448 LEFT JOIN civicrm_entity_financial_trxn eft
449 ON (eft.entity_table = 'civicrm_contribution' AND eft.entity_id = con.id)
450 LEFT JOIN {$tempTableName1} tpi
451 ON con.payment_instrument_id = tpi.instrument_id
452 WHERE con.contribution_status_id IN ({$completedStatus}, {$cancelledStatus})";
453 CRM_Core_DAO::executeQuery($sql);
454 // CRM-12141
455 $sql = "ALTER TABLE {$tempTableName2} ADD INDEX index_action (action);";
456 CRM_Core_DAO::executeQuery($sql);
457
458 //handling for completed contribution and cancelled contribution
459 //insertion of new records
460 $sql = "
461 INSERT INTO civicrm_financial_trxn
462 (contribution_id, payment_instrument_id, currency, total_amount, net_amount, fee_amount, trxn_id, status_id, check_number,
463 to_financial_account_id, from_financial_account_id, trxn_date)
464 SELECT tempI.contribution_id, tempI.payment_instrument_id, tempI.currency, tempI.total_amount, tempI.net_amount,
465 tempI.fee_amount, tempI.trxn_id, tempI.contribution_status_id, tempI.check_number,
466 tempI.to_financial_account_id, tempI.from_financial_account_id, tempI.trxn_date
467 FROM {$tempTableName2} tempI
468 WHERE tempI.action = 'insert';";
469 CRM_Core_DAO::executeQuery($sql);
470
471 //update of existing records
472 $sql = "
473 UPDATE civicrm_financial_trxn ft
474 INNER JOIN {$tempTableName2} tempU
475 ON (tempU.action != 'insert' AND ft.id = tempU.action)
476 SET ft.from_financial_account_id = NULL,
477 ft.to_financial_account_id = tempU.to_financial_account_id,
478 ft.status_id = tempU.contribution_status_id,
479 ft.payment_instrument_id = tempU.payment_instrument_id,
480 ft.check_number = tempU.check_number,
481 ft.contribution_id = tempU.contribution_id;";
482 CRM_Core_DAO::executeQuery($sql);
483
484 //insert the -ve transaction rows for cancelled contributions
485 $sql = "
486 INSERT INTO civicrm_financial_trxn
487 (contribution_id, payment_instrument_id, currency, total_amount, net_amount, fee_amount, trxn_id, status_id,
488 check_number, to_financial_account_id, from_financial_account_id, trxn_date)
489 SELECT ft.contribution_id, ft.payment_instrument_id, ft.currency, -ft.total_amount, ft.net_amount, ft.fee_amount, ft.trxn_id,
490 ft.status_id, ft.check_number, ft.to_financial_account_id, ft.from_financial_account_id, ft.trxn_date
491 FROM civicrm_financial_trxn ft
492 WHERE ft.status_id = {$cancelledStatus};";
493 CRM_Core_DAO::executeQuery($sql);
494
495 //inserting entity financial trxn entries if its not present in entity_financial_trxn for completed and pending contribution statuses
496 //this also handles +ve and -ve both transaction entries for a cancelled contribution
497 $sql = "
498 INSERT INTO civicrm_entity_financial_trxn (entity_table, entity_id, financial_trxn_id, amount)
499 SELECT 'civicrm_contribution', ft.contribution_id, ft.id, ft.total_amount as amount
500 FROM civicrm_financial_trxn ft
501 WHERE contribution_id IS NOT NULL AND
502 ft.id NOT IN (SELECT financial_trxn_id
503 FROM civicrm_entity_financial_trxn
504 WHERE entity_table = 'civicrm_contribution'
505 AND entity_id = ft.contribution_id)";
506 CRM_Core_DAO::executeQuery($sql);
507 //end of adding financial_trxn records and entity_financial_trxn records related to contribution
508
509 //update all linked line_item rows
510 // set line_item.financial_type_id = contribution.financial_type_id if contribution page id is null and not participant line item
511 // set line_item.financial_type_id = price_field_value.financial_type_id if contribution page id is set and not participant line item
512 // set line_item.financial_type_id = event.financial_type_id if its participant line item and line_item.price_field_value_id is null
513 // 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
514 $updateLineItemSql = "
515 UPDATE civicrm_line_item li
516 LEFT JOIN civicrm_contribution con
517 ON (li.entity_id = con.id AND li.entity_table = 'civicrm_contribution')
518 LEFT JOIN civicrm_price_field_value cpfv
519 ON li.price_field_value_id = cpfv.id
520 LEFT JOIN civicrm_participant cp
521 ON (li.entity_id = cp.id AND li.entity_table = 'civicrm_participant')
522 LEFT JOIN civicrm_event ce
523 ON ce.id = cp.event_id
524 SET li.financial_type_id = CASE
525 WHEN (con.contribution_page_id IS NULL || li.price_field_value_id IS NULL) AND cp.id IS NULL THEN
526 con.financial_type_id
527 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
528 cpfv.financial_type_id
529 WHEN cp.id IS NOT NULL AND li.price_field_value_id IS NULL THEN
530 ce.financial_type_id
531 END";
532 CRM_Core_DAO::executeQuery($updateLineItemSql, $queryParams);
533
534 //add the financial_item entries
535 //add a temp column so that inserting entity_financial_trxn entries gets easy
536 $sql = "ALTER TABLE civicrm_financial_item ADD COLUMN f_trxn_id INT DEFAULT NULL";
537 CRM_Core_DAO::executeQuery($sql);
538
539 //add financial_item entries for contribution completed / pending pay later / cancelled
540 $contributionlineItemSql = "
541 INSERT INTO civicrm_financial_item
542 (transaction_date, contact_id, amount, currency, entity_table, entity_id, description, status_id, financial_account_id, f_trxn_id)
543
544 SELECT REPLACE(REPLACE(REPLACE(ft.trxn_date, '-', ''), ':', ''), ' ', ''), con.contact_id,
545 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',
546 li.id as line_item_id, li.label as line_item_label,
547 IF(con.contribution_status_id = {$pendingStatus}, {$unpaidStatus}, {$paidStatus}) as status_id, efa.financial_account_id as financial_account_id,
548 ft.id as f_trxn_id
549 FROM civicrm_line_item li
550 INNER JOIN civicrm_contribution con
551 ON (li.entity_id = con.id AND li.entity_table = 'civicrm_contribution')
552 INNER JOIN civicrm_financial_trxn ft
553 ON (con.id = ft.contribution_id)
554 LEFT JOIN civicrm_entity_financial_account efa
555 ON (li.financial_type_id = efa.entity_id AND efa.entity_table = 'civicrm_financial_type'
556 AND efa.account_relationship = {$incomeAccountIs})
557 WHERE con.contribution_status_id IN (%1, %3) OR (con.is_pay_later = 1 AND con.contribution_status_id = %2)";
558 CRM_Core_DAO::executeQuery($contributionlineItemSql, $queryParams);
559
560 //add financial_item entries for event
561 $participantLineItemSql = "
562 INSERT INTO civicrm_financial_item
563 (transaction_date, contact_id, amount, currency, entity_table, entity_id, description, status_id, financial_account_id, f_trxn_id)
564
565 SELECT REPLACE(REPLACE(REPLACE(ft.trxn_date, '-', ''), ':', ''), ' ', ''), con.contact_id,
566 IF(ft.total_amount < 0 AND con.contribution_status_id = %3, -li.line_total, li.line_total) as line_total,
567 con.currency, 'civicrm_line_item', li.id as line_item_id, li.label as line_item_label,
568 IF(con.contribution_status_id = {$pendingStatus}, {$unpaidStatus}, {$paidStatus}) as status_id,
569 efa.financial_account_id as financial_account_id, ft.id as f_trxn_id
570 FROM civicrm_line_item li
571 INNER JOIN civicrm_participant par
572 ON (li.entity_id = par.id AND li.entity_table = 'civicrm_participant')
573 INNER JOIN civicrm_participant_payment pp
574 ON (pp.participant_id = par.id)
575 INNER JOIN civicrm_contribution con
576 ON (pp.contribution_id = con.id)
577 INNER JOIN civicrm_financial_trxn ft
578 ON (con.id = ft.contribution_id)
579 LEFT JOIN civicrm_entity_financial_account efa
580 ON (li.financial_type_id = efa.entity_id AND
581 efa.entity_table = 'civicrm_financial_type' AND efa.account_relationship = {$incomeAccountIs})
582 WHERE con.contribution_status_id IN (%1, %3) OR (con.is_pay_later = 1 AND con.contribution_status_id = %2)";
583 CRM_Core_DAO::executeQuery($participantLineItemSql, $queryParams);
584
585 //fee handling for contributions
586 //insert fee entries in financial_trxn for contributions
587 $sql = "ALTER TABLE civicrm_financial_trxn ADD COLUMN is_fee TINYINT DEFAULT NULL";
588 CRM_Core_DAO::executeQuery($sql);
589
590 $sql = "
591 INSERT INTO civicrm_financial_trxn
592 (contribution_id, payment_instrument_id, currency, total_amount, net_amount, fee_amount, trxn_id, status_id, check_number,
593 to_financial_account_id, from_financial_account_id, trxn_date, payment_processor_id, is_fee)
594
595 SELECT con.id, ft.payment_instrument_id, ft.currency, ft.fee_amount, NULL, NULL, ft.trxn_id, %1 as status_id,
596 ft.check_number, efaFT.financial_account_id as to_financial_account_id, CASE
597 WHEN efaPP.financial_account_id IS NOT NULL THEN
598 efaPP.financial_account_id
599 WHEN tpi.financial_account_id IS NOT NULL THEN
600 tpi.financial_account_id
601 ELSE
602 {$financialAccountId}
603 END as from_financial_account_id, ft.trxn_date, ft.payment_processor_id, 1 as is_fee
604 FROM civicrm_contribution con
605 INNER JOIN civicrm_financial_trxn ft
606 ON (ft.contribution_id = con.id)
607 LEFT JOIN civicrm_entity_financial_account efaFT
608 ON (con.financial_type_id = efaFT.entity_id AND efaFT.entity_table = 'civicrm_financial_type'
609 AND efaFT.account_relationship = {$expenseAccountIs})
610 LEFT JOIN civicrm_entity_financial_account efaPP
611 ON (ft.payment_processor_id = efaPP.entity_id AND efaPP.entity_table = 'civicrm_payment_processor'
612 AND efaPP.account_relationship = {$assetAccountIs})
613 LEFT JOIN {$tempTableName1} tpi
614 ON ft.payment_instrument_id = tpi.instrument_id
615 WHERE 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))
616 GROUP BY con.id";
617 CRM_Core_DAO::executeQuery($sql, $queryParams);
618
619 //link financial_trxn to contribution
620 $sql = "
621 INSERT INTO civicrm_entity_financial_trxn
622 (entity_table, entity_id, financial_trxn_id, amount)
623 SELECT 'civicrm_contribution', ft.contribution_id, ft.id, ft.total_amount
624 FROM civicrm_financial_trxn ft
625 WHERE ft.is_fee = 1";
626 CRM_Core_DAO::executeQuery($sql);
627
628 //add fee related entries to financial item table
629 $domainId = CRM_Core_Config::domainID();
630 $domainContactId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Domain', $domainId, 'contact_id');
631 $sql = "
632 INSERT INTO civicrm_financial_item
633 (transaction_date, contact_id, amount, currency, entity_table, entity_id, description, status_id, financial_account_id, f_trxn_id)
634 SELECT ft.trxn_date, {$domainContactId} as contact_id, ft.total_amount, ft.currency, 'civicrm_financial_trxn', ft.id,
635 'Fee', {$paidStatus} as status_id, ft.to_financial_account_id as financial_account_id, ft.id as f_trxn_id
636 FROM civicrm_financial_trxn ft
637 WHERE ft.is_fee = 1;";
638 CRM_Core_DAO::executeQuery($sql);
639
640 //add entries to entity_financial_trxn table
641 $sql = "
642 INSERT INTO civicrm_entity_financial_trxn (entity_table, entity_id, financial_trxn_id, amount)
643 SELECT 'civicrm_financial_item' as entity_table, fi.id as entity_id, fi.f_trxn_id as financial_trxn_id, fi.amount
644 FROM civicrm_financial_item fi";
645 CRM_Core_DAO::executeQuery($sql);
646
647 //drop the temparory columns
648 $sql = "ALTER TABLE civicrm_financial_trxn
649 DROP COLUMN contribution_id,
650 DROP COLUMN is_fee;";
651 CRM_Core_DAO::executeQuery($sql);
652
653 $sql = "ALTER TABLE civicrm_financial_item DROP f_trxn_id";
654 CRM_Core_DAO::executeQuery($sql);
655
656 return TRUE;
657 }
658
659 function createDomainContacts() {
660 $domainParams = $context = array();
661 $query = "
662 ALTER 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',
663 ADD CONSTRAINT `FK_civicrm_domain_contact_id` FOREIGN KEY (`contact_id`) REFERENCES `civicrm_contact` (`id`);";
664 CRM_Core_DAO::executeQuery($query, CRM_Core_DAO::$_nullArray, TRUE, NULL, FALSE, FALSE);
665
666 $query = 'SELECT cd.id, cd.name, ce.email FROM `civicrm_domain` cd
667 LEFT JOIN civicrm_loc_block clb ON clb.id = cd. loc_block_id
668 LEFT JOIN civicrm_email ce ON ce.id = clb.email_id ;' ;
669 $dao = CRM_Core_DAO::executeQuery($query);
670 while($dao->fetch()) {
671 $params = array(
672 'sort_name' => $dao->name,
673 'display_name' => $dao->name,
674 'legal_name' => $dao->name,
675 'organization_name' => $dao->name,
676 'contact_type' => 'Organization'
677 );
678 $query = "SELECT cc.id FROM `civicrm_contact` cc
679 LEFT JOIN civicrm_email ce ON ce.contact_id = cc.id
680 WHERE cc.contact_type = 'Organization' AND cc.organization_name = '{$dao->name}' ";
681 if ($dao->email) {
682 $query .= " AND ce.email = '{$dao->email}' ";
683 }
684 $contactID = CRM_Core_DAO::singleValueQuery($query);
685 $context[1] = $dao->name;
686 if (empty($contactID)) {
687 $contact = CRM_Contact_BAO_Contact::add($params);
688 $contactID = $contact->id;
689 $context[0] = 'added';
690 }
691 else {
692 $context[0] = 'merged';
693 }
694 $domainParams['contact_id'] = $contactID;
695 CRM_Core_BAO_Domain::edit($domainParams, $dao->id);
696 }
697 return $context;
698 }
699
700 function task_4_3_alpha1_checkDBConstraints() {
701 //checking whether the foreign key exists before dropping it CRM-11260
702 $config = CRM_Core_Config::singleton();
703 $dbUf = DB::parseDSN($config->dsn);
704 $params = array();
705 $tables = array(
706 'autorenewal_msg_id' => array('tableName' => 'civicrm_membership_type', 'fkey' => 'FK_civicrm_membership_autorenewal_msg_id'),
707 'to_account_id' => array('tableName' => 'civicrm_financial_trxn', 'constraintName' => 'civicrm_financial_trxn_ibfk_2'),
708 'from_account_id' => array('tableName' => 'civicrm_financial_trxn', 'constraintName' => 'civicrm_financial_trxn_ibfk_1'),
709 'contribution_type_id' => array('tableName' => 'civicrm_contribution_recur', 'fkey' => 'FK_civicrm_contribution_recur_contribution_type_id'),
710 );
711 $query = "SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
712 WHERE table_name = 'civicrm_contribution_recur'
713 AND constraint_name = 'FK_civicrm_contribution_recur_contribution_type_id'
714 AND TABLE_SCHEMA = '{$dbUf['database']}'";
715
716 $dao = CRM_Core_DAO::executeQuery($query, $params, TRUE, NULL, FALSE, FALSE);
717 foreach($tables as $columnName => $value){
718 if ($value['tableName'] == 'civicrm_membership_type' || $value['tableName'] == 'civicrm_contribution_recur') {
719 $foreignKeyExists = CRM_Core_DAO::checkConstraintExists($value['tableName'], $value['fkey']);
720 $fKey = $value['fkey'];
721 } else {
722 $foreignKeyExists = CRM_Core_DAO::checkFKConstraintInFormat($value['tableName'], $columnName);
723 $fKey = "`FK_{$value['tableName']}_{$columnName}`";
724 }
725 if ($foreignKeyExists || $value['tableName'] == 'civicrm_financial_trxn') {
726 if ($value['tableName'] != 'civicrm_contribution_recur' || ($value['tableName'] == 'civicrm_contribution_recur' && $dao->N)) {
727 $constraintName = $foreignKeyExists ? $fKey : $value['constraintName'];
728 CRM_Core_DAO::executeQuery("ALTER TABLE {$value['tableName']} DROP FOREIGN KEY {$constraintName}", $params, TRUE, NULL, FALSE, FALSE);
729 }
730 CRM_Core_DAO::executeQuery("ALTER TABLE {$value['tableName']} DROP INDEX {$fKey}", $params, TRUE, NULL, FALSE, FALSE);
731 }
732 }
733 // check if column contact_id is present or not in civicrm_financial_account
734 $fieldExists = CRM_Core_DAO::checkFieldExists('civicrm_financial_account', 'contact_id', FALSE);
735 if (!$fieldExists) {
736 $query = "ALTER TABLE civicrm_financial_account ADD `contact_id` int(10) unsigned DEFAULT NULL COMMENT 'Version identifier of financial_type' AFTER `name`, ADD CONSTRAINT `FK_civicrm_financial_account_contact_id` FOREIGN KEY (`contact_id`) REFERENCES `civicrm_contact`(id);";
737 CRM_Core_DAO::executeQuery($query, $params, TRUE, NULL, FALSE, FALSE);
738 }
739 }
740
741 /**
742 * Read creation and modification times from civicrm_log; add
743 * them to civicrm_contact.
744 */
745 function convertTimestamps(CRM_Queue_TaskContext $ctx, $startId, $endId) {
746 $sql = "
747 SELECT entity_id, min(modified_date) AS created, max(modified_date) AS modified
748 FROM civicrm_log
749 WHERE entity_table = 'civicrm_contact'
750 AND entity_id BETWEEN %1 AND %2
751 GROUP BY entity_id
752 ";
753 $params = array(
754 1 => array($startId, 'Integer'),
755 2 => array($endId, 'Integer'),
756 );
757 $dao = CRM_Core_DAO::executeQuery($sql, $params);
758 while ($dao->fetch()) {
759 // FIXME civicrm_log.modified_date is DATETIME; civicrm_contact.modified_date is TIMESTAMP
760 CRM_Core_DAO::executeQuery(
761 'UPDATE civicrm_contact SET created_date = %1, modified_date = %2 WHERE id = %3',
762 array(
763 1 => array($dao->created, 'String'),
764 2 => array($dao->modified, 'String'),
765 3 => array($dao->entity_id, 'Integer'),
766 )
767 );
768 }
769
770 return TRUE;
771 }
772
773 /**
774 * replace contribution_type to financial_type in table
775 * civicrm_saved_search and Structure civicrm_report_instance
776 */
777 function replaceContributionTypeId(CRM_Queue_TaskContext $ctx, $query, $table) {
778 $dao = CRM_Core_DAO::executeQuery($query);
779 while ($dao->fetch()) {
780 $formValues = unserialize($dao->form_values);
781 foreach (array('contribution_type_id_op', 'contribution_type_id_value', 'contribution_type_id') as $value) {
782 if (array_key_exists($value, $formValues)) {
783 $key = preg_replace('/contribution/', 'financial', $value);
784 $formValues[$key] = $formValues[$value];
785 unset($formValues[$value]);
786 }
787 }
788 if ($table != 'savedSearch') {
789 foreach (array('fields', 'group_bys') as $value) {
790 if (array_key_exists($value, $formValues)) {
791 if (array_key_exists('contribution_type_id', $formValues[$value])) {
792 $formValues[$value]['financial_type_id'] = $formValues[$value]['contribution_type_id'];
793 unset($formValues[$value]['contribution_type_id']);
794 }
795 else if (array_key_exists('contribution_type', $formValues[$value])) {
796 $formValues[$value]['financial_type'] = $formValues[$value]['contribution_type'];
797 unset($formValues[$value]['contribution_type']);
798 }
799 }
800 }
801 if (array_key_exists('order_bys', $formValues)) {
802 foreach ($formValues['order_bys'] as $key => $values) {
803 if (preg_grep('/contribution_type/', $values)) {
804 $formValues['order_bys'][$key]['column'] = preg_replace('/contribution_type/', 'financial_type', $values['column']);
805 }
806 }
807 }
808 }
809
810 if ($table == 'savedSearch') {
811 $saveDao = new CRM_Contact_DAO_SavedSearch();
812 }
813 else {
814 $saveDao = new CRM_Report_DAO_Instance();
815 }
816 $saveDao->id = $dao->id;
817
818 if ($table == 'savedSearch') {
819 if (array_key_exists('mapper', $formValues)) {
820 foreach ($formValues['mapper'] as $key => $values) {
821 foreach ($values as $k => $v) {
822 if (preg_grep('/contribution_/', $v)) {
823 $formValues['mapper'][$key][$k] = preg_replace('/contribution_type/', 'financial_type', $v);
824 }
825 }
826 }
827 }
828 foreach (array('select_tables', 'where_tables') as $value) {
829 if (preg_match('/contribution_type/', $dao->$value)) {
830 $tempValue = unserialize($dao->$value);
831 if (array_key_exists('civicrm_contribution_type', $tempValue)) {
832 $tempValue['civicrm_financial_type'] = $tempValue['civicrm_contribution_type'];
833 unset($tempValue['civicrm_contribution_type']);
834 }
835 $saveDao->$value = serialize($tempValue);
836 }
837 }
838 if (preg_match('/contribution_type/', $dao->where_clause)) {
839 $saveDao->where_clause = preg_replace('/contribution_type/', 'financial_type', $dao->where_clause);
840 }
841 }
842 $saveDao->form_values = serialize($formValues);
843
844 $saveDao->save();
845 }
846 return TRUE;
847 }
848
849 /**
850 * Check/Add INDEX CRM-12141
851 *
852 * @return bool TRUE for success
853 */
854 function task_4_3_x_checkIndexes(CRM_Queue_TaskContext $ctx) {
855 $query = "SHOW KEYS FROM `civicrm_entity_financial_trxn`
856 WHERE key_name IN ('UI_entity_financial_trxn_entity_table', 'UI_entity_financial_trxn_entity_id');";
857 $dao = CRM_Core_DAO::executeQuery($query);
858 if (!$dao->N) {
859 CRM_Core_DAO::executeQuery("ALTER TABLE civicrm_entity_financial_trxn
860 ADD INDEX UI_entity_financial_trxn_entity_table (entity_table),
861 ADD INDEX UI_entity_financial_trxn_entity_id (entity_id);");
862 }
863 return TRUE;
864 }
865
866 /**
867 * Update phones CRM-11292
868 *
869 * @return bool TRUE for success
870 */
871 static function phoneNumeric(CRM_Queue_TaskContext $ctx) {
872 CRM_Core_DAO::executeQuery(CRM_Contact_BAO_Contact::DROP_STRIP_FUNCTION_43);
873 CRM_Core_DAO::executeQuery(CRM_Contact_BAO_Contact::CREATE_STRIP_FUNCTION_43);
874 CRM_Core_DAO::executeQuery("UPDATE civicrm_phone SET phone_numeric = civicrm_strip_non_numeric(phone)");
875 return TRUE;
876 }
877
878 /**
879 * (Queue Task Callback)
880 */
881 static function task_4_3_x_runSql(CRM_Queue_TaskContext $ctx, $rev) {
882 $upgrade = new CRM_Upgrade_Form();
883 $upgrade->processSQL($rev);
884
885 return TRUE;
886 }
887
888 /**
889 * Syntatic sugar for adding a task which (a) is in this class and (b) has
890 * a high priority.
891 *
892 * After passing the $funcName, you can also pass parameters that will go to
893 * the function. Note that all params must be serializable.
894 */
895 protected function addTask($title, $funcName) {
896 $queue = CRM_Queue_Service::singleton()->load(array(
897 'type' => 'Sql',
898 'name' => CRM_Upgrade_Form::QUEUE_NAME,
899 ));
900
901 $args = func_get_args();
902 $title = array_shift($args);
903 $funcName = array_shift($args);
904 $task = new CRM_Queue_Task(
905 array(get_class($this), $funcName),
906 $args,
907 $title
908 );
909 $queue->createItem($task, array('weight' => -1));
910 }
911 }