Commit | Line | Data |
---|---|---|
296342b1 OB |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
7e9e8871 | 4 | | CiviCRM version 4.7 | |
296342b1 | 5 | +--------------------------------------------------------------------+ |
e7112fa7 | 6 | | Copyright CiviCRM LLC (c) 2004-2015 | |
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 | 31 | class 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 |
3182e644 | 62 | $this->addTask(ts('Migrate honoree information to module_data'), 'migrateHonoreeInfo'); |
bf6a5362 | 63 | $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.5.alpha1')), 'runSql', $rev); |
8b49cb50 OB |
64 | $this->addTask(ts('Set default for Individual name fields configuration'), 'addNameFieldOptions'); |
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 = " | |
73 | SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS | |
74 | WHERE TABLE_NAME = 'civicrm_msg_template' | |
75 | AND CONSTRAINT_TYPE = 'FOREIGN KEY' | |
76 | AND 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` |
85 | DROP FOREIGN KEY `{$dao->CONSTRAINT_NAME}`, | |
86 | DROP 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. |
c50c7e9f | 293 | $this->addTask(ts('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 | } |