Merge pull request #12682 from eileenmcnaughton/date_extension
[civicrm-core.git] / CRM / Upgrade / Incremental / php / FourFive.php
CommitLineData
296342b1
OB
1<?php
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
296342b1 5 +--------------------------------------------------------------------+
8c9251b3 6 | Copyright CiviCRM LLC (c) 2004-2018 |
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 |
c73475ea 12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
296342b1
OB
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 |
c73475ea
WA
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
296342b1
OB
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 +--------------------------------------------------------------------+
d25dd0ee 26 */
296342b1
OB
27
28/**
bf6a5362 29 * Upgrade logic for 4.5
296342b1 30 */
bf6a5362 31class CRM_Upgrade_Incremental_php_FourFive extends CRM_Upgrade_Incremental_Base {
296342b1
OB
32
33 /**
fe482240 34 * Compute any messages which should be displayed after upgrade.
296342b1 35 *
5a4f6742
CW
36 * @param string $postUpgradeMessage
37 * alterable.
38 * @param string $rev
39 * an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs.
296342b1 40 */
00be9182 41 public function setPostUpgradeMessage(&$postUpgradeMessage, $rev) {
1421174e 42 if ($rev == '4.5.alpha1') {
e2cd07fc 43 $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 44 $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 45 $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 46 }
7c3d751c
DG
47 if ($rev == '4.5.beta2') {
48 $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 ).');
49 }
0cc5fafb 50 if ($rev == '4.5.1') {
df7a207d 51 $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 52 }
296342b1
OB
53 }
54
624e56fa
EM
55 /**
56 * @param $rev
57 *
58 * @return bool
59 */
00be9182 60 public function upgrade_4_5_alpha1($rev) {
296342b1 61 // task to process sql
b604d7ec 62 $this->addTask('Migrate honoree information to module_data', 'migrateHonoreeInfo');
bf6a5362 63 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.5.alpha1')), 'runSql', $rev);
b604d7ec 64 $this->addTask('Set default for Individual name fields configuration', 'addNameFieldOptions');
8b49cb50 65
64542f7e
PJ
66 // CRM-14522 - The below schema checking is done as foreign key name
67 // for pdf_format_id column varies for different databases
68 // if DB is been into upgrade for 3.4.2 version, it would have pdf_format_id name for FK
69 // else FK_civicrm_msg_template_pdf_format_id
70 $config = CRM_Core_Config::singleton();
71 $dbUf = DB::parseDSN($config->dsn);
72 $query = "
73SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
74WHERE TABLE_NAME = 'civicrm_msg_template'
75AND CONSTRAINT_TYPE = 'FOREIGN KEY'
76AND TABLE_SCHEMA = %1
77";
78 $params = array(1 => array($dbUf['database'], 'String'));
79 $dao = CRM_Core_DAO::executeQuery($query, $params, TRUE, NULL, FALSE, FALSE);
80 if ($dao->fetch()) {
81 if ($dao->CONSTRAINT_NAME == 'FK_civicrm_msg_template_pdf_format_id' ||
353ffa53
TO
82 $dao->CONSTRAINT_NAME == 'pdf_format_id'
83 ) {
64542f7e
PJ
84 $sqlDropFK = "ALTER TABLE `civicrm_msg_template`
85DROP FOREIGN KEY `{$dao->CONSTRAINT_NAME}`,
86DROP KEY `{$dao->CONSTRAINT_NAME}`";
87 CRM_Core_DAO::executeQuery($sqlDropFK, CRM_Core_DAO::$_nullArray, TRUE, NULL, FALSE, FALSE);
88 }
89 }
90
8b49cb50
OB
91 return TRUE;
92 }
93
f49da658
PN
94 /**
95 * @param $rev
96 *
97 * @return bool
98 */
00be9182 99 public function upgrade_4_5_beta9($rev) {
bf6a5362 100 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.5.beta9')), 'runSql', $rev);
0cc5fafb 101
15ed8da7
PN
102 $entityTable = array(
103 'Participant' => 'civicrm_participant_payment',
17ea44da 104 'Contribution' => 'civicrm_contribution',
15ed8da7
PN
105 'Membership' => 'civicrm_membership',
106 );
0cc5fafb 107
15ed8da7
PN
108 foreach ($entityTable as $label => $tableName) {
109 list($minId, $maxId) = CRM_Core_DAO::executeQuery("SELECT coalesce(min(id),0), coalesce(max(id),0)
110 FROM {$tableName}")->getDatabaseResult()->fetchRow();
111 for ($startId = $minId; $startId <= $maxId; $startId += self::BATCH_SIZE) {
112 $endId = $startId + self::BATCH_SIZE - 1;
353ffa53
TO
113 $title = ts("Upgrade DB to 4.5.beta9: Fix line items for {$label} (%1 => %2)", array(
114 1 => $startId,
af9b09df 115 2 => $endId,
353ffa53 116 ));
15ed8da7 117 $this->addTask($title, 'task_4_5_0_fixLineItem', $startId, $endId, $label);
0cc5fafb 118 }
119 }
f49da658
PN
120 return TRUE;
121 }
122
123 /**
124 * (Queue Task Callback)
125 *
c490a46a 126 * update the line items
0cc5fafb 127 *
f49da658
PN
128 *
129 * @param CRM_Queue_TaskContext $ctx
5a4f6742
CW
130 * @param int $startId
131 * the first/lowest entity ID to convert.
132 * @param int $endId
133 * the last/highest entity ID to convert.
0cc5fafb 134 * @param
f49da658
PN
135 *
136 * @return bool
137 */
00be9182 138 public static function task_4_5_0_fixLineItem(CRM_Queue_TaskContext $ctx, $startId, $endId, $entityTable) {
0cc5fafb 139
f49da658
PN
140 $sqlParams = array(
141 1 => array($startId, 'Integer'),
142 2 => array($endId, 'Integer'),
143 );
144 switch ($entityTable) {
0cc5fafb 145 case 'Contribution':
f49da658 146 // update all the line item entity_table and entity_id with contribution due to bug CRM-15055
17ea44da
PN
147 CRM_Core_DAO::executeQuery("UPDATE civicrm_line_item li
148 INNER JOIN civicrm_contribution cc ON cc.id = li.contribution_id
149 SET entity_id = li.contribution_id, entity_table = 'civicrm_contribution'
150 WHERE li.contribution_id IS NOT NULL AND li.entity_table <> 'civicrm_participant' AND (cc.id BETWEEN %1 AND %2)", $sqlParams);
0cc5fafb 151
f49da658 152 // update the civicrm_line_item.contribution_id
17ea44da 153 CRM_Core_DAO::executeQuery("UPDATE civicrm_line_item li
0cc5fafb 154 INNER JOIN civicrm_contribution cc ON cc.id = li.entity_id
f49da658 155 SET contribution_id = entity_id
0cc5fafb 156 WHERE li.contribution_id IS NULL AND li.entity_table = 'civicrm_contribution' AND (cc.id BETWEEN %1 AND %2)", $sqlParams);
f49da658 157 break;
0cc5fafb 158
15ed8da7 159 case 'Participant':
f49da658 160 // update the civicrm_line_item.contribution_id
0cc5fafb 161 CRM_Core_DAO::executeQuery("UPDATE civicrm_line_item li
f49da658
PN
162 INNER JOIN civicrm_participant_payment pp ON pp.participant_id = li.entity_id
163 SET li.contribution_id = pp.contribution_id
17ea44da 164 WHERE li.entity_table = 'civicrm_participant' AND li.contribution_id IS NULL AND (pp.id BETWEEN %1 AND %2)", $sqlParams);
f49da658 165 break;
0cc5fafb 166
15ed8da7 167 case 'Membership':
f49da658
PN
168 $upgrade = new CRM_Upgrade_Form();
169 // update the line item of membership
170 CRM_Core_DAO::executeQuery("UPDATE civicrm_line_item li
171 INNER JOIN civicrm_membership_payment mp ON mp.contribution_id = li.contribution_id
172 INNER JOIN civicrm_membership cm ON mp.membership_id = cm.id
173 INNER JOIN civicrm_price_field_value pv ON pv.id = li.price_field_value_id
174 SET li.entity_table = 'civicrm_membership', li.entity_id = mp.membership_id
175 WHERE li.entity_table = 'civicrm_contribution'
17ea44da 176 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 177
f49da658
PN
178 CRM_Core_DAO::executeQuery("UPDATE civicrm_line_item li
179 INNER JOIN civicrm_membership_payment mp ON mp.contribution_id = li.contribution_id
180 INNER JOIN civicrm_price_field_value pv ON pv.id = li.price_field_value_id
181 SET li.entity_table = 'civicrm_membership', li.entity_id = mp.membership_id
182 WHERE li.entity_table = 'civicrm_contribution'
17ea44da 183 AND pv.membership_type_id IS NOT NULL AND (mp.membership_id BETWEEN %1 AND %2)", $sqlParams);
0cc5fafb 184
17ea44da 185 CRM_Core_DAO::executeQuery("INSERT INTO civicrm_line_item (entity_table, entity_id, price_field_id, label,
f49da658 186 qty, unit_price, line_total, price_field_value_id, financial_type_id)
0cc5fafb 187 SELECT 'civicrm_membership', cm.id, cpf.id price_field_id, cpfv.label, 1 as qty, cpfv.amount, cpfv.amount line_total,
f49da658
PN
188 cpfv.id price_field_value_id, cpfv.financial_type_id FROM civicrm_membership cm
189 LEFT JOIN civicrm_membership_payment cmp ON cmp.membership_id = cm.id
17ea44da
PN
190 INNER JOIN civicrm_price_field_value cpfv ON cpfv.membership_type_id = cm.membership_type_id
191 INNER JOIN civicrm_price_field cpf ON cpf.id = cpfv.price_field_id
192 INNER JOIN civicrm_price_set cps ON cps.id = cpf.price_set_id
f49da658
PN
193 WHERE cmp.contribution_id IS NULL AND cps.name = 'default_membership_type_amount' AND (cm.id BETWEEN %1 AND %2)", $sqlParams);
194 break;
0cc5fafb 195 }
f49da658
PN
196 return TRUE;
197 }
198
8b49cb50
OB
199 /**
200 * Add defaults for the newly introduced name fields configuration in 'contact_edit_options' setting
201 *
d0f74b53
EM
202 * @param CRM_Queue_TaskContext $ctx
203 *
a6c01b45
CW
204 * @return bool
205 * TRUE for success
8b49cb50 206 */
00be9182 207 public static function addNameFieldOptions(CRM_Queue_TaskContext $ctx) {
8b49cb50
OB
208 $query = "SELECT `value` FROM `civicrm_setting` WHERE `group_name` = 'CiviCRM Preferences' AND `name` = 'contact_edit_options'";
209 $dao = CRM_Core_DAO::executeQuery($query);
210 $dao->fetch();
211 $oldValue = unserialize($dao->value);
212
213 $newValue = $oldValue . '12\ 114\ 115\ 116\ 117\ 1';
214
215 $query = "UPDATE `civicrm_setting` SET `value` = %1 WHERE `group_name` = 'CiviCRM Preferences' AND `name` = 'contact_edit_options'";
216 $params = array(1 => array(serialize($newValue), 'String'));
217 CRM_Core_DAO::executeQuery($query, $params);
218
296342b1
OB
219 return TRUE;
220 }
221
3182e644 222 /**
223 * Migrate honoree information to uf_join.module_data as honoree columns (text and title) will be dropped
224 * on DB upgrade
225 *
226 * @param CRM_Queue_TaskContext $ctx
227 *
a6c01b45
CW
228 * @return bool
229 * TRUE for success
3182e644 230 */
00be9182 231 public static function migrateHonoreeInfo(CRM_Queue_TaskContext $ctx) {
3182e644 232 $query = "ALTER TABLE `civicrm_uf_join`
233 ADD COLUMN `module_data` longtext COMMENT 'Json serialized array of data used by the ufjoin.module'";
e418776c 234 CRM_Core_DAO::executeQuery($query);
3182e644 235
236 $honorTypes = array_keys(CRM_Core_OptionGroup::values('honor_type'));
237 $ufGroupDAO = new CRM_Core_DAO_UFGroup();
238 $ufGroupDAO->name = 'new_individual';
239 $ufGroupDAO->find(TRUE);
240
241 $query = "SELECT * FROM civicrm_contribution_page";
242 $dao = CRM_Core_DAO::executeQuery($query);
243
244 if ($dao->N) {
2177d15c 245 $domain = new CRM_Core_DAO_Domain();
3182e644 246 $domain->find(TRUE);
247 while ($dao->fetch()) {
248 $honorParams = array('soft_credit' => array('soft_credit_types' => $honorTypes));
249 if ($domain->locales) {
250 $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);
251 foreach ($locales as $locale) {
e418776c
TO
252 $honor_block_title = "honor_block_title_{$locale}";
253 $honor_block_text = "honor_block_text_{$locale}";
3182e644 254 $honorParams['soft_credit'] += array(
255 $locale => array(
256 'honor_block_title' => $dao->$honor_block_title,
257 'honor_block_text' => $dao->$honor_block_text,
258 ),
259 );
260 }
261 }
262 else {
263 $honorParams['soft_credit'] += array(
264 'default' => array(
265 'honor_block_title' => $dao->honor_block_title,
266 'honor_block_text' => $dao->honor_block_text,
267 ),
268 );
269 }
270 $ufJoinParam = array(
271 'module' => 'soft_credit',
272 'entity_table' => 'civicrm_contribution_page',
273 'is_active' => $dao->honor_block_is_active,
274 'entity_id' => $dao->id,
275 'uf_group_id' => $ufGroupDAO->id,
276 'module_data' => json_encode($honorParams),
277 );
278 CRM_Core_BAO_UFJoin::create($ufJoinParam);
279 }
280 }
281
282 return TRUE;
283 }
284
bb606fef 285 /**
286 * Upgrade function.
287 *
288 * @param string $rev
bf6a5362 289 * @return bool
bb606fef 290 */
c50c7e9f 291 public function upgrade_4_5_9($rev) {
bb606fef 292 // Task to process sql.
b604d7ec 293 $this->addTask('Upgrade DB to 4.5.9: Fix saved searches consisting of multi-choice custom field(s)', 'updateSavedSearch');
bb606fef 294
295 return TRUE;
296 }
297
298 /**
299 * Update saved search for multi-select custom fields on DB upgrade
300 *
301 * @param CRM_Queue_TaskContext $ctx
302 *
303 * @return bool TRUE for success
304 */
6f22e282 305 public static function updateSavedSearch(CRM_Queue_TaskContext $ctx) {
bb606fef 306 $sql = "SELECT id, form_values FROM civicrm_saved_search";
307 $dao = CRM_Core_DAO::executeQuery($sql);
308 while ($dao->fetch()) {
00e0fd5e
JM
309 $copy = $formValues = unserialize($dao->form_values);
310 $update = FALSE;
311 foreach ($copy as $field => $data_value) {
6a4282e5 312 if (preg_match('/^custom_/', $field) && is_array($data_value) && !array_key_exists("${field}_operator", $formValues)) {
00e0fd5e
JM
313 // Now check for CiviCRM_OP_OR as either key or value in the data_value array.
314 // This is the conclusive evidence of an old-style data format.
6f22e282 315 if (array_key_exists('CiviCRM_OP_OR', $data_value) || FALSE !== array_search('CiviCRM_OP_OR', $data_value)) {
00e0fd5e
JM
316 // We have old style data. Mark this record to be updated.
317 $update = TRUE;
318 $op = 'and';
6f22e282 319 if (!preg_match('/^custom_([0-9]+)/', $field, $matches)) {
00e0fd5e
JM
320 // fatal error?
321 continue;
322 }
6f22e282 323 $fieldID = $matches[1];
00e0fd5e
JM
324 if (array_key_exists('CiviCRM_OP_OR', $data_value)) {
325 // This indicates data structure identified by jamie in the form:
326 // value1 => 1, value2 => , value3 => 1.
13322a1e 327 $data_value = array_keys($data_value, 1);
00e0fd5e
JM
328
329 // If CiviCRM_OP_OR - change OP from default to OR
6f22e282 330 if ($data_value['CiviCRM_OP_OR'] == 1) {
6a4282e5 331 $op = 'or';
6a4282e5 332 }
00e0fd5e
JM
333 unset($data_value['CiviCRM_OP_OR']);
334 }
335 else {
336 // The value is here, but it is not set as a key.
337 // This is using the style identified by Monish - the existence of the value
338 // indicates an OR search and values are set in the form of:
339 // 0 => value1, 1 => value1, 3 => value2.
6a4282e5 340 $key = array_search('CiviCRM_OP_OR', $data_value);
00e0fd5e
JM
341 $op = 'or';
342 unset($data_value[$key]);
09ffa0c1 343 }
13322a1e 344
345 //If only Or operator has been chosen, means we need to select all values and
346 //so to execute OR operation between these values according to new data structure
347 if (count($data_value) == 0 && $op == 'or') {
348 $customOption = CRM_Core_BAO_CustomOption::getCustomOption($fieldID);
349 foreach ($customOption as $option) {
350 $data_value[] = CRM_Utils_Array::value('value', $option);
351 }
352 }
353
00e0fd5e
JM
354 $formValues[$field] = $data_value;
355 $formValues["${field}_operator"] = $op;
09ffa0c1 356 }
bb606fef 357 }
358 }
bb606fef 359
13322a1e 360 if ($update) {
00e0fd5e
JM
361 $sql = "UPDATE civicrm_saved_search SET form_values = %0 WHERE id = %1";
362 CRM_Core_DAO::executeQuery($sql,
363 array(
364 array(serialize($formValues), 'String'),
365 array($dao->id, 'Integer'),
366 )
367 );
368 }
369 }
bb606fef 370 return TRUE;
371 }
372
296342b1 373}