Merge pull request #14222 from mfb/debug-var
[civicrm-core.git] / CRM / Upgrade / Form.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2019 |
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-2019
32 * $Id$
33 *
34 */
35 class CRM_Upgrade_Form extends CRM_Core_Form {
36 const QUEUE_NAME = 'CRM_Upgrade';
37
38 /**
39 * Minimum size of MySQL's thread_stack option
40 *
41 * @see install/index.php MINIMUM_THREAD_STACK
42 */
43 const MINIMUM_THREAD_STACK = 192;
44
45 /**
46 * Minimum previous CiviCRM version we can directly upgrade from
47 */
48 const MINIMUM_UPGRADABLE_VERSION = '4.2.9';
49
50 /**
51 * Minimum php version required to run (equal to or lower than the minimum install version)
52 *
53 * Even though 5.6 is no longer supported, this value is left here for a while
54 * so as not to block stragglers from upgrading.
55 */
56 const MINIMUM_PHP_VERSION = '5.6';
57
58 /**
59 * @var \CRM_Core_Config
60 */
61 protected $_config;
62
63 /**
64 * Upgrade for multilingual.
65 *
66 * @var bool
67 */
68 public $multilingual = FALSE;
69
70 /**
71 * Locales available for multilingual upgrade.
72 *
73 * @var array
74 */
75 public $locales;
76
77 /**
78 * Constructor for the basic form page.
79 *
80 * We should not use QuickForm directly. This class provides a lot
81 * of default convenient functions, rules and buttons
82 *
83 * @param object $state
84 * State associated with this form.
85 * @param const|\enum|int $action The mode the form is operating in (None/Create/View/Update/Delete)
86 * @param string $method
87 * The type of http method used (GET/POST).
88 * @param string $name
89 * The name of the form if different from class name.
90 */
91 public function __construct(
92 $state = NULL,
93 $action = CRM_Core_Action::NONE,
94 $method = 'post',
95 $name = NULL
96 ) {
97 $this->_config = CRM_Core_Config::singleton();
98
99 $domain = new CRM_Core_DAO_Domain();
100 $domain->find(TRUE);
101
102 $this->multilingual = (bool) $domain->locales;
103 $this->locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);
104
105 $smarty = CRM_Core_Smarty::singleton();
106 //$smarty->compile_dir = $this->_config->templateCompileDir;
107 $smarty->assign('multilingual', $this->multilingual);
108 $smarty->assign('locales', $this->locales);
109
110 // we didn't call CRM_Core_BAO_ConfigSetting::retrieve(), so we need to set $dbLocale by hand
111 if ($this->multilingual) {
112 global $dbLocale;
113 $dbLocale = "_{$this->_config->lcMessages}";
114 }
115
116 parent::__construct($state, $action, $method, $name);
117 }
118
119 /**
120 * @param $version
121 *
122 * @return mixed
123 */
124 public static function &incrementalPhpObject($version) {
125 static $incrementalPhpObject = [];
126
127 $versionParts = explode('.', $version);
128 $versionName = CRM_Utils_EnglishNumber::toCamelCase($versionParts[0]) . CRM_Utils_EnglishNumber::toCamelCase($versionParts[1]);
129
130 if (!array_key_exists($versionName, $incrementalPhpObject)) {
131 $className = "CRM_Upgrade_Incremental_php_{$versionName}";
132 $incrementalPhpObject[$versionName] = new $className();
133 }
134 return $incrementalPhpObject[$versionName];
135 }
136
137 /**
138 * @param $version
139 * @param $release
140 *
141 * @return bool
142 */
143 public function checkVersionRelease($version, $release) {
144 $versionParts = explode('.', $version);
145 return ($versionParts[2] == $release);
146 }
147
148 /**
149 * @param $constraints
150 *
151 * @return array
152 */
153 public function checkSQLConstraints(&$constraints) {
154 $pass = $fail = 0;
155 foreach ($constraints as $constraint) {
156 if ($this->checkSQLConstraint($constraint)) {
157 $pass++;
158 }
159 else {
160 $fail++;
161 }
162 return [$pass, $fail];
163 }
164 }
165
166 /**
167 * @param $constraint
168 *
169 * @return bool
170 */
171 public function checkSQLConstraint($constraint) {
172 // check constraint here
173 return TRUE;
174 }
175
176 /**
177 * @param string $fileName
178 * @param bool $isQueryString
179 */
180 public function source($fileName, $isQueryString = FALSE) {
181 if ($isQueryString) {
182 CRM_Utils_File::runSqlQuery($this->_config->dsn,
183 $fileName, NULL
184 );
185 }
186 else {
187 CRM_Utils_File::sourceSQLFile($this->_config->dsn,
188 $fileName, NULL
189 );
190 }
191 }
192
193 public function preProcess() {
194 CRM_Utils_System::setTitle($this->getTitle());
195 if (!$this->verifyPreDBState($errorMessage)) {
196 if (!isset($errorMessage)) {
197 $errorMessage = 'pre-condition failed for current upgrade step';
198 }
199 CRM_Core_Error::fatal($errorMessage);
200 }
201 $this->assign('recentlyViewed', FALSE);
202 }
203
204 public function buildQuickForm() {
205 $this->addDefaultButtons($this->getButtonTitle(),
206 'next',
207 NULL,
208 TRUE
209 );
210 }
211
212 /**
213 * Getter function for title. Should be over-ridden by derived class
214 *
215 * @return string
216 */
217
218 /**
219 * @return string
220 */
221 public function getTitle() {
222 return ts('Title not Set');
223 }
224
225 /**
226 * @return string
227 */
228 public function getFieldsetTitle() {
229 return '';
230 }
231
232 /**
233 * @return string
234 */
235 public function getButtonTitle() {
236 return ts('Continue');
237 }
238
239 /**
240 * Use the form name to create the tpl file name.
241 *
242 * @return string
243 */
244
245 /**
246 * @return string
247 */
248 public function getTemplateFileName() {
249 $this->assign('title',
250 $this->getFieldsetTitle()
251 );
252 $this->assign('message',
253 $this->getTemplateMessage()
254 );
255 return 'CRM/Upgrade/Base.tpl';
256 }
257
258 public function postProcess() {
259 $this->upgrade();
260
261 if (!$this->verifyPostDBState($errorMessage)) {
262 if (!isset($errorMessage)) {
263 $errorMessage = 'post-condition failed for current upgrade step';
264 }
265 CRM_Core_Error::fatal($errorMessage);
266 }
267 }
268
269 /**
270 * @param $query
271 *
272 * @return Object
273 */
274 public function runQuery($query) {
275 return CRM_Core_DAO::executeQuery($query);
276 }
277
278 /**
279 * @param $version
280 *
281 * @return Object
282 */
283 public function setVersion($version) {
284 $this->logVersion($version);
285
286 $query = "
287 UPDATE civicrm_domain
288 SET version = '$version'
289 ";
290 return $this->runQuery($query);
291 }
292
293 /**
294 * @param $newVersion
295 *
296 * @return bool
297 */
298 public function logVersion($newVersion) {
299 if ($newVersion) {
300 $oldVersion = CRM_Core_BAO_Domain::version();
301
302 $session = CRM_Core_Session::singleton();
303 $logParams = [
304 'entity_table' => 'civicrm_domain',
305 'entity_id' => 1,
306 'data' => "upgrade:{$oldVersion}->{$newVersion}",
307 // lets skip 'modified_id' for now, as it causes FK issues And
308 // is not very important for now.
309 'modified_date' => date('YmdHis'),
310 ];
311 CRM_Core_BAO_Log::add($logParams);
312 return TRUE;
313 }
314
315 return FALSE;
316 }
317
318 /**
319 * @param $version
320 *
321 * @return bool
322 */
323 public function checkVersion($version) {
324 $domainID = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Domain',
325 $version, 'id',
326 'version'
327 );
328 return $domainID ? TRUE : FALSE;
329 }
330
331 /**
332 * @return array
333 * @throws Exception
334 */
335 public function getRevisionSequence() {
336 $revList = [];
337 $sqlDir = implode(DIRECTORY_SEPARATOR,
338 [dirname(__FILE__), 'Incremental', 'sql']
339 );
340 $sqlFiles = scandir($sqlDir);
341
342 $sqlFilePattern = '/^((\d{1,2}\.\d{1,2})\.(\d{1,2}\.)?(\d{1,2}|\w{4,7}))\.(my)?sql(\.tpl)?$/i';
343 foreach ($sqlFiles as $file) {
344 if (preg_match($sqlFilePattern, $file, $matches)) {
345 if (!in_array($matches[1], $revList)) {
346 $revList[] = $matches[1];
347 }
348 }
349 }
350
351 usort($revList, 'version_compare');
352 return $revList;
353 }
354
355 /**
356 * @param $rev
357 * @param int $index
358 *
359 * @return null
360 */
361 public static function getRevisionPart($rev, $index = 1) {
362 $revPattern = '/^((\d{1,2})\.\d{1,2})\.(\d{1,2}|\w{4,7})?$/i';
363 preg_match($revPattern, $rev, $matches);
364
365 return array_key_exists($index, $matches) ? $matches[$index] : NULL;
366 }
367
368 /**
369 * @param $tplFile
370 * @param $rev
371 *
372 * @return bool
373 */
374 public function processLocales($tplFile, $rev) {
375 $smarty = CRM_Core_Smarty::singleton();
376 $smarty->assign('domainID', CRM_Core_Config::domainID());
377
378 $this->source($smarty->fetch($tplFile), TRUE);
379
380 if ($this->multilingual) {
381 CRM_Core_I18n_Schema::rebuildMultilingualSchema($this->locales, $rev);
382 }
383 return $this->multilingual;
384 }
385
386 /**
387 * @param $rev
388 */
389 public function setSchemaStructureTables($rev) {
390 if ($this->multilingual) {
391 CRM_Core_I18n_Schema::schemaStructureTables($rev, TRUE);
392 }
393 }
394
395 /**
396 * @param $rev
397 *
398 * @throws Exception
399 */
400 public function processSQL($rev) {
401 $sqlFile = implode(DIRECTORY_SEPARATOR,
402 [
403 dirname(__FILE__),
404 'Incremental',
405 'sql',
406 $rev . '.mysql',
407 ]
408 );
409 $tplFile = "$sqlFile.tpl";
410
411 if (file_exists($tplFile)) {
412 $this->processLocales($tplFile, $rev);
413 }
414 else {
415 if (!file_exists($sqlFile)) {
416 CRM_Core_Error::fatal("sqlfile - $rev.mysql not found.");
417 }
418 $this->source($sqlFile);
419 }
420 }
421
422 /**
423 * Determine the start and end version of the upgrade process.
424 *
425 * @return array(0=>$currentVer, 1=>$latestVer)
426 */
427 public function getUpgradeVersions() {
428 $latestVer = CRM_Utils_System::version();
429 $currentVer = CRM_Core_BAO_Domain::version(TRUE);
430 if (!$currentVer) {
431 CRM_Core_Error::fatal(ts('Version information missing in civicrm database.'));
432 }
433 elseif (stripos($currentVer, 'upgrade')) {
434 CRM_Core_Error::fatal(ts('Database check failed - the database looks to have been partially upgraded. You may want to reload the database with the backup and try the upgrade process again.'));
435 }
436 if (!$latestVer) {
437 CRM_Core_Error::fatal(ts('Version information missing in civicrm codebase.'));
438 }
439
440 return [$currentVer, $latestVer];
441 }
442
443 /**
444 * Determine if $currentVer can be upgraded to $latestVer
445 *
446 * @param $currentVer
447 * @param $latestVer
448 *
449 * @return mixed, a string error message or boolean 'false' if OK
450 */
451 public function checkUpgradeableVersion($currentVer, $latestVer) {
452 $error = FALSE;
453 // since version is suppose to be in valid format at this point, especially after conversion ($convertVer),
454 // lets do a pattern check -
455 if (!CRM_Utils_System::isVersionFormatValid($currentVer)) {
456 $error = ts('Database is marked with invalid version format. You may want to investigate this before you proceed further.');
457 }
458 elseif (version_compare($currentVer, $latestVer) > 0) {
459 // DB version number is higher than codebase being upgraded to. This is unexpected condition-fatal error.
460 $error = ts('Your database is marked with an unexpected version number: %1. The automated upgrade to version %2 can not be run - and the %2 codebase may not be compatible with your database state. You will need to determine the correct version corresponding to your current database state. You may want to revert to the codebase you were using prior to beginning this upgrade until you resolve this problem.',
461 [1 => $currentVer, 2 => $latestVer]
462 );
463 }
464 elseif (version_compare($currentVer, $latestVer) == 0) {
465 $error = ts('Your database has already been upgraded to CiviCRM %1',
466 [1 => $latestVer]
467 );
468 }
469 elseif (version_compare($currentVer, self::MINIMUM_UPGRADABLE_VERSION) < 0) {
470 $error = ts('CiviCRM versions prior to %1 cannot be upgraded directly to %2. This upgrade will need to be done in stages. First download an intermediate version (the LTS may be a good choice) and upgrade to that before proceeding to this version.',
471 [1 => self::MINIMUM_UPGRADABLE_VERSION, 2 => $latestVer]
472 );
473 }
474
475 if (version_compare(phpversion(), self::MINIMUM_PHP_VERSION) < 0) {
476 $error = ts('CiviCRM %3 requires PHP version %1 (or newer), but the current system uses %2 ',
477 [
478 1 => self::MINIMUM_PHP_VERSION,
479 2 => phpversion(),
480 3 => $latestVer,
481 ]);
482 }
483
484 // check for mysql trigger privileges
485 if (!\Civi::settings()->get('logging_no_trigger_permission') && !CRM_Core_DAO::checkTriggerViewPermission(FALSE, TRUE)) {
486 $error = ts('CiviCRM %1 requires MySQL trigger privileges.',
487 [1 => $latestVer]);
488 }
489
490 if (CRM_Core_DAO::getGlobalSetting('thread_stack', 0) < (1024 * self::MINIMUM_THREAD_STACK)) {
491 $error = ts('CiviCRM %1 requires MySQL thread stack >= %2k', [
492 1 => $latestVer,
493 2 => self::MINIMUM_THREAD_STACK,
494 ]);
495 }
496
497 return $error;
498 }
499
500 /**
501 * Determine if $currentver already matches $latestVer
502 *
503 * @param $currentVer
504 * @param $latestVer
505 *
506 * @return mixed, a string error message or boolean 'false' if OK
507 */
508 public function checkCurrentVersion($currentVer, $latestVer) {
509 $error = FALSE;
510
511 // since version is suppose to be in valid format at this point, especially after conversion ($convertVer),
512 // lets do a pattern check -
513 if (!CRM_Utils_System::isVersionFormatValid($currentVer)) {
514 $error = ts('Database is marked with invalid version format. You may want to investigate this before you proceed further.');
515 }
516 elseif (version_compare($currentVer, $latestVer) != 0) {
517 $error = ts('Your database is not configured for version %1',
518 [1 => $latestVer]
519 );
520 }
521 return $error;
522 }
523
524 /**
525 * Fill the queue with upgrade tasks.
526 *
527 * @param string $currentVer
528 * the original revision.
529 * @param string $latestVer
530 * the target (final) revision.
531 * @param string $postUpgradeMessageFile
532 * path of a modifiable file which lists the post-upgrade messages.
533 *
534 * @return CRM_Queue_Service
535 */
536 public static function buildQueue($currentVer, $latestVer, $postUpgradeMessageFile) {
537 $upgrade = new CRM_Upgrade_Form();
538
539 // Ensure that queue can be created
540 if (!CRM_Queue_BAO_QueueItem::findCreateTable()) {
541 CRM_Core_Error::fatal(ts('Failed to find or create queueing table'));
542 }
543 $queue = CRM_Queue_Service::singleton()->create([
544 'name' => self::QUEUE_NAME,
545 'type' => 'Sql',
546 'reset' => TRUE,
547 ]);
548
549 $task = new CRM_Queue_Task(
550 ['CRM_Upgrade_Form', 'doFileCleanup'],
551 [$postUpgradeMessageFile],
552 "Cleanup old files"
553 );
554 $queue->createItem($task);
555
556 $task = new CRM_Queue_Task(
557 ['CRM_Upgrade_Form', 'disableOldExtensions'],
558 [$postUpgradeMessageFile],
559 "Checking extensions"
560 );
561 $queue->createItem($task);
562
563 $revisions = $upgrade->getRevisionSequence();
564 foreach ($revisions as $rev) {
565 // proceed only if $currentVer < $rev
566 if (version_compare($currentVer, $rev) < 0) {
567 $beginTask = new CRM_Queue_Task(
568 // callback
569 ['CRM_Upgrade_Form', 'doIncrementalUpgradeStart'],
570 // arguments
571 [$rev],
572 "Begin Upgrade to $rev"
573 );
574 $queue->createItem($beginTask);
575
576 $task = new CRM_Queue_Task(
577 // callback
578 ['CRM_Upgrade_Form', 'doIncrementalUpgradeStep'],
579 // arguments
580 [$rev, $currentVer, $latestVer, $postUpgradeMessageFile],
581 "Upgrade DB to $rev"
582 );
583 $queue->createItem($task);
584
585 $task = new CRM_Queue_Task(
586 // callback
587 ['CRM_Upgrade_Form', 'doIncrementalUpgradeFinish'],
588 // arguments
589 [$rev, $currentVer, $latestVer, $postUpgradeMessageFile],
590 "Finish Upgrade DB to $rev"
591 );
592 $queue->createItem($task);
593 }
594 }
595
596 return $queue;
597 }
598
599 /**
600 * Find any old, orphaned files that should have been deleted.
601 *
602 * These files can get left behind, eg, if you use the Joomla
603 * upgrade procedure.
604 *
605 * The earlier we can do this, the better - don't want upgrade logic
606 * to inadvertently rely on old/relocated files.
607 *
608 * @param \CRM_Queue_TaskContext $ctx
609 * @param string $postUpgradeMessageFile
610 * @return bool
611 */
612 public static function doFileCleanup(CRM_Queue_TaskContext $ctx, $postUpgradeMessageFile) {
613 $source = new CRM_Utils_Check_Component_Source();
614 $files = $source->findOrphanedFiles();
615 $errors = [];
616 foreach ($files as $file) {
617 if (is_dir($file['path'])) {
618 @rmdir($file['path']);
619 }
620 else {
621 @unlink($file['path']);
622 }
623
624 if (file_exists($file['path'])) {
625 $errors[] = sprintf("<li>%s</li>", htmlentities($file['path']));
626 }
627 }
628
629 if (!empty($errors)) {
630 file_put_contents($postUpgradeMessageFile,
631 '<br/><br/>' . ts('Some old files could not be removed. Please remove them.')
632 . '<ul>' . implode("\n", $errors) . '</ul>',
633 FILE_APPEND
634 );
635 }
636
637 return TRUE;
638 }
639
640 /**
641 * Disable any extensions not compatible with this new version.
642 *
643 * @param \CRM_Queue_TaskContext $ctx
644 * @param string $postUpgradeMessageFile
645 * @return bool
646 */
647 public static function disableOldExtensions(CRM_Queue_TaskContext $ctx, $postUpgradeMessageFile) {
648 $compatInfo = CRM_Extension_System::getCompatibilityInfo();
649 $disabled = [];
650 $manager = CRM_Extension_System::singleton()->getManager();
651 foreach ($compatInfo as $key => $ext) {
652 if (!empty($ext['obsolete']) && $manager->getStatus($key) == $manager::STATUS_INSTALLED) {
653 $disabled[$key] = sprintf("<li>%s</li>", ts('The extension %1 is now obsolete and has been disabled.', [1 => $key]));
654 }
655 }
656 if ($disabled) {
657 $manager->disable(array_keys($disabled));
658 file_put_contents($postUpgradeMessageFile,
659 '<br/><br/><ul>' . implode("\n", $disabled) . '</ul>',
660 FILE_APPEND
661 );
662 }
663
664 return TRUE;
665 }
666
667 /**
668 * Perform an incremental version update.
669 *
670 * @param CRM_Queue_TaskContext $ctx
671 * @param string $rev
672 * the target (intermediate) revision e.g '3.2.alpha1'.
673 *
674 * @return bool
675 */
676 public static function doIncrementalUpgradeStart(CRM_Queue_TaskContext $ctx, $rev) {
677 $upgrade = new CRM_Upgrade_Form();
678
679 // as soon as we start doing anything we append ".upgrade" to version.
680 // this also helps detect any partial upgrade issues
681 $upgrade->setVersion($rev . '.upgrade');
682
683 return TRUE;
684 }
685
686 /**
687 * Perform an incremental version update.
688 *
689 * @param CRM_Queue_TaskContext $ctx
690 * @param string $rev
691 * the target (intermediate) revision e.g '3.2.alpha1'.
692 * @param string $originalVer
693 * the original revision.
694 * @param string $latestVer
695 * the target (final) revision.
696 * @param string $postUpgradeMessageFile
697 * path of a modifiable file which lists the post-upgrade messages.
698 *
699 * @return bool
700 */
701 public static function doIncrementalUpgradeStep(CRM_Queue_TaskContext $ctx, $rev, $originalVer, $latestVer, $postUpgradeMessageFile) {
702 $upgrade = new CRM_Upgrade_Form();
703
704 $phpFunctionName = 'upgrade_' . str_replace('.', '_', $rev);
705
706 $versionObject = $upgrade->incrementalPhpObject($rev);
707
708 // pre-db check for major release.
709 if ($upgrade->checkVersionRelease($rev, 'alpha1')) {
710 if (!(is_callable([$versionObject, 'verifyPreDBstate']))) {
711 CRM_Core_Error::fatal("verifyPreDBstate method was not found for $rev");
712 }
713
714 $error = NULL;
715 if (!($versionObject->verifyPreDBstate($error))) {
716 if (!isset($error)) {
717 $error = "post-condition failed for current upgrade for $rev";
718 }
719 CRM_Core_Error::fatal($error);
720 }
721
722 }
723
724 $upgrade->setSchemaStructureTables($rev);
725
726 if (is_callable([$versionObject, $phpFunctionName])) {
727 $versionObject->$phpFunctionName($rev, $originalVer, $latestVer);
728 }
729 else {
730 $upgrade->processSQL($rev);
731 }
732
733 // set post-upgrade-message if any
734 if (is_callable([$versionObject, 'setPostUpgradeMessage'])) {
735 $postUpgradeMessage = file_get_contents($postUpgradeMessageFile);
736 $versionObject->setPostUpgradeMessage($postUpgradeMessage, $rev);
737 file_put_contents($postUpgradeMessageFile, $postUpgradeMessage);
738 }
739
740 return TRUE;
741 }
742
743 /**
744 * Perform an incremental version update.
745 *
746 * @param CRM_Queue_TaskContext $ctx
747 * @param string $rev
748 * the target (intermediate) revision e.g '3.2.alpha1'.
749 * @param string $currentVer
750 * the original revision.
751 * @param string $latestVer
752 * the target (final) revision.
753 * @param string $postUpgradeMessageFile
754 * path of a modifiable file which lists the post-upgrade messages.
755 *
756 * @return bool
757 */
758 public static function doIncrementalUpgradeFinish(CRM_Queue_TaskContext $ctx, $rev, $currentVer, $latestVer, $postUpgradeMessageFile) {
759 $upgrade = new CRM_Upgrade_Form();
760 $upgrade->setVersion($rev);
761 CRM_Utils_System::flushCache();
762
763 $config = CRM_Core_Config::singleton();
764 $config->userSystem->flush();
765 return TRUE;
766 }
767
768 public static function doFinish() {
769 $upgrade = new CRM_Upgrade_Form();
770 list($ignore, $latestVer) = $upgrade->getUpgradeVersions();
771 // Seems extraneous in context, but we'll preserve old behavior
772 $upgrade->setVersion($latestVer);
773
774 // Clear cached metadata.
775 Civi::service('settings_manager')->flush();
776
777 // cleanup caches CRM-8739
778 $config = CRM_Core_Config::singleton();
779 $config->cleanupCaches(1);
780
781 $versionCheck = new CRM_Utils_VersionCheck();
782 $versionCheck->flushCache();
783
784 // Rebuild all triggers and re-enable logging if needed
785 $logging = new CRM_Logging_Schema();
786 $logging->fixSchemaDifferences();
787 }
788
789 /**
790 * Compute any messages which should be displayed before upgrade
791 * by calling the 'setPreUpgradeMessage' on each incremental upgrade
792 * object.
793 *
794 * @param string $preUpgradeMessage
795 * alterable.
796 * @param $currentVer
797 * @param $latestVer
798 */
799 public function setPreUpgradeMessage(&$preUpgradeMessage, $currentVer, $latestVer) {
800 // check for changed message templates
801 CRM_Upgrade_Incremental_General::checkMessageTemplate($preUpgradeMessage, $latestVer, $currentVer);
802 // set global messages
803 CRM_Upgrade_Incremental_General::setPreUpgradeMessage($preUpgradeMessage, $currentVer, $latestVer);
804
805 // Scan through all php files and see if any file is interested in setting pre-upgrade-message
806 // based on $currentVer, $latestVer.
807 // Please note, at this point upgrade hasn't started executing queries.
808 $revisions = $this->getRevisionSequence();
809 foreach ($revisions as $rev) {
810 if (version_compare($currentVer, $rev) < 0) {
811 $versionObject = $this->incrementalPhpObject($rev);
812 CRM_Upgrade_Incremental_General::updateMessageTemplate($preUpgradeMessage, $rev);
813 if (is_callable([$versionObject, 'setPreUpgradeMessage'])) {
814 $versionObject->setPreUpgradeMessage($preUpgradeMessage, $rev, $currentVer);
815 }
816 }
817 }
818 }
819
820 }