CRM_Core_BAO_Setting - Don't prefill settings
[civicrm-core.git] / CRM / Upgrade / Incremental / php / FourFour.php
CommitLineData
a47a2f90 1<?php
2/*
3 +--------------------------------------------------------------------+
7e9e8871 4 | CiviCRM version 4.7 |
a47a2f90 5 +--------------------------------------------------------------------+
e7112fa7 6 | Copyright CiviCRM LLC (c) 2004-2015 |
a47a2f90 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. |
a47a2f90 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 |
a47a2f90 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 */
a47a2f90 27
28/**
bf6a5362 29 * Upgrade logic for 4.4
a47a2f90 30 */
bf6a5362 31class CRM_Upgrade_Incremental_php_FourFour extends CRM_Upgrade_Incremental_Base {
52592398
TO
32 const MAX_WORD_REPLACEMENT_SIZE = 255;
33
a47a2f90 34 /**
fe482240 35 * Compute any messages which should be displayed beforeupgrade.
a47a2f90 36 *
37 * Note: This function is called iteratively for each upcoming
38 * revision to the database.
39 *
d0f74b53 40 * @param $preUpgradeMessage
5a4f6742
CW
41 * @param string $rev
42 * a version number, e.g. '4.4.alpha1', '4.4.beta3', '4.4.0'.
d0f74b53
EM
43 * @param null $currentVer
44 *
a47a2f90 45 * @return void
46 */
00be9182 47 public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL) {
52592398
TO
48 if ($rev == '4.4.beta1') {
49 $apiCalls = self::getConfigArraysAsAPIParams(FALSE);
50 $oversizedEntries = 0;
51 foreach ($apiCalls as $params) {
52 if (!self::isValidWordReplacement($params)) {
53 $oversizedEntries++;
54 }
55 }
56 if ($oversizedEntries > 0) {
57 $preUpgradeMessage .= '<br/>' . ts("WARNING: There are %1 word-replacement entries which will not be valid in v4.4+ (eg with over 255 characters). They will be dropped during upgrade. For details, consult the CiviCRM log.", array(
353ffa53
TO
58 1 => $oversizedEntries,
59 ));
52592398
TO
60 }
61 }
a47a2f90 62 }
63
64 /**
fe482240 65 * Compute any messages which should be displayed after upgrade.
a47a2f90 66 *
5a4f6742
CW
67 * @param string $postUpgradeMessage
68 * alterable.
69 * @param string $rev
70 * an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs.
a47a2f90 71 * @return void
72 */
00be9182 73 public function setPostUpgradeMessage(&$postUpgradeMessage, $rev) {
61320313 74 if ($rev == '4.4.1') {
634e1a1a
DL
75 $config = CRM_Core_Config::singleton();
76 if (!empty($config->useIDS)) {
61320313 77 $postUpgradeMessage .= '<br />' . ts("The setting to skip IDS check has been removed. Your site has this configured in civicrm.settings.php but it will no longer work. Instead, use the new permission 'skip IDS check' to bypass the IDS system.");
634e1a1a
DL
78 }
79 }
9e58e6ff 80 if ($rev == '4.4.3') {
09163e8a 81 $postUpgradeMessage .= '<br /><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></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).');
9e58e6ff 82 }
1543f800
DG
83 if ($rev == '4.4.3') {
84 $query = "SELECT cft.id financial_trxn
85FROM civicrm_financial_trxn cft
86LEFT JOIN civicrm_entity_financial_trxn ceft ON ceft.financial_trxn_id = cft.id
87LEFT JOIN civicrm_contribution cc ON ceft.entity_id = cc.id
88WHERE ceft.entity_table = 'civicrm_contribution' AND cft.payment_instrument_id IS NULL;";
89 $dao = CRM_Core_DAO::executeQuery($query);
90 if ($dao->N) {
353ffa53
TO
91 $postUpgradeMessage .= '<br /><br /><strong>' . ts('Your database contains %1 financial transaction records with no payment instrument (Paid By is empty). If you use the Accounting Batches feature this may result in unbalanced transactions. If you do not use this feature, you can ignore the condition (although you will be required to select a Paid By value for new transactions). <a href="%2" target="_blank">You can review steps to correct transactions with missing payment instruments on the wiki.</a>', array(
92 1 => $dao->N,
bed98343 93 2 => 'http://wiki.civicrm.org/confluence/display/CRMDOC/Fixing+Transactions+Missing+a+Payment+Instrument+-+4.4.3+Upgrades',
353ffa53 94 )) . '</strong>';
1543f800
DG
95 }
96 }
9b873358 97 if ($rev == '4.4.6') {
86bfa4f6 98 $postUpgradeMessage .= '<br /><br /><strong>' . ts('Your contact image urls have been upgraded. If your contact image urls did not follow the standard format for image Urls they have not been upgraded. Please check the log to see image urls that were not upgraded.');
5da97e99 99 }
a47a2f90 100 }
101
624e56fa
EM
102 /**
103 * @param $rev
104 *
105 * @return bool
106 */
00be9182 107 public function upgrade_4_4_alpha1($rev) {
634e1a1a 108 // task to process sql
bf6a5362 109 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.4.alpha1')), 'runSql', $rev);
a47a2f90 110
111 // Consolidate activity contacts CRM-12274.
d1401e86 112 $this->addTask('Consolidate activity contacts', 'activityContacts');
a47a2f90 113
114 return TRUE;
115 }
116
624e56fa
EM
117 /**
118 * @param $rev
119 */
00be9182 120 public function upgrade_4_4_beta1($rev) {
bf6a5362 121 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.4.beta1')), 'runSql', $rev);
7ee2786a 122
56d4e0ab 123 // add new 'data' column in civicrm_batch
124 $query = 'ALTER TABLE civicrm_batch ADD data LONGTEXT NULL COMMENT "cache entered data"';
d427e40e 125 CRM_Core_DAO::executeQuery($query, array(), TRUE, NULL, FALSE, FALSE);
56d4e0ab 126
7ee2786a 127 // check if batch entry data exists in civicrm_cache table
f1811020 128 $query = 'SELECT path, data FROM civicrm_cache WHERE group_name = "batch entry"';
7ee2786a 129 $dao = CRM_Core_DAO::executeQuery($query);
130 while ($dao->fetch()) {
131 // get batch id $batchId[2]
132 $batchId = explode('-', $dao->path);
133 $data = unserialize($dao->data);
134
135 // move the data to civicrm_batch table
136 CRM_Core_DAO::setFieldValue('CRM_Batch_DAO_Batch', $batchId[2], 'data', json_encode(array('values' => $data)));
137 }
138
139 // delete entries from civicrm_cache table
f1811020 140 $query = 'DELETE FROM civicrm_cache WHERE group_name = "batch entry"';
7ee2786a 141 CRM_Core_DAO::executeQuery($query);
ba457d64 142
d1401e86 143 $this->addTask('Migrate custom word-replacements', 'wordReplacements');
7ee2786a 144 }
145
624e56fa
EM
146 /**
147 * @param $rev
148 */
00be9182 149 public function upgrade_4_4_1($rev) {
95c0a77c 150 $config = CRM_Core_Config::singleton();
6b12405a
RN
151 // CRM-13327 upgrade handling for the newly added name badges
152 $ogID = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', 'name_badge', 'id', 'name');
153 $nameBadges = array_flip(array_values(CRM_Core_BAO_OptionValue::getOptionValuesAssocArrayFromName('name_badge')));
154 unset($nameBadges['Avery 5395']);
155 if (!empty($nameBadges)) {
156 $dimension = '{"paper-size":"a4","orientation":"portrait","font-name":"times","font-size":6,"font-style":"","NX":2,"NY":4,"metric":"mm","lMargin":6,"tMargin":19,"SpaceX":0,"SpaceY":0,"width":100,"height":65,"lPadding":0,"tPadding":0}';
157 $query = "UPDATE civicrm_option_value
158 SET value = '{$dimension}'
159 WHERE option_group_id = %1 AND name = 'Fattorini Name Badge 100x65'";
160
161 CRM_Core_DAO::executeQuery($query, array(1 => array($ogID, 'Integer')));
162 }
163 else {
164 $dimensions = array(
165 1 => '{"paper-size":"a4","orientation":"landscape","font-name":"times","font-size":6,"font-style":"","NX":2,"NY":1,"metric":"mm","lMargin":25,"tMargin":27,"SpaceX":0,"SpaceY":35,"width":106,"height":150,"lPadding":5,"tPadding":5}',
166 2 => '{"paper-size":"a4","orientation":"portrait","font-name":"times","font-size":6,"font-style":"","NX":2,"NY":4,"metric":"mm","lMargin":6,"tMargin":19,"SpaceX":0,"SpaceY":0,"width":100,"height":65,"lPadding":0,"tPadding":0}',
167 3 => '{"paper-size":"a4","orientation":"portrait","font-name":"times","font-size":6,"font-style":"","NX":2,"NY":2,"metric":"mm","lMargin":10,"tMargin":28,"SpaceX":0,"SpaceY":0,"width":96,"height":121,"lPadding":5,"tPadding":5}',
168 );
169 $insertStatements = array(
170 1 => "($ogID, %1, '{$dimensions[1]}', %1, NULL, 0, NULL, 2, NULL, 0, 0, 1, NULL, NULL)",
171 2 => "($ogID, %2, '{$dimensions[2]}', %2, NULL, 0, NULL, 3, NULL, 0, 0, 1, NULL, NULL)",
172 3 => "($ogID, %3, '{$dimensions[3]}', %3, NULL, 0, NULL, 4, NULL, 0, 0, 1, NULL, NULL)",
173 );
174
175 $queryParams = array(
176 1 => array('A6 Badge Portrait 150x106', 'String'),
177 2 => array('Fattorini Name Badge 100x65', 'String'),
178 3 => array('Hanging Badge 3-3/4" x 4-3"/4', 'String'),
179 );
3a88e331 180
6b12405a
RN
181 foreach ($insertStatements as $values) {
182 $query = 'INSERT INTO civicrm_option_value (`option_group_id`, `label`, `value`, `name`, `grouping`, `filter`, `is_default`, `weight`, `description`, `is_optgroup`, `is_reserved`, `is_active`, `component_id`, `visibility_id`) VALUES' . $values;
183 CRM_Core_DAO::executeQuery($query, $queryParams);
184 }
185 }
186
95c0a77c
CW
187 // CRM-12578 - Prior to this version a CSS file under drupal would disable core css
188 if (!empty($config->customCSSURL) && strpos($config->userFramework, 'Drupal') === 0) {
189 // The new setting doesn't exist yet - need to create it first
76bd16ab
TO
190 Civi::service('settings_manager')->flush();
191 Civi::settings()->set('disable_core_css', 1);
95c0a77c
CW
192 }
193
fcab62b4
CW
194 // CRM-13701 - Fix $config->timeInputFormat
195 $sql = "
196 SELECT time_format
197 FROM civicrm_preferences_date
198 WHERE time_format IS NOT NULL
199 AND time_format <> ''
200 LIMIT 1
201 ";
202 $timeInputFormat = CRM_Core_DAO::singleValueQuery($sql);
203 if ($timeInputFormat && $timeInputFormat != $config->timeInputFormat) {
204 $params = array('timeInputFormat' => $timeInputFormat);
205 CRM_Core_BAO_ConfigSetting::add($params);
206 }
207
187e382a
PJ
208 // CRM-13698 - add 'Available' and 'No-show' activity statuses
209 $insertStatus = array();
210 $nsinc = $avinc = $inc = 0;
211 if (!CRM_Core_OptionGroup::getValue('activity_status', 'Available', 'name')) {
212 $insertStatus[] = "(%1, 'Available', %2, 'Available', NULL, 0, NULL, %3, 0, 0, 1, NULL, NULL)";
213 $avinc = $inc = 1;
214 }
5b8e40ab
CW
215 if (!CRM_Core_OptionGroup::getValue('activity_status', 'No_show', 'name')) {
216 $insertStatus[] = "(%1, 'No-show', %4, 'No_show', NULL, 0, NULL, %5, 0, 0, 1, NULL, NULL)";
187e382a
PJ
217 $nsinc = $inc + 1;
218 }
219 if (!empty($insertStatus)) {
220 $acOptionGroupID = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', 'activity_status', 'id', 'name');
221 $maxVal = CRM_Core_DAO::singleValueQuery("SELECT MAX(ROUND(op.value)) FROM civicrm_option_value op WHERE op.option_group_id = $acOptionGroupID");
222 $maxWeight = CRM_Core_DAO::singleValueQuery("SELECT MAX(weight) FROM civicrm_option_value WHERE option_group_id = $acOptionGroupID");
223
224 $p[1] = array($acOptionGroupID, 'Integer');
225 if ($avinc) {
e418776c
TO
226 $p[2] = array($avinc + $maxVal, 'Integer');
227 $p[3] = array($avinc + $maxWeight, 'Integer');
187e382a
PJ
228 }
229 if ($nsinc) {
e418776c
TO
230 $p[4] = array($nsinc + $maxVal, 'Integer');
231 $p[5] = array($nsinc + $maxWeight, 'Integer');
187e382a
PJ
232 }
233 $insertStatus = implode(',', $insertStatus);
234
235 $sql = "
236INSERT INTO
237 civicrm_option_value (`option_group_id`, label, `value`, `name`, `grouping`, `filter`, `is_default`, `weight`, `is_optgroup`, `is_reserved`, `is_active`, `component_id`, `visibility_id`)
238VALUES {$insertStatus}";
239 CRM_Core_DAO::executeQuery($sql, $p);
240 }
241
bf6a5362 242 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.4.1')), 'runSql', $rev);
44379fac 243 $this->addTask('Patch word-replacement schema', 'wordReplacements_patch', $rev);
6b12405a
RN
244 }
245
624e56fa
EM
246 /**
247 * @param $rev
248 *
249 * @return bool
250 */
00be9182 251 public function upgrade_4_4_4($rev) {
23e300df
PJ
252 $fkConstraint = array();
253 if (!CRM_Core_DAO::checkFKConstraintInFormat('civicrm_activity_contact', 'activity_id')) {
254 $fkConstraint[] = "ADD CONSTRAINT `FK_civicrm_activity_contact_activity_id` FOREIGN KEY (`activity_id`) REFERENCES `civicrm_activity` (`id`) ON DELETE CASCADE";
255 }
256 if (!CRM_Core_DAO::checkFKConstraintInFormat('civicrm_activity_contact', 'contact_id')) {
257 $fkConstraint[] = "ADD CONSTRAINT `FK_civicrm_activity_contact_contact_id` FOREIGN KEY (`contact_id`) REFERENCES `civicrm_contact` (`id`) ON DELETE CASCADE;
258";
259 }
260
261 if (!empty($fkConstraint)) {
262 $fkConstraint = implode(',', $fkConstraint);
263 $sql = "ALTER TABLE `civicrm_activity_contact`
264{$fkConstraint}
265";
266 // CRM-14036 : delete entries of un-mapped contacts
e418776c 267 CRM_Core_DAO::executeQuery("DELETE ac FROM civicrm_activity_contact ac
23e300df
PJ
268LEFT JOIN civicrm_contact c
269ON c.id = ac.contact_id
270WHERE c.id IS NULL;
271");
e418776c
TO
272 // delete entries of un-mapped activities
273 CRM_Core_DAO::executeQuery("DELETE ac FROM civicrm_activity_contact ac
23e300df
PJ
274LEFT JOIN civicrm_activity a
275ON a.id = ac.activity_id
276WHERE a.id IS NULL;
277");
278
279 CRM_Core_DAO::executeQuery("SET FOREIGN_KEY_CHECKS=0;");
280 CRM_Core_DAO::executeQuery($sql);
281 CRM_Core_DAO::executeQuery("SET FOREIGN_KEY_CHECKS=1;");
282 }
283
fa4916a4 284 // task to process sql
bf6a5362 285 $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => '4.4.4')), 'runSql', $rev);
fa4916a4 286
7bfaef22 287 // CRM-13892 : add `name` column to dashboard schema
fa4916a4 288 $query = "
289ALTER TABLE civicrm_dashboard
290 ADD name varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Internal name of dashlet.' AFTER domain_id ";
9359d28c 291 CRM_Core_DAO::executeQuery($query, array(), TRUE, NULL, FALSE, FALSE);
fa4916a4 292
293 $dashboard = new CRM_Core_DAO_Dashboard();
294 $dashboard->find();
295 while ($dashboard->fetch()) {
296 $urlElements = explode('/', $dashboard->url);
297 if ($urlElements[1] == 'dashlet') {
298 $url = explode('&', $urlElements[2]);
299 $name = $url[0];
300 }
301 elseif ($urlElements[1] == 'report') {
302 $url = explode('&', $urlElements[3]);
86bfa4f6 303 $name = 'report/' . $url[0];
fa4916a4 304 }
305 $values .= "
306 WHEN {$dashboard->id} THEN '{$name}'
307 ";
308 }
309
310 $query = "
311 UPDATE civicrm_dashboard
312 SET name = CASE id
313 {$values}
314 END;
315 ";
9359d28c 316 CRM_Core_DAO::executeQuery($query, array(), TRUE, NULL, FALSE, FALSE);
d0f74b53 317
52df1bbd
DG
318 // CRM-13998 : missing alter statements for civicrm_report_instance
319 $this->addTask(ts('Confirm civicrm_report_instance sql table for upgrades'), 'updateReportInstanceTable');
320
f15ec728 321 return TRUE;
fa4916a4 322 }
323
624e56fa
EM
324 /**
325 * @param $rev
326 */
9b873358 327 public function upgrade_4_4_6($rev) {
92fcb95f 328 $sql = "SELECT count(*) AS count FROM INFORMATION_SCHEMA.STATISTICS where " .
92fae7a2 329 "TABLE_SCHEMA = database() AND INDEX_NAME = 'index_image_url' AND TABLE_NAME = 'civicrm_contact';";
e71693e1
JM
330 $dao = CRM_Core_DAO::executeQuery($sql);
331 $dao->fetch();
4014394e 332 if ($dao->count < 1) {
e71693e1
JM
333 $sql = "CREATE INDEX index_image_url ON civicrm_contact (image_url);";
334 $dao = CRM_Core_DAO::executeQuery($sql);
335 }
336 $minId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(min(id),0) FROM civicrm_contact WHERE image_URL IS NOT NULL');
337 $maxId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(max(id),0) FROM civicrm_contact WHERE image_URL IS NOT NULL');
5da97e99
M
338 for ($startId = $minId; $startId <= $maxId; $startId += self::BATCH_SIZE) {
339 $endId = $startId + self::BATCH_SIZE - 1;
340 $title = ts('Upgrade image_urls (%1 => %2)', array(1 => $startId, 2 => $endId));
341 $this->addTask($title, 'upgradeImageUrls', $startId, $endId);
342 }
343 }
344
624e56fa 345 /**
bed98343 346 * @param $rev
347 * @param $originalVer
348 * @param $latestVer
624e56fa 349 *
bed98343 350 * @return void
624e56fa 351 */
00be9182 352 public function upgrade_4_4_7($rev, $originalVer, $latestVer) {
0e19dab5
TO
353 // For WordPress/Joomla(?), cleanup broken image_URL from 4.4.6 upgrades - https://issues.civicrm.org/jira/browse/CRM-14971
354 $exBackendUrl = CRM_Utils_System::url('civicrm/contact/imagefile', 'photo=XXX', TRUE); // URL formula from 4.4.6 upgrade
355 $exFrontendUrl = CRM_Utils_System::url('civicrm/contact/imagefile', 'photo=XXX', TRUE, NULL, TRUE, TRUE);
356 if ($originalVer == '4.4.6' && $exBackendUrl != $exFrontendUrl) {
357 $minId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(min(id),0) FROM civicrm_contact WHERE image_URL IS NOT NULL');
358 $maxId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(max(id),0) FROM civicrm_contact WHERE image_URL IS NOT NULL');
359 for ($startId = $minId; $startId <= $maxId; $startId += self::BATCH_SIZE) {
360 $endId = $startId + self::BATCH_SIZE - 1;
361 $title = ts('Upgrade image_urls (%1 => %2)', array(1 => $startId, 2 => $endId));
362 $this->addTask($title, 'cleanupBackendImageUrls', $startId, $endId);
363 }
364 }
97f4ef9c 365 $this->addTask(ts('Update saved search information'), 'changeSavedSearch');
0e19dab5
TO
366 }
367
b896fa44
EM
368 /**
369 * Upgrade image URLs.
370 *
371 * @param \CRM_Queue_TaskContext $ctx
372 * @param $startId
373 * @param $endId
374 *
375 * @return bool
376 */
9b873358 377 public static function upgradeImageUrls(CRM_Queue_TaskContext $ctx, $startId, $endId) {
0e19dab5 378 $dao = self::findContactImageUrls($startId, $endId);
5da97e99 379 $failures = array();
db233aa7 380 $config = CRM_Core_Config::singleton();
9b873358 381 while ($dao->fetch()) {
5da97e99
M
382 $imageURL = $dao->image_url;
383 $baseurl = CIVICRM_UF_BASEURL;
50afd725 384 //CRM-15897 - gross hack for joomla to remove the administrator/
db233aa7 385 if ($config->userFramework == 'Joomla') {
386 $baseurl = str_replace("/administrator/", "/", $baseurl);
387 }
5da97e99 388 $baselen = strlen($baseurl);
9b873358 389 if (substr($imageURL, 0, $baselen) == $baseurl) {
94fbf0d0 390 $photo = basename($dao->image_url);
92fcb95f 391 $fullpath = $config->customFileUploadDir . $photo;
9b873358 392 if (file_exists($fullpath)) {
e418776c
TO
393 // For anyone who upgraded 4.4.6 release (eg 4.4.0=>4.4.6), the $newImageUrl incorrectly used backend URLs.
394 // For anyone who skipped 4.4.6 (eg 4.4.0=>4.4.7), the $newImageUrl correctly uses frontend URLs
395 self::setContactImageUrl($dao->id,
353ffa53 396 CRM_Utils_System::url('civicrm/contact/imagefile', 'photo=' . $photo, TRUE, NULL, TRUE, TRUE));
5da97e99 397 }
92e4c2a5 398 else {
e418776c 399 $failures[$dao->id] = $dao->image_url;
94fbf0d0 400 }
5da97e99 401 }
92e4c2a5 402 else {
e418776c
TO
403 $failures[$dao->id] = $dao->image_url;
404 }
405 }
5da97e99
M
406 CRM_Core_Error::debug_var('imageUrlsNotUpgraded', $failures);
407 return TRUE;
408 }
409
b896fa44
EM
410 /**
411 * Change saved search.
412 *
413 * @param \CRM_Queue_TaskContext $ctx
414 *
415 * @return bool
416 */
00be9182 417 public static function changeSavedSearch(CRM_Queue_TaskContext $ctx) {
97f4ef9c 418 $membershipStatuses = array_flip(CRM_Member_PseudoConstant::membershipStatus());
419
420 $dao = new CRM_Contact_DAO_SavedSearch();
421 $dao->find();
422 while ($dao->fetch()) {
423 $formValues = CRM_Contact_BAO_SavedSearch::getFormValues($dao->id);
424 if (!empty($formValues['mapper'])) {
425 foreach ($formValues['mapper'] as $key => $value) {
426 foreach ($value as $k => $v) {
427 if ($v[0] == 'Membership' && in_array($v[1], array('membership_status', 'membership_status_id'))) {
428 $value = $formValues['value'][$key][$k];
429 $op = $formValues['operator'][$key][$k];
430 if ($op == 'IN') {
431 $value = trim($value);
432 $value = str_replace('(', '', $value);
433 $value = str_replace(')', '', $value);
434
435 $v = explode(',', $value);
436 $value = array();
437 foreach ($v as $k1 => $v2) {
438 if (is_numeric($v2)) {
439 break 2;
440 }
441 $value[$k1] = $membershipStatuses[$v2];
442 }
443 $formValues['value'][$key][$k] = "(" . implode(',', $value) . ")";
444 }
445 elseif (in_array($op, array('=', '!='))) {
446 if (is_numeric($value)) {
447 break;
448 }
449 $formValues['value'][$key][$k] = $membershipStatuses[$value];
450 }
451 }
452 }
453 }
454 $dao->form_values = serialize($formValues);
455 $dao->save();
456 }
457 }
458
459 return TRUE;
460 }
461
0e19dab5
TO
462 /**
463 * For WordPress/Joomla(?) sites which upgraded to 4.4.6, find back-end image_URLs
464 * (e.g. "http://example.com/wp-admin/admin.php?page=CiviCRM&amp;q=civicrm/contact/imagefile&amp;photo=123.jpg")
465 * and convert them to front-end URLs
466 * (e.g. "http://example.com/?page=CiviCRM&amp;q=civicrm/contact/imagefile&amp;photo=123.jpg").
467 *
468 * @param CRM_Queue_TaskContext $ctx
100fef9d
CW
469 * @param int $startId
470 * @param int $endId
0e19dab5
TO
471 * @return bool
472 */
00be9182 473 public static function cleanupBackendImageUrls(CRM_Queue_TaskContext $ctx, $startId, $endId) {
0e19dab5
TO
474 $dao = self::findContactImageUrls($startId, $endId);
475 while ($dao->fetch()) {
476 $imageUrl = str_replace('&amp;', '&', $dao->image_url);
477 if (preg_match(":civicrm/contact/imagefile.*photo=:", $imageUrl)) {
478 // looks like one of ours
479 $imageUrlParts = parse_url($imageUrl);
480 parse_str($imageUrlParts['query'], $imageUrlQuery);
481 self::setContactImageUrl($dao->id,
92fcb95f 482 CRM_Utils_System::url('civicrm/contact/imagefile', 'photo=' . $imageUrlQuery['photo'], TRUE, NULL, TRUE, TRUE));
0e19dab5
TO
483 }
484 }
485 return TRUE;
486 }
487
488 /**
489 * @param int $startId
490 * @param int $endId
16b10e64
CW
491 * @return CRM_Core_DAO
492 * columns include "id" and "image_URL"
0e19dab5
TO
493 */
494 public static function findContactImageUrls($startId, $endId) {
495 $sql = "
496SELECT id, image_url
497FROM civicrm_contact
498WHERE 1
499AND id BETWEEN %1 AND %2
500AND image_URL IS NOT NULL
501";
502
503 $params = array(
504 1 => array($startId, 'Integer'),
505 2 => array($endId, 'Integer'),
506 );
507 $dao = CRM_Core_DAO::executeQuery($sql, $params, TRUE, NULL, FALSE, FALSE);
508 return $dao;
509 }
510
511 /**
512 * @param int $cid
513 * @param string $newImageUrl
514 */
515 public static function setContactImageUrl($cid, $newImageUrl) {
516 $sql = 'UPDATE civicrm_contact SET image_url=%1 WHERE id=%2';
517 $params = array(
518 1 => array($newImageUrl, 'String'),
519 2 => array($cid, 'Integer'),
520 );
521 $updatedao = CRM_Core_DAO::executeQuery($sql, $params);
522 }
523
a47a2f90 524 /**
525 * Update activity contacts CRM-12274
526 *
77b97be7
EM
527 * @param CRM_Queue_TaskContext $ctx
528 *
a6c01b45
CW
529 * @return bool
530 * TRUE for success
a47a2f90 531 */
00be9182 532 public static function activityContacts(CRM_Queue_TaskContext $ctx) {
a47a2f90 533 $upgrade = new CRM_Upgrade_Form();
127ca309 534
e7e657f0 535 $activityContacts = CRM_Core_OptionGroup::values('activity_contacts', FALSE, FALSE, FALSE, NULL, 'name');
b95507ab 536 $ovValue[] = $sourceID = CRM_Utils_Array::key('Activity Source', $activityContacts);
537 $ovValue[] = $assigneeID = CRM_Utils_Array::key('Activity Assignees', $activityContacts);
538 $ovValue[] = $targetID = CRM_Utils_Array::key('Activity Targets', $activityContacts);
634e1a1a 539
9744c42c 540 $optionGroupID = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', 'activity_contacts', 'id', 'name');
b95507ab 541 if (!empty($ovValue)) {
542 $ovValues = implode(', ', $ovValue);
543 $query = "
634e1a1a 544UPDATE civicrm_option_value
b95507ab 545SET is_reserved = 1
546WHERE option_group_id = {$optionGroupID} AND value IN ($ovValues)";
547
548 $dao = CRM_Core_DAO::executeQuery($query);
549 }
550
9744c42c 551 if (!$assigneeID) {
b95507ab 552 $assigneeID = 1;
9744c42c 553 $value[] = "({$optionGroupID}, 'Activity Assignees', 1, 'Activity Assignees', 1, 1, 1)";
554 }
555 if (!$sourceID) {
b95507ab 556 $sourceID = 2;
9744c42c 557 $value[] = "({$optionGroupID}, 'Activity Source', 2, 'Activity Source', 2, 1, 1)";
558 }
559 if (!$targetID) {
b95507ab 560 $targetID = 3;
9744c42c 561 $value[] = "({$optionGroupID}, 'Activity Targets', 3, 'Activity Targets', 3, 1, 1)";
562 }
563
481a74f4 564 if (!$assigneeID || !$sourceID || !$targetID) {
e418776c 565 $insert = "
9744c42c 566INSERT INTO civicrm_option_value
567(option_group_id, label, value, name, weight, is_reserved, is_active)
568VALUES
569
570";
571 $values = implode(', ', $value);
572 $query = $insert . $values;
573 $dao = CRM_Core_DAO::executeQuery($query);
574 }
575
3a88e331
DL
576 // sometimes an user does not make a clean backup and the above table
577 // already exists, so lets delete this table - CRM-13665
187e382a 578 $query = "DROP TABLE IF EXISTS civicrm_activity_contact";
3a88e331 579 $dao = CRM_Core_DAO::executeQuery($query);
9744c42c 580
a47a2f90 581 $query = "
127ca309 582CREATE TABLE IF NOT EXISTS civicrm_activity_contact (
583 id int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Activity contact id',
584 activity_id int(10) unsigned NOT NULL COMMENT 'Foreign key to the activity for this record.',
585 contact_id int(10) unsigned NOT NULL COMMENT 'Foreign key to the contact for this record.',
586 record_type_id int(10) unsigned DEFAULT NULL COMMENT 'The record type id for this row',
587 PRIMARY KEY (id),
588 UNIQUE KEY UI_activity_contact (contact_id,activity_id,record_type_id),
589 KEY FK_civicrm_activity_contact_activity_id (activity_id)
a47a2f90 590) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
591";
592
593 $dao = CRM_Core_DAO::executeQuery($query);
634e1a1a
DL
594
595 $query = "
127ca309 596INSERT INTO civicrm_activity_contact (activity_id, contact_id, record_type_id)
597SELECT activity_id, target_contact_id, {$targetID} as record_type_id
a47a2f90 598FROM civicrm_activity_target";
599
600 $dao = CRM_Core_DAO::executeQuery($query);
601
634e1a1a 602 $query = "
127ca309 603INSERT INTO civicrm_activity_contact (activity_id, contact_id, record_type_id)
604SELECT activity_id, assignee_contact_id, {$assigneeID} as record_type_id
a47a2f90 605FROM civicrm_activity_assignment";
606 $dao = CRM_Core_DAO::executeQuery($query);
634e1a1a 607
a47a2f90 608 $query = "
127ca309 609 INSERT INTO civicrm_activity_contact (activity_id, contact_id, record_type_id)
610SELECT id, source_contact_id, {$sourceID} as record_type_id
634e1a1a 611FROM civicrm_activity
a47a2f90 612WHERE source_contact_id IS NOT NULL";
613
614 $dao = CRM_Core_DAO::executeQuery($query);
615
e418776c
TO
616 $query = "DROP TABLE civicrm_activity_target";
617 $dao = CRM_Core_DAO::executeQuery($query);
a47a2f90 618
e418776c
TO
619 $query = "DROP TABLE civicrm_activity_assignment";
620 $dao = CRM_Core_DAO::executeQuery($query);
a47a2f90 621
e418776c 622 $query = "ALTER TABLE civicrm_activity
a47a2f90 623 DROP FOREIGN KEY FK_civicrm_activity_source_contact_id";
634e1a1a 624
e418776c 625 $dao = CRM_Core_DAO::executeQuery($query);
a47a2f90 626
e418776c
TO
627 $query = "ALTER TABLE civicrm_activity DROP COLUMN source_contact_id";
628 $dao = CRM_Core_DAO::executeQuery($query);
a47a2f90 629
e418776c 630 return TRUE;
ba457d64
TO
631 }
632
633 /**
634 * Migrate word-replacements from $config to civicrm_word_replacement
635 *
d0f74b53
EM
636 * @param CRM_Queue_TaskContext $ctx
637 *
a6c01b45
CW
638 * @return bool
639 * TRUE for success
ba457d64
TO
640 * @see http://issues.civicrm.org/jira/browse/CRM-13187
641 */
00be9182 642 public static function wordReplacements(CRM_Queue_TaskContext $ctx) {
ba457d64 643 $query = "
7c312eca
TO
644CREATE TABLE IF NOT EXISTS `civicrm_word_replacement` (
645 `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Word replacement ID',
02ffc0f2
TO
646 `find_word` varchar(255) COLLATE utf8_bin COMMENT 'Word which need to be replaced',
647 `replace_word` varchar(255) COLLATE utf8_bin COMMENT 'Word which will replace the word in find',
7c312eca
TO
648 `is_active` tinyint COMMENT 'Is this entry active?',
649 `match_type` enum('wildcardMatch', 'exactMatch') DEFAULT 'wildcardMatch',
650 `domain_id` int unsigned COMMENT 'FK to Domain ID. This is for Domain specific word replacement',
651 PRIMARY KEY ( `id` ),
44379fac 652 UNIQUE INDEX `UI_domain_find` (domain_id, find_word),
7c312eca
TO
653 CONSTRAINT FK_civicrm_word_replacement_domain_id FOREIGN KEY (`domain_id`) REFERENCES `civicrm_domain`(`id`)
654) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
655 ";
ba457d64
TO
656 $dao = CRM_Core_DAO::executeQuery($query);
657
daa14c0c 658 self::rebuildWordReplacementTable();
ba457d64 659 return TRUE;
a47a2f90 660 }
661
44379fac
TO
662 /**
663 * Fix misconfigured constraints created in 4.4.0. To distinguish the good
664 * and bad configurations, we change the constraint name from "UI_find"
665 * (the original name in 4.4.0) to "UI_domain_find" (the new name in
666 * 4.4.1).
667 *
d0f74b53
EM
668 * @param CRM_Queue_TaskContext $ctx
669 * @param $rev
670 *
a6c01b45
CW
671 * @return bool
672 * TRUE for success
44379fac
TO
673 * @see http://issues.civicrm.org/jira/browse/CRM-13655
674 */
00be9182 675 public static function wordReplacements_patch(CRM_Queue_TaskContext $ctx, $rev) {
44379fac
TO
676 if (CRM_Core_DAO::checkConstraintExists('civicrm_word_replacement', 'UI_find')) {
677 CRM_Core_DAO::executeQuery("ALTER TABLE civicrm_word_replacement DROP FOREIGN KEY FK_civicrm_word_replacement_domain_id;");
678 CRM_Core_DAO::executeQuery("ALTER TABLE civicrm_word_replacement DROP KEY FK_civicrm_word_replacement_domain_id;");
679 CRM_Core_DAO::executeQuery("ALTER TABLE civicrm_word_replacement DROP KEY UI_find;");
680 CRM_Core_DAO::executeQuery("ALTER TABLE civicrm_word_replacement MODIFY COLUMN `find_word` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'Word which need to be replaced';");
681 CRM_Core_DAO::executeQuery("ALTER TABLE civicrm_word_replacement MODIFY COLUMN `replace_word` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'Word which will replace the word in find';");
682 CRM_Core_DAO::executeQuery("ALTER TABLE civicrm_word_replacement ADD CONSTRAINT UI_domain_find UNIQUE KEY `UI_domain_find` (`domain_id`,`find_word`);");
683 CRM_Core_DAO::executeQuery("ALTER TABLE civicrm_word_replacement ADD CONSTRAINT FK_civicrm_word_replacement_domain_id FOREIGN KEY (`domain_id`) REFERENCES `civicrm_domain` (`id`);");
684 }
685 return TRUE;
686 }
687
a47a2f90 688 /**
689 * Syntatic sugar for adding a task which (a) is in this class and (b) has
690 * a high priority.
691 *
692 * After passing the $funcName, you can also pass parameters that will go to
693 * the function. Note that all params must be serializable.
694 */
695 protected function addTask($title, $funcName) {
696 $queue = CRM_Queue_Service::singleton()->load(array(
697 'type' => 'Sql',
698 'name' => CRM_Upgrade_Form::QUEUE_NAME,
699 ));
700
701 $args = func_get_args();
702 $title = array_shift($args);
703 $funcName = array_shift($args);
704 $task = new CRM_Queue_Task(
705 array(get_class($this), $funcName),
706 $args,
707 $title
708 );
709 $queue->createItem($task, array('weight' => -1));
710 }
cbe56ea6
TO
711
712 /**
daa14c0c
TO
713 * Get all the word-replacements stored in config-arrays
714 * and convert them to params for the WordReplacement.create API.
715 *
0f65e834
TO
716 * Note: This function is duplicated in CRM_Core_BAO_WordReplacement and
717 * CRM_Upgrade_Incremental_php_FourFour to ensure that the incremental upgrade
718 * step behaves consistently even as the BAO evolves in future versions.
719 * However, if there's a bug in here prior to 4.4.0, we should apply the
720 * bugfix in both places.
721 *
c68f8bfa
TO
722 * @param bool $rebuildEach
723 * Whether to perform rebuild after each individual API call.
a6c01b45
CW
724 * @return array
725 * Each item is $params for WordReplacement.create
daa14c0c 726 * @see CRM_Core_BAO_WordReplacement::convertConfigArraysToAPIParams
cbe56ea6 727 */
00be9182 728 public static function getConfigArraysAsAPIParams($rebuildEach) {
cbe56ea6 729 $wordReplacementCreateParams = array();
cbe56ea6 730 // get all domains
daa14c0c
TO
731 $result = civicrm_api3('domain', 'get', array(
732 'return' => array('locale_custom_strings'),
733 ));
cbe56ea6
TO
734 if (!empty($result["values"])) {
735 foreach ($result["values"] as $value) {
736 $params = array();
cbe56ea6 737 $params["domain_id"] = $value["id"];
63b71ea8 738 $params["options"] = array('wp-rebuild' => $rebuildEach);
cbe56ea6 739 // unserialize word match string
8f3ccaf0
DG
740 $localeCustomArray = array();
741 if (!empty($value["locale_custom_strings"])) {
742 $localeCustomArray = unserialize($value["locale_custom_strings"]);
743 }
cbe56ea6
TO
744 if (!empty($localeCustomArray)) {
745 $wordMatchArray = array();
7c312eca 746 // Traverse Language array
cbe56ea6 747 foreach ($localeCustomArray as $localCustomData) {
7c312eca
TO
748 // Traverse status array "enabled" "disabled"
749 foreach ($localCustomData as $status => $matchTypes) {
e418776c 750 $params["is_active"] = ($status == "enabled") ? TRUE : FALSE;
7c312eca
TO
751 // Traverse Match Type array "wildcardMatch" "exactMatch"
752 foreach ($matchTypes as $matchType => $words) {
753 $params["match_type"] = $matchType;
754 foreach ($words as $word => $replace) {
755 $params["find_word"] = $word;
756 $params["replace_word"] = $replace;
757 $wordReplacementCreateParams[] = $params;
758 }
759 }
cbe56ea6
TO
760 }
761 }
762 }
763 }
764 }
765 return $wordReplacementCreateParams;
8d57c529 766 }
ba457d64 767
daa14c0c
TO
768 /**
769 * Get all the word-replacements stored in config-arrays
770 * and write them out as records in civicrm_word_replacement.
0f65e834
TO
771 *
772 * Note: This function is duplicated in CRM_Core_BAO_WordReplacement and
773 * CRM_Upgrade_Incremental_php_FourFour to ensure that the incremental upgrade
774 * step behaves consistently even as the BAO evolves in future versions.
775 * However, if there's a bug in here prior to 4.4.0, we should apply the
776 * bugfix in both places.
daa14c0c
TO
777 */
778 public static function rebuildWordReplacementTable() {
779 civicrm_api3('word_replacement', 'replace', array(
780 'options' => array('match' => array('domain_id', 'find_word')),
52592398 781 'values' => array_filter(self::getConfigArraysAsAPIParams(FALSE), array(__CLASS__, 'isValidWordReplacement')),
daa14c0c
TO
782 ));
783 CRM_Core_BAO_WordReplacement::rebuild();
ba457d64 784 }
52df1bbd 785
d0f74b53 786
bed98343 787 /**
52df1bbd 788 * CRM-13998 missing alter statements for civicrm_report_instance
bed98343 789 */
52df1bbd
DG
790 public function updateReportInstanceTable() {
791
d0f74b53 792 // add civicrm_report_instance.name
52df1bbd
DG
793
794 $sql = "SELECT count(*) FROM information_schema.columns "
353ffa53 795 . "WHERE table_schema = database() AND table_name = 'civicrm_report_instance' AND COLUMN_NAME = 'name' ";
52df1bbd
DG
796
797 $res = CRM_Core_DAO::singleValueQuery($sql);
798
481a74f4 799 if ($res <= 0) {
52df1bbd
DG
800 $sql = "ALTER TABLE civicrm_report_instance ADD `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'when combined with report_id/template uniquely identifies the instance'";
801 $res = CRM_Core_DAO::executeQuery($sql);
802 }
803
d0f74b53 804 // add civicrm_report_instance args
52df1bbd
DG
805
806 $sql = "SELECT count(*) FROM information_schema.columns WHERE table_schema = database() AND table_name = 'civicrm_report_instance' AND COLUMN_NAME = 'args' ";
807
808 $res = CRM_Core_DAO::singleValueQuery($sql);
809
481a74f4 810 if ($res <= 0) {
52df1bbd
DG
811 $sql = "ALTER TABLE civicrm_report_instance ADD `args` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'arguments that are passed in the url when invoking the instance'";
812
813 $res = CRM_Core_DAO::executeQuery($sql);
814 }
815
816 return TRUE;
817 }
52592398
TO
818
819 /**
820 * @param array $params
a6c01b45
CW
821 * @return bool
822 * TRUE if $params is valid
52592398 823 */
00be9182 824 public static function isValidWordReplacement($params) {
89b6dcf0 825 $result = strlen($params['find_word']) <= self::MAX_WORD_REPLACEMENT_SIZE && strlen($params['replace_word']) <= self::MAX_WORD_REPLACEMENT_SIZE;
52592398
TO
826 if (!$result) {
827 CRM_Core_Error::debug_var('invalidWordReplacement', $params);
828 }
829 return $result;
830 }
96025800 831
a47a2f90 832}