Merge pull request #4764 from rohankatkar/CRM-15615
[civicrm-core.git] / CRM / Upgrade / Incremental / php / FourFive.php
CommitLineData
296342b1
OB
1<?php
2/*
3 +--------------------------------------------------------------------+
06b69b18 4 | CiviCRM version 4.5 |
296342b1 5 +--------------------------------------------------------------------+
06b69b18 6 | Copyright CiviCRM LLC (c) 2004-2014 |
296342b1
OB
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License along with this program; if not, contact CiviCRM LLC |
21 | at info[AT]civicrm[DOT]org. If you have questions about the |
22 | GNU Affero General Public License or the licensing of CiviCRM, |
23 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
24 +--------------------------------------------------------------------+
25*/
26
27/**
28 *
29 * @package CRM
06b69b18 30 * @copyright CiviCRM LLC (c) 2004-2014
296342b1
OB
31 * $Id$
32 *
33 */
34class CRM_Upgrade_Incremental_php_FourFive {
35 const BATCH_SIZE = 5000;
36
624e56fa
EM
37 /**
38 * @param $errors
39 *
40 * @return bool
41 */
296342b1
OB
42 function verifyPreDBstate(&$errors) {
43 return TRUE;
44 }
45
46 /**
47 * Compute any messages which should be displayed beforeupgrade
48 *
49 * Note: This function is called iteratively for each upcoming
50 * revision to the database.
51 *
d0f74b53 52 * @param $preUpgradeMessage
296342b1 53 * @param $rev string, a version number, e.g. '4.4.alpha1', '4.4.beta3', '4.4.0'
d0f74b53
EM
54 * @param null $currentVer
55 *
296342b1
OB
56 * @return void
57 */
58 function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL) {
59 }
60
61 /**
62 * Compute any messages which should be displayed after upgrade
63 *
64 * @param $postUpgradeMessage string, alterable
65 * @param $rev string, an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs
66 * @return void
67 */
68 function setPostUpgradeMessage(&$postUpgradeMessage, $rev) {
1421174e 69 if ($rev == '4.5.alpha1') {
e2cd07fc 70 $postUpgradeMessage .= '<br /><br />' . ts('Default versions of the following System Workflow Message Templates have been modified to handle new functionality: <ul><li>Contributions - Receipt (off-line)</li><li>Contributions - Receipt (on-line)</li><li>Contributions - Recurring Start and End Notification</li><li>Contributions - Recurring Updates</li><li>Memberships - Receipt (on-line)</li><li>Memberships - Signup and Renewal Receipts (off-line)</li><li>Pledges - Acknowledgement</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). (<a href="%1">learn more...</a>)', array(1 => 'http://wiki.civicrm.org/confluence/display/CRMDOC/Updating+System+Workflow+Message+Templates+after+Upgrades+-+method+1+-+kdiff'));
b05a0fb6 71 $postUpgradeMessage .= '<br /><br />' . ts('This release allows you to view and edit multiple-record custom field sets in a table format which will be more usable in some cases. You can try out the format by navigating to Administer > Custom Data & Screens > Custom Fields. Click Settings for a custom field set and change Display Style to "Tab with Tables".');
03390e26 72 $postUpgradeMessage .= '<br /><br />' . ts('This release changes the way that anonymous event registrations match participants with existing contacts. By default, all event participants will be matched with existing individuals using the Unsupervised rule, even if multiple registrations with the same email address are allowed. However, you can now select a different matching rule to use for each event. Please review your events to make sure you choose the appropriate matching rule and collect sufficient information for it to match contacts.');
1421174e 73 }
7c3d751c
DG
74 if ($rev == '4.5.beta2') {
75 $postUpgradeMessage .= '<br /><br />' . ts('If you use CiviMail for newsletters or other communications, check out the new sample CiviMail templates which use responsive design to optimize display on mobile devices (Administer > Communications > Message Templates ).');
76 }
0cc5fafb 77 if ($rev == '4.5.1') {
df7a207d 78 $postUpgradeMessage .= '<br /><br />' . ts('WARNING: If you use CiviCase with v4.5.alpha*, v4.5.beta*, or v4.5.0, it is possible that previous upgrades corrupted some CiviCase metadata. If you have not already done so, please identify any custom field sets, smart groups, or reports which refer to CiviCase and ensure that they are properly configured.');
0cc5fafb 79 }
296342b1
OB
80 }
81
624e56fa
EM
82 /**
83 * @param $rev
84 *
85 * @return bool
86 */
296342b1
OB
87 function upgrade_4_5_alpha1($rev) {
88 // task to process sql
3182e644 89 $this->addTask(ts('Migrate honoree information to module_data'), 'migrateHonoreeInfo');
296342b1 90 $this->addTask(ts('Upgrade DB to 4.5.alpha1: SQL'), 'task_4_5_x_runSql', $rev);
8b49cb50
OB
91 $this->addTask(ts('Set default for Individual name fields configuration'), 'addNameFieldOptions');
92
64542f7e
PJ
93 // CRM-14522 - The below schema checking is done as foreign key name
94 // for pdf_format_id column varies for different databases
95 // if DB is been into upgrade for 3.4.2 version, it would have pdf_format_id name for FK
96 // else FK_civicrm_msg_template_pdf_format_id
97 $config = CRM_Core_Config::singleton();
98 $dbUf = DB::parseDSN($config->dsn);
99 $query = "
100SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
101WHERE TABLE_NAME = 'civicrm_msg_template'
102AND CONSTRAINT_TYPE = 'FOREIGN KEY'
103AND TABLE_SCHEMA = %1
104";
105 $params = array(1 => array($dbUf['database'], 'String'));
106 $dao = CRM_Core_DAO::executeQuery($query, $params, TRUE, NULL, FALSE, FALSE);
107 if ($dao->fetch()) {
108 if ($dao->CONSTRAINT_NAME == 'FK_civicrm_msg_template_pdf_format_id' ||
109 $dao->CONSTRAINT_NAME == 'pdf_format_id') {
110 $sqlDropFK = "ALTER TABLE `civicrm_msg_template`
111DROP FOREIGN KEY `{$dao->CONSTRAINT_NAME}`,
112DROP KEY `{$dao->CONSTRAINT_NAME}`";
113 CRM_Core_DAO::executeQuery($sqlDropFK, CRM_Core_DAO::$_nullArray, TRUE, NULL, FALSE, FALSE);
114 }
115 }
116
8b49cb50
OB
117 return TRUE;
118 }
119
f49da658
PN
120 /**
121 * @param $rev
122 *
123 * @return bool
124 */
125 function upgrade_4_5_beta9($rev) {
126 $this->addTask(ts('Upgrade DB to 4.5.beta9: SQL'), 'task_4_5_x_runSql', $rev);
0cc5fafb 127
15ed8da7
PN
128 $entityTable = array(
129 'Participant' => 'civicrm_participant_payment',
17ea44da 130 'Contribution' => 'civicrm_contribution',
15ed8da7
PN
131 'Membership' => 'civicrm_membership',
132 );
0cc5fafb 133
15ed8da7
PN
134 foreach ($entityTable as $label => $tableName) {
135 list($minId, $maxId) = CRM_Core_DAO::executeQuery("SELECT coalesce(min(id),0), coalesce(max(id),0)
136 FROM {$tableName}")->getDatabaseResult()->fetchRow();
137 for ($startId = $minId; $startId <= $maxId; $startId += self::BATCH_SIZE) {
138 $endId = $startId + self::BATCH_SIZE - 1;
139 $title = ts("Upgrade DB to 4.5.beta9: Fix line items for {$label} (%1 => %2)", array(1 => $startId, 2 => $endId));
140 $this->addTask($title, 'task_4_5_0_fixLineItem', $startId, $endId, $label);
0cc5fafb 141 }
142 }
f49da658
PN
143 return TRUE;
144 }
145
146 /**
147 * (Queue Task Callback)
148 *
c490a46a 149 * update the line items
0cc5fafb 150 *
f49da658
PN
151 *
152 * @param CRM_Queue_TaskContext $ctx
153 * @param $startId int, the first/lowest entity ID to convert
154 * @param $endId int, the last/highest entity ID to convert
0cc5fafb 155 * @param
f49da658
PN
156 *
157 * @return bool
158 */
159 static function task_4_5_0_fixLineItem(CRM_Queue_TaskContext $ctx, $startId, $endId, $entityTable) {
0cc5fafb 160
f49da658
PN
161 $sqlParams = array(
162 1 => array($startId, 'Integer'),
163 2 => array($endId, 'Integer'),
164 );
165 switch ($entityTable) {
0cc5fafb 166 case 'Contribution':
f49da658 167 // update all the line item entity_table and entity_id with contribution due to bug CRM-15055
17ea44da
PN
168 CRM_Core_DAO::executeQuery("UPDATE civicrm_line_item li
169 INNER JOIN civicrm_contribution cc ON cc.id = li.contribution_id
170 SET entity_id = li.contribution_id, entity_table = 'civicrm_contribution'
171 WHERE li.contribution_id IS NOT NULL AND li.entity_table <> 'civicrm_participant' AND (cc.id BETWEEN %1 AND %2)", $sqlParams);
0cc5fafb 172
f49da658 173 // update the civicrm_line_item.contribution_id
17ea44da 174 CRM_Core_DAO::executeQuery("UPDATE civicrm_line_item li
0cc5fafb 175 INNER JOIN civicrm_contribution cc ON cc.id = li.entity_id
f49da658 176 SET contribution_id = entity_id
0cc5fafb 177 WHERE li.contribution_id IS NULL AND li.entity_table = 'civicrm_contribution' AND (cc.id BETWEEN %1 AND %2)", $sqlParams);
f49da658 178 break;
0cc5fafb 179
15ed8da7 180 case 'Participant':
f49da658 181 // update the civicrm_line_item.contribution_id
0cc5fafb 182 CRM_Core_DAO::executeQuery("UPDATE civicrm_line_item li
f49da658
PN
183 INNER JOIN civicrm_participant_payment pp ON pp.participant_id = li.entity_id
184 SET li.contribution_id = pp.contribution_id
17ea44da 185 WHERE li.entity_table = 'civicrm_participant' AND li.contribution_id IS NULL AND (pp.id BETWEEN %1 AND %2)", $sqlParams);
f49da658 186 break;
0cc5fafb 187
15ed8da7 188 case 'Membership':
f49da658
PN
189 $upgrade = new CRM_Upgrade_Form();
190 // update the line item of membership
191 CRM_Core_DAO::executeQuery("UPDATE civicrm_line_item li
192 INNER JOIN civicrm_membership_payment mp ON mp.contribution_id = li.contribution_id
193 INNER JOIN civicrm_membership cm ON mp.membership_id = cm.id
194 INNER JOIN civicrm_price_field_value pv ON pv.id = li.price_field_value_id
195 SET li.entity_table = 'civicrm_membership', li.entity_id = mp.membership_id
196 WHERE li.entity_table = 'civicrm_contribution'
17ea44da 197 AND pv.membership_type_id IS NOT NULL AND cm.membership_type_id = pv.membership_type_id AND (cm.id BETWEEN %1 AND %2)", $sqlParams);
0cc5fafb 198
f49da658
PN
199 CRM_Core_DAO::executeQuery("UPDATE civicrm_line_item li
200 INNER JOIN civicrm_membership_payment mp ON mp.contribution_id = li.contribution_id
201 INNER JOIN civicrm_price_field_value pv ON pv.id = li.price_field_value_id
202 SET li.entity_table = 'civicrm_membership', li.entity_id = mp.membership_id
203 WHERE li.entity_table = 'civicrm_contribution'
17ea44da 204 AND pv.membership_type_id IS NOT NULL AND (mp.membership_id BETWEEN %1 AND %2)", $sqlParams);
0cc5fafb 205
17ea44da 206 CRM_Core_DAO::executeQuery("INSERT INTO civicrm_line_item (entity_table, entity_id, price_field_id, label,
f49da658 207 qty, unit_price, line_total, price_field_value_id, financial_type_id)
0cc5fafb 208 SELECT 'civicrm_membership', cm.id, cpf.id price_field_id, cpfv.label, 1 as qty, cpfv.amount, cpfv.amount line_total,
f49da658
PN
209 cpfv.id price_field_value_id, cpfv.financial_type_id FROM civicrm_membership cm
210 LEFT JOIN civicrm_membership_payment cmp ON cmp.membership_id = cm.id
17ea44da
PN
211 INNER JOIN civicrm_price_field_value cpfv ON cpfv.membership_type_id = cm.membership_type_id
212 INNER JOIN civicrm_price_field cpf ON cpf.id = cpfv.price_field_id
213 INNER JOIN civicrm_price_set cps ON cps.id = cpf.price_set_id
f49da658
PN
214 WHERE cmp.contribution_id IS NULL AND cps.name = 'default_membership_type_amount' AND (cm.id BETWEEN %1 AND %2)", $sqlParams);
215 break;
0cc5fafb 216 }
f49da658
PN
217 return TRUE;
218 }
219
8b49cb50
OB
220 /**
221 * Add defaults for the newly introduced name fields configuration in 'contact_edit_options' setting
222 *
d0f74b53
EM
223 * @param CRM_Queue_TaskContext $ctx
224 *
8b49cb50
OB
225 * @return bool TRUE for success
226 */
227 static function addNameFieldOptions(CRM_Queue_TaskContext $ctx) {
228 $query = "SELECT `value` FROM `civicrm_setting` WHERE `group_name` = 'CiviCRM Preferences' AND `name` = 'contact_edit_options'";
229 $dao = CRM_Core_DAO::executeQuery($query);
230 $dao->fetch();
231 $oldValue = unserialize($dao->value);
232
233 $newValue = $oldValue . '12\ 114\ 115\ 116\ 117\ 1';
234
235 $query = "UPDATE `civicrm_setting` SET `value` = %1 WHERE `group_name` = 'CiviCRM Preferences' AND `name` = 'contact_edit_options'";
236 $params = array(1 => array(serialize($newValue), 'String'));
237 CRM_Core_DAO::executeQuery($query, $params);
238
296342b1
OB
239 return TRUE;
240 }
241
3182e644 242 /**
243 * Migrate honoree information to uf_join.module_data as honoree columns (text and title) will be dropped
244 * on DB upgrade
245 *
246 * @param CRM_Queue_TaskContext $ctx
247 *
248 * @return bool TRUE for success
249 */
250 static function migrateHonoreeInfo(CRM_Queue_TaskContext $ctx) {
251 $query = "ALTER TABLE `civicrm_uf_join`
252 ADD COLUMN `module_data` longtext COMMENT 'Json serialized array of data used by the ufjoin.module'";
253 CRM_Core_DAO::executeQuery($query);
254
255 $honorTypes = array_keys(CRM_Core_OptionGroup::values('honor_type'));
256 $ufGroupDAO = new CRM_Core_DAO_UFGroup();
257 $ufGroupDAO->name = 'new_individual';
258 $ufGroupDAO->find(TRUE);
259
260 $query = "SELECT * FROM civicrm_contribution_page";
261 $dao = CRM_Core_DAO::executeQuery($query);
262
263 if ($dao->N) {
264 $domain = new CRM_Core_DAO_Domain;
265 $domain->find(TRUE);
266 while ($dao->fetch()) {
267 $honorParams = array('soft_credit' => array('soft_credit_types' => $honorTypes));
268 if ($domain->locales) {
269 $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);
270 foreach ($locales as $locale) {
271 $honor_block_title = "honor_block_title_{$locale}";
272 $honor_block_text = "honor_block_text_{$locale}";
273 $honorParams['soft_credit'] += array(
274 $locale => array(
275 'honor_block_title' => $dao->$honor_block_title,
276 'honor_block_text' => $dao->$honor_block_text,
277 ),
278 );
279 }
280 }
281 else {
282 $honorParams['soft_credit'] += array(
283 'default' => array(
284 'honor_block_title' => $dao->honor_block_title,
285 'honor_block_text' => $dao->honor_block_text,
286 ),
287 );
288 }
289 $ufJoinParam = array(
290 'module' => 'soft_credit',
291 'entity_table' => 'civicrm_contribution_page',
292 'is_active' => $dao->honor_block_is_active,
293 'entity_id' => $dao->id,
294 'uf_group_id' => $ufGroupDAO->id,
295 'module_data' => json_encode($honorParams),
296 );
297 CRM_Core_BAO_UFJoin::create($ufJoinParam);
298 }
299 }
300
301 return TRUE;
302 }
303
296342b1
OB
304 /**
305 * (Queue Task Callback)
306 */
307 static function task_4_5_x_runSql(CRM_Queue_TaskContext $ctx, $rev) {
308 $upgrade = new CRM_Upgrade_Form();
309 $upgrade->processSQL($rev);
310
311 return TRUE;
312 }
313
314 /**
d0f74b53 315 * Syntactic sugar for adding a task which (a) is in this class and (b) has
296342b1
OB
316 * a high priority.
317 *
318 * After passing the $funcName, you can also pass parameters that will go to
319 * the function. Note that all params must be serializable.
320 */
321 protected function addTask($title, $funcName) {
322 $queue = CRM_Queue_Service::singleton()->load(array(
323 'type' => 'Sql',
324 'name' => CRM_Upgrade_Form::QUEUE_NAME,
325 ));
326
327 $args = func_get_args();
328 $title = array_shift($args);
329 $funcName = array_shift($args);
330 $task = new CRM_Queue_Task(
331 array(get_class($this), $funcName),
332 $args,
333 $title
334 );
335 $queue->createItem($task, array('weight' => -1));
336 }
337}