/**
* Minimum previous CiviCRM version we can directly upgrade from
*/
- const MINIMUM_UPGRADABLE_VERSION = '4.4.7';
+ const MINIMUM_UPGRADABLE_VERSION = '4.5.9';
/**
* @var \CRM_Core_Config
}
/**
- * @param $version
+ * @param string $version
+ * Ex: '5.22' or '5.22.3'
*
- * @return mixed
+ * @return CRM_Upgrade_Incremental_Base
+ * Ex: CRM_Upgrade_Incremental_php_FiveTwentyTwo
*/
public static function &incrementalPhpObject($version) {
static $incrementalPhpObject = [];
return $incrementalPhpObject[$versionName];
}
+ /**
+ * @return array
+ * ex: ['5.13', '5.14', '5.15']
+ */
+ public static function incrementalPhpObjectVersions() {
+ $versions = [];
+
+ $phpDir = implode(DIRECTORY_SEPARATOR, [dirname(__FILE__), 'Incremental', 'php']);
+ $phpFiles = glob("$phpDir/*.php");
+ foreach ($phpFiles as $phpFile) {
+ $phpWord = substr(basename($phpFile), 0, -4);
+ if (CRM_Utils_EnglishNumber::isNumeric($phpWord)) {
+ /** @var \CRM_Upgrade_Incremental_Base $instance */
+ $className = 'CRM_Upgrade_Incremental_php_' . $phpWord;
+ $instance = new $className();
+ $versions[] = $instance->getMajorMinor();
+ }
+ }
+
+ usort($versions, 'version_compare');
+ return $versions;
+ }
+
/**
* @param $version
* @param $release
}
public function preProcess() {
- CRM_Utils_System::setTitle($this->getTitle());
+ $this->setTitle($this->getTitle());
if (!$this->verifyPreDBState($errorMessage)) {
if (!isset($errorMessage)) {
$errorMessage = 'pre-condition failed for current upgrade step';
}
/**
+ * Get a list of all patch-versions that appear in upgrade steps, whether
+ * as *.mysql.tpl or as *.php.
+ *
* @return array
* @throws Exception
*/
public function getRevisionSequence() {
$revList = [];
- $sqlDir = implode(DIRECTORY_SEPARATOR,
- [dirname(__FILE__), 'Incremental', 'sql']
- );
- $sqlFiles = scandir($sqlDir);
- $sqlFilePattern = '/^((\d{1,2}\.\d{1,2})\.(\d{1,2}\.)?(\d{1,2}|\w{4,7}))\.(my)?sql(\.tpl)?$/i';
- foreach ($sqlFiles as $file) {
- if (preg_match($sqlFilePattern, $file, $matches)) {
- if (!in_array($matches[1], $revList)) {
- $revList[] = $matches[1];
- }
- }
+ foreach (self::incrementalPhpObjectVersions() as $majorMinor) {
+ $phpUpgrader = self::incrementalPhpObject($majorMinor);
+ $revList = array_merge($revList, array_values($phpUpgrader->getRevisionSequence()));
}
usort($revList, 'version_compare');
$queue->createItem($task);
$revisions = $upgrade->getRevisionSequence();
+ $maxRevision = empty($revisions) ? NULL : end($revisions);
+ reset($revisions);
+ if (version_compare($latestVer, $maxRevision, '<')) {
+ throw new CRM_Core_Exception("Malformed upgrade sequence. The incremental update $maxRevision exceeds target version $latestVer");
+ }
+
foreach ($revisions as $rev) {
// proceed only if $currentVer < $rev
if (version_compare($currentVer, $rev) < 0) {
}
}
+ // It's possible that xml/version.xml points to a version that doesn't have any concrete revision steps.
+ if (!in_array($latestVer, $revisions)) {
+ $task = new CRM_Queue_Task(
+ ['CRM_Upgrade_Form', 'doIncrementalUpgradeFinish'],
+ [$rev, $latestVer, $latestVer, $postUpgradeMessageFile],
+ "Finish Upgrade DB to $latestVer"
+ );
+ $queue->createItem($task);
+ }
+
return $queue;
}
}
/**
- * Perform an incremental version update.
+ * Mark an incremental update as finished.
+ *
+ * This method may be called in two cases:
+ *
+ * - After performing each incremental update (`X.X.X.mysql.tpl` or `upgrade_X_X_X()`)
+ * - If needed, one more time at the end of the upgrade for the final version-number.
*
* @param CRM_Queue_TaskContext $ctx
* @param string $rev