Merge pull request #4246 from crusonweb/CRM-15310
[civicrm-core.git] / CRM / Upgrade / Incremental / Legacy.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
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 and the CiviCRM Licensing Exception. |
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 and the CiviCRM Licensing Exception along |
21 | 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-2014
32 * $Id$
33 *
34 */
35
36 /**
37 * This class is a container for legacy upgrade logic which predates
38 * the current 'CRM/Incremental/php/*' structure.
39 */
40 class CRM_Upgrade_Incremental_Legacy {
41
42 /**
43 * Compute any messages which should be displayed before upgrade
44 *
45 * @param $preUpgradeMessage string, alterable
46 * @param $currentVer
47 * @param $latestVer
48 */
49 static function setPreUpgradeMessage(&$preUpgradeMessage, $currentVer, $latestVer) {
50 $upgrade = new CRM_Upgrade_Form();
51 $template = CRM_Core_Smarty::singleton();
52
53 if ((version_compare($currentVer, '3.3.alpha1') < 0 &&
54 version_compare($latestVer, '3.3.alpha1') >= 0
55 ) ||
56 (version_compare($currentVer, '3.4.alpha1') < 0 &&
57 version_compare($latestVer, '3.4.alpha1') >= 0
58 )
59 ) {
60 $query = "
61 SELECT id
62 FROM civicrm_mailing_job
63 WHERE status NOT IN ( 'Complete', 'Canceled' ) AND is_test = 0 LIMIT 1";
64 $mjId = CRM_Core_DAO::singleValueQuery($query);
65 if ($mjId) {
66 $preUpgradeMessage = ts("There are one or more Scheduled or In Progress mailings in your install. Scheduled mailings will not be sent and In Progress mailings will not finish if you continue with the upgrade. We strongly recommend that all Scheduled and In Progress mailings be completed or cancelled and then upgrade your CiviCRM install.");
67 }
68 }
69
70 //turning some tables to monolingual during 3.4.beta3, CRM-7869
71 $upgradeTo = str_replace('4.0.', '3.4.', $latestVer);
72 $upgradeFrom = str_replace('4.0.', '3.4.', $currentVer);
73
74 // check for changed message templates
75 self::checkMessageTemplate($template, $preUpgradeMessage, $upgradeTo, $upgradeFrom);
76
77 $upgrade = new CRM_Upgrade_Form();
78 if ($upgrade->multilingual &&
79 version_compare($upgradeFrom, '3.4.beta3') == -1 &&
80 version_compare($upgradeTo, '3.4.beta3') >= 0
81 ) {
82 $config = CRM_Core_Config::singleton();
83 $preUpgradeMessage .= '<br />' . ts("As per <a href='%1'>the related blog post</a>, we are making contact names, addresses and mailings monolingual; the values entered for the default locale (%2) will be preserved and values for other locales removed.", array(1 => 'http://civicrm.org/blogs/shot/multilingual-civicrm-3440-making-some-fields-monolingual', 2 => $config->lcMessages));
84 }
85
86 if (version_compare($currentVer, '3.4.6') == -1 &&
87 version_compare($latestVer, '3.4.6') >= 0
88 ) {
89 $googleProcessorExists = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_payment_processor WHERE payment_processor_type = 'Google_Checkout' AND is_active = 1 LIMIT 1;");
90
91 if ($googleProcessorExists) {
92 $preUpgradeMessage .= '<br />' . ts('To continue using Google Checkout Payment Processor with latest version of CiviCRM, requires updating merchant account settings. Please refer "Set API callback URL and other settings" section of <a href="%1" target="_blank"><strong>Google Checkout Configuration</strong></a> doc.', array(1 => 'http://wiki.civicrm.org/confluence/x/zAJTAg'));
93 }
94 }
95
96 // http://issues.civicrm.org/jira/browse/CRM-13572
97 // Depending on how the code was upgraded, some sites may still have copies of old
98 // source files left behind. This is often a forgivable offense, but it's quite
99 // dangerous for CIVI-SA-2013-001.
100 global $civicrm_root;
101 $ofcFile = "$civicrm_root/packages/OpenFlashChart/php-ofc-library/ofc_upload_image.php";
102 if (file_exists($ofcFile)) {
103 if (@unlink($ofcFile)) {
104 $preUpgradeMessage .= '<br />' . ts('This system included an outdated, insecure script (%1). The file was automatically deleted.', array(
105 1 => $ofcFile
106 ));
107 } else {
108 $preUpgradeMessage .= '<br />' . ts('This system includes an outdated, insecure script (%1). Please delete it.', array(
109 1 => $ofcFile
110 ));
111 }
112 }
113
114 if (CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SEARCH_PREFERENCES_NAME, 'enable_innodb_fts', NULL, FALSE)) {
115 // The FTS indexing feature dynamically manipulates the schema which could
116 // cause conflicts with other layers that manipulate the schema. The
117 // simplest thing is to turn it off and back on.
118
119 // It may not always be necessary to do this -- but I doubt we're going to test
120 // systematically in future releases. When it is necessary, one could probably
121 // ignore the matter and simply run CRM_Core_InnoDBIndexer::fixSchemaDifferences
122 // after the upgrade. But that's speculative. For now, we'll leave this
123 // advanced feature in the hands of the sysadmin.
124 $preUpgradeMessage .= '<br />' . ts('This database uses InnoDB Full Text Search for optimized searching. The upgrade procedure has not been tested with this feature. You should disable (and later re-enable) the feature by navigating to "Administer => System Settings => Miscellaneous".');
125 }
126 }
127
128 /**
129 * @param $template
130 * @param $message
131 * @param $latestVer
132 * @param $currentVer
133 */
134 static function checkMessageTemplate(&$template, &$message, $latestVer, $currentVer) {
135 if (version_compare($currentVer, '3.1.alpha1') < 0) {
136 return;
137 }
138
139 $sql = "SELECT orig.workflow_id as workflow_id,
140 orig.msg_title as title
141 FROM civicrm_msg_template diverted JOIN civicrm_msg_template orig ON (
142 diverted.workflow_id = orig.workflow_id AND
143 orig.is_reserved = 1 AND (
144 diverted.msg_subject != orig.msg_subject OR
145 diverted.msg_text != orig.msg_text OR
146 diverted.msg_html != orig.msg_html
147 )
148 )";
149
150 $dao = &CRM_Core_DAO::executeQuery($sql);
151 while ($dao->fetch()) {
152 $workflows[$dao->workflow_id] = $dao->title;
153 }
154
155 if (empty($workflows)) {
156 return;
157 }
158
159 $html = NULL;
160 $pathName = dirname(dirname(__FILE__));
161 $flag = FALSE;
162 foreach ($workflows as $workflow => $title) {
163 $name = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionValue',
164 $workflow,
165 'name',
166 'id'
167 );
168
169 // check if file exists locally
170 $textFileName = implode(DIRECTORY_SEPARATOR,
171 array(
172 $pathName,
173 "{$latestVer}.msg_template",
174 'message_templates',
175 "{$name}_text.tpl",
176 )
177 );
178
179 $htmlFileName = implode(DIRECTORY_SEPARATOR,
180 array(
181 $pathName,
182 "{$latestVer}.msg_template",
183 'message_templates',
184 "{$name}_html.tpl",
185 )
186 );
187
188 if (file_exists($textFileName) ||
189 file_exists($htmlFileName)
190 ) {
191 $flag = TRUE;
192 $html .= "<li>{$title}</li>";
193 }
194 }
195
196 if ($flag == TRUE) {
197 $html = "<ul>" . $html . "<ul>";
198
199 $message .= '<br />' . ts("The default copies of the message templates listed below will be updated to handle new features or correct a problem. Your installation has customized versions of these message templates, and you will need to apply the updates manually after running this upgrade. <a href='%1' style='color:white; text-decoration:underline; font-weight:bold;' target='_blank'>Click here</a> for detailed instructions. %2", array(1 => 'http://wiki.civicrm.org/confluence/display/CRMDOC/Message+Templates#MessageTemplates-UpgradesandCustomizedSystemWorkflowTemplates', 2 => $html));
200 }
201 }
202
203 /**
204 * Compute any messages which should be displayed after upgrade
205 *
206 * @param $postUpgradeMessage string, alterable
207 * @param $rev string, an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs
208 * @return void
209 */
210 static function setPostUpgradeMessage(&$postUpgradeMessage, $rev) {
211 if ($rev == '3.2.alpha1') {
212 $postUpgradeMessage .= '<br />' . ts("We have reset the COUNTED flag to false for the event participant status 'Pending from incomplete transaction'. This change ensures that people who have a problem during registration can try again.");
213 }
214 if ($rev == '3.2.beta3') {
215 $subTypes = CRM_Contact_BAO_ContactType::subTypes();
216
217 if (is_array($subTypes) && !empty($subTypes)) {
218 $config = CRM_Core_Config::singleton();
219 $subTypeTemplates = array();
220
221 if (isset($config->customTemplateDir)) {
222 foreach ($subTypes as $key => $subTypeName) {
223 $customContactSubTypeEdit = $config->customTemplateDir . "CRM/Contact/Form/Edit/" . $subTypeName . ".tpl";
224 $customContactSubTypeView = $config->customTemplateDir . "CRM/Contact/Page/View/" . $subTypeName . ".tpl";
225 if (file_exists($customContactSubTypeEdit) || file_exists($customContactSubTypeView)) {
226 $subTypeTemplates[$subTypeName] = $subTypeName;
227 }
228 }
229 }
230
231 foreach ($subTypes as $key => $subTypeName) {
232 $customContactSubTypeEdit = $config->templateDir . "CRM/Contact/Form/Edit/" . $subTypeName . ".tpl";
233 $customContactSubTypeView = $config->templateDir . "CRM/Contact/Page/View/" . $subTypeName . ".tpl";
234 if (file_exists($customContactSubTypeEdit) || file_exists($customContactSubTypeView)) {
235 $subTypeTemplates[$subTypeName] = $subTypeName;
236 }
237 }
238
239 if (!empty($subTypeTemplates)) {
240 $subTypeTemplates = implode(',', $subTypeTemplates);
241 $postUpgradeMessage .= '<br />' . ts('You are using custom template for contact subtypes: %1.', array(1 => $subTypeTemplates)) . '<br />' . ts('You need to move these subtype templates to the SubType directory in %1 and %2 respectively.', array(1 => 'CRM/Contact/Form/Edit', 2 => 'CRM/Contact/Page/View'));
242 }
243 }
244 }
245 if ($rev == '3.2.beta4') {
246 $statuses = array('New', 'Current', 'Grace', 'Expired', 'Pending', 'Cancelled', 'Deceased');
247 $sql = "
248 SELECT count( id ) as statusCount
249 FROM civicrm_membership_status
250 WHERE name IN ( '" . implode("' , '", $statuses) . "' ) ";
251 $count = CRM_Core_DAO::singleValueQuery($sql);
252 if ($count < count($statuses)) {
253 $postUpgradeMessage .= '<br />' . ts("One or more Membership Status Rules was disabled during the upgrade because it did not match a recognized status name. if custom membership status rules were added to this site - review the disabled statuses and re-enable any that are still needed (Administer > CiviMember > Membership Status Rules).");
254 }
255 }
256 if ($rev == '3.4.alpha1') {
257 $renamedBinScripts = array(
258 'ParticipantProcessor.php',
259 'RespondentProcessor.php',
260 'UpdateGreeting.php',
261 'UpdateMembershipRecord.php',
262 'UpdatePledgeRecord.php ',
263 );
264 $postUpgradeMessage .= '<br />' . ts('The following files have been renamed to have a ".php" extension instead of a ".php.txt" extension') . ': ' . implode(', ', $renamedBinScripts);
265 }
266 }
267
268 /**
269 * Perform an incremental upgrade
270 *
271 * @param $rev string, the revision to which we are upgrading (Note: When processing a series of upgrades, this is the immediate upgrade - not the final)
272 */
273 static function upgrade_2_2_alpha1($rev) {
274 for ($stepID = 1; $stepID <= 4; $stepID++) {
275 $formName = "CRM_Upgrade_TwoTwo_Form_Step{$stepID}";
276 $form = new $formName();
277
278 $error = NULL;
279 if (!$form->verifyPreDBState($error)) {
280 if (!isset($error)) {
281 $error = "pre-condition failed for current upgrade step $stepID, rev $rev";
282 }
283 CRM_Core_Error::fatal($error);
284 }
285
286 if ($stepID == 4) {
287 return;
288 }
289
290 $template = CRM_Core_Smarty::singleton();
291
292 $eventFees = array();
293 $query = "SELECT og.id ogid FROM civicrm_option_group og WHERE og.name LIKE %1";
294 $params = array(1 => array('civicrm_event_page.amount%', 'String'));
295 $dao = CRM_Core_DAO::executeQuery($query, $params);
296 while ($dao->fetch()) {
297 $eventFees[$dao->ogid] = $dao->ogid;
298 }
299 $template->assign('eventFees', $eventFees);
300
301 $form->upgrade();
302
303 if (!$form->verifyPostDBState($error)) {
304 if (!isset($error)) {
305 $error = "post-condition failed for current upgrade step $stepID, rev $rev";
306 }
307 CRM_Core_Error::fatal($error);
308 }
309 }
310 }
311
312 /**
313 * Perform an incremental upgrade
314 *
315 * @param $rev string, the revision to which we are upgrading (Note: When processing a series of upgrades, this is the immediate upgrade - not the final)
316 */
317 static function upgrade_2_1_2($rev) {
318 $formName = "CRM_Upgrade_TwoOne_Form_TwoOneTwo";
319 $form = new $formName($rev);
320
321 $error = NULL;
322 if (!$form->verifyPreDBState($error)) {
323 if (!isset($error)) {
324 $error = "pre-condition failed for current upgrade for $rev";
325 }
326 CRM_Core_Error::fatal($error);
327 }
328
329 $form->upgrade();
330
331 if (!$form->verifyPostDBState($error)) {
332 if (!isset($error)) {
333 $error = "post-condition failed for current upgrade for $rev";
334 }
335 CRM_Core_Error::fatal($error);
336 }
337 }
338
339 /**
340 * This function should check if if need to skip current sql file
341 * Name of this function will change according to the latest release
342 *
343 */
344 static function upgrade_2_2_alpha3($rev) {
345 // skip processing sql file, if fresh install -
346 if (!CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', 'mail_protocol', 'id', 'name')) {
347 $upgrade = new CRM_Upgrade_Form();
348 $upgrade->processSQL($rev);
349 }
350 return TRUE;
351 }
352
353 /**
354 * Perform an incremental upgrade
355 *
356 * @param $rev string, the revision to which we are upgrading (Note: When processing a series of upgrades, this is the immediate upgrade - not the final)
357 */
358 static function upgrade_2_2_beta1($rev) {
359 if (!CRM_Core_DAO::checkFieldExists('civicrm_pcp_block', 'notify_email')) {
360 $template = CRM_Core_Smarty::singleton();
361 $template->assign('notifyAbsent', TRUE);
362 }
363 $upgrade = new CRM_Upgrade_Form();
364 $upgrade->processSQL($rev);
365 }
366
367 /**
368 * Perform an incremental upgrade
369 *
370 * @param $rev string, the revision to which we are upgrading (Note: When processing a series of upgrades, this is the immediate upgrade - not the final)
371 */
372 static function upgrade_2_2_beta2($rev) {
373 $template = CRM_Core_Smarty::singleton();
374 if (!CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionValue',
375 'CRM_Contact_Form_Search_Custom_ZipCodeRange', 'id', 'name'
376 )) {
377 $template->assign('customSearchAbsentAll', TRUE);
378 }
379 elseif (!CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionValue',
380 'CRM_Contact_Form_Search_Custom_MultipleValues', 'id', 'name'
381 )) {
382 $template->assign('customSearchAbsent', TRUE);
383 }
384 $upgrade = new CRM_Upgrade_Form();
385 $upgrade->processSQL($rev);
386 }
387
388 /**
389 * Perform an incremental upgrade
390 *
391 * @param $rev string, the revision to which we are upgrading (Note: When processing a series of upgrades, this is the immediate upgrade - not the final)
392 */
393 static function upgrade_2_2_beta3($rev) {
394 $template = CRM_Core_Smarty::singleton();
395 if (!CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', 'custom_data_type', 'id', 'name')) {
396 $template->assign('customDataType', TRUE);
397 }
398
399 $upgrade = new CRM_Upgrade_Form();
400 $upgrade->processSQL($rev);
401 }
402
403 /**
404 * Perform an incremental upgrade
405 *
406 * @param $rev string, the revision to which we are upgrading (Note: When processing a series of upgrades, this is the immediate upgrade - not the final)
407 */
408 static function upgrade_3_0_alpha1($rev) {
409
410 $threeZero = new CRM_Upgrade_ThreeZero_ThreeZero();
411
412 $error = NULL;
413 if (!$threeZero->verifyPreDBState($error)) {
414 if (!isset($error)) {
415 $error = 'pre-condition failed for current upgrade for 3.0.alpha2';
416 }
417 CRM_Core_Error::fatal($error);
418 }
419
420 $threeZero->upgrade($rev);
421 }
422
423 /**
424 * Perform an incremental upgrade
425 *
426 * @param $rev string, the revision to which we are upgrading (Note: When processing a series of upgrades, this is the immediate upgrade - not the final)
427 */
428 static function upgrade_3_1_alpha1($rev) {
429
430 $threeOne = new CRM_Upgrade_ThreeOne_ThreeOne();
431
432 $error = NULL;
433 if (!$threeOne->verifyPreDBState($error)) {
434 if (!isset($error)) {
435 $error = 'pre-condition failed for current upgrade for 3.0.alpha2';
436 }
437 CRM_Core_Error::fatal($error);
438 }
439
440 $threeOne->upgrade($rev);
441 }
442
443 /**
444 * Perform an incremental upgrade
445 *
446 * @param $rev string, the revision to which we are upgrading (Note: When processing a series of upgrades, this is the immediate upgrade - not the final)
447 */
448 static function upgrade_2_2_7($rev) {
449 $upgrade = new CRM_Upgrade_Form();
450 $upgrade->processSQL($rev);
451 $sql = "UPDATE civicrm_report_instance
452 SET form_values = REPLACE(form_values,'#',';') ";
453 CRM_Core_DAO::executeQuery($sql, CRM_Core_DAO::$_nullArray);
454
455 // make report component enabled by default
456 $domain = new CRM_Core_DAO_Domain();
457 $domain->selectAdd();
458 $domain->selectAdd('config_backend');
459 $domain->find(TRUE);
460 if ($domain->config_backend) {
461 $defaults = unserialize($domain->config_backend);
462
463 if (is_array($defaults['enableComponents'])) {
464 $compId = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_component WHERE name = 'CiviReport'");
465 if ($compId) {
466 $defaults['enableComponents'][] = 'CiviReport';
467 $defaults['enableComponentIDs'][] = $compId;
468
469 CRM_Core_BAO_ConfigSetting::add($defaults);
470 }
471 }
472 }
473 }
474
475 /**
476 * Perform an incremental upgrade
477 *
478 * @param $rev string, the revision to which we are upgrading (Note: When processing a series of upgrades, this is the immediate upgrade - not the final)
479 */
480 static function upgrade_3_0_2($rev) {
481
482 $template = CRM_Core_Smarty::singleton();
483 //check whether upgraded from 2.1.x or 2.2.x
484 $inboundEmailID = CRM_Core_OptionGroup::getValue('activity_type', 'Inbound Email', 'name');
485
486 if (!empty($inboundEmailID)) {
487 $template->assign('addInboundEmail', FALSE);
488 }
489 else {
490 $template->assign('addInboundEmail', TRUE);
491 }
492
493 $upgrade = new CRM_Upgrade_Form();
494 $upgrade->processSQL($rev);
495 }
496
497 /**
498 * Perform an incremental upgrade
499 *
500 * @param $rev string, the revision to which we are upgrading (Note: When processing a series of upgrades, this is the immediate upgrade - not the final)
501 */
502 static function upgrade_3_0_4($rev) {
503 //make sure 'Deceased' membership status present in db,CRM-5636
504 $template = CRM_Core_Smarty::singleton();
505
506 $addDeceasedStatus = FALSE;
507 $sql = "SELECT max(id) FROM civicrm_membership_status where name = 'Deceased'";
508 if (!CRM_Core_DAO::singleValueQuery($sql)) {
509 $addDeceasedStatus = TRUE;
510 }
511 $template->assign('addDeceasedStatus', $addDeceasedStatus);
512
513 $upgrade = new CRM_Upgrade_Form();
514 $upgrade->processSQL($rev);
515 }
516
517 /**
518 * Perform an incremental upgrade
519 *
520 * @param $rev string, the revision to which we are upgrading (Note: When processing a series of upgrades, this is the immediate upgrade - not the final)
521 */
522 static function upgrade_3_1_0($rev) {
523 // upgrade all roles who have 'access CiviEvent' permission, to also have
524 // newly added permission 'edit_all_events', CRM-5472
525 $config = CRM_Core_Config::singleton();
526 if (is_callable(array(
527 $config->userSystem, 'replacePermission'))) {
528 $config->userSystem->replacePermission('access CiviEvent', array('access CiviEvent', 'edit all events'));
529 }
530
531 //make sure 'Deceased' membership status present in db,CRM-5636
532 $template = CRM_Core_Smarty::singleton();
533
534 $addDeceasedStatus = FALSE;
535 $sql = "SELECT max(id) FROM civicrm_membership_status where name = 'Deceased'";
536 if (!CRM_Core_DAO::singleValueQuery($sql)) {
537 $addDeceasedStatus = TRUE;
538 }
539 $template->assign('addDeceasedStatus', $addDeceasedStatus);
540
541 $upgrade = new CRM_Upgrade_Form();
542 $upgrade->processSQL($rev);
543 }
544
545 /**
546 * Perform an incremental upgrade
547 *
548 * @param $rev string, the revision to which we are upgrading (Note: When processing a series of upgrades, this is the immediate upgrade - not the final)
549 */
550 static function upgrade_3_1_3($rev) {
551 $threeOne = new CRM_Upgrade_ThreeOne_ThreeOne();
552 $threeOne->upgrade_3_1_3();
553
554 $upgrade = new CRM_Upgrade_Form();
555 $upgrade->processSQL($rev);
556 }
557
558 /**
559 * Perform an incremental upgrade
560 *
561 * @param $rev string, the revision to which we are upgrading (Note: When processing a series of upgrades, this is the immediate upgrade - not the final)
562 */
563 static function upgrade_3_1_4($rev) {
564 $threeOne = new CRM_Upgrade_ThreeOne_ThreeOne();
565 $threeOne->upgrade_3_1_4();
566
567 $upgrade = new CRM_Upgrade_Form();
568 $upgrade->processSQL($rev);
569 }
570 }
571