This commit is contained in:
Andrew Nicols 2020-01-15 12:40:19 +08:00
commit 20a7746b1e
13 changed files with 617 additions and 23 deletions

View file

@ -59,12 +59,21 @@ class core_plugin_manager {
const REQUIREMENT_STATUS_OUTDATED = 'outdated';
/** the required dependency is not installed */
const REQUIREMENT_STATUS_MISSING = 'missing';
/** the current Moodle version is too high for plugin. */
const REQUIREMENT_STATUS_NEWER = 'newer';
/** the required dependency is available in the plugins directory */
const REQUIREMENT_AVAILABLE = 'available';
/** the required dependency is available in the plugins directory */
const REQUIREMENT_UNAVAILABLE = 'unavailable';
/** the moodle version is explicitly supported */
const VERSION_SUPPORTED = 'supported';
/** the moodle version is not explicitly supported */
const VERSION_NOT_SUPPORTED = 'notsupported';
/** the plugin does not specify supports */
const VERSION_NO_SUPPORTS = 'nosupports';
/** @var core_plugin_manager holds the singleton instance */
protected static $singletoninstance;
/** @var array of raw plugins information */
@ -737,10 +746,14 @@ class core_plugin_manager {
*
* @param int $moodleversion the version from version.php.
* @param array $failedplugins to return the list of plugins with non-satisfied dependencies
* @param int $branch the current moodle branch, null if not provided
* @return bool true if all the dependencies are satisfied for all plugins.
*/
public function all_plugins_ok($moodleversion, &$failedplugins = array()) {
public function all_plugins_ok($moodleversion, &$failedplugins = array(), $branch = null) {
global $CFG;
if (empty($branch)) {
$branch = $CFG->branch;
}
$return = true;
foreach ($this->get_plugins() as $type => $plugins) {
foreach ($plugins as $plugin) {
@ -754,6 +767,11 @@ class core_plugin_manager {
$return = false;
$failedplugins[] = $plugin->component;
}
if (!$plugin->is_core_compatible_satisfied($branch)) {
$return = false;
$failedplugins[] = $plugin->component;
}
}
}
@ -794,7 +812,7 @@ class core_plugin_manager {
}
$reqs = array();
$reqcore = $this->resolve_core_requirements($plugin, $moodleversion);
$reqcore = $this->resolve_core_requirements($plugin, $moodleversion, $moodlebranch);
if (!empty($reqcore)) {
$reqs['core'] = $reqcore;
@ -814,7 +832,7 @@ class core_plugin_manager {
* @param string|int|double $moodleversion moodle core branch to check against
* @return stdObject
*/
protected function resolve_core_requirements(\core\plugininfo\base $plugin, $moodleversion) {
protected function resolve_core_requirements(\core\plugininfo\base $plugin, $moodleversion, $moodlebranch) {
$reqs = (object)array(
'hasver' => null,
@ -822,7 +840,6 @@ class core_plugin_manager {
'status' => null,
'availability' => null,
);
$reqs->hasver = $moodleversion;
if (empty($plugin->versionrequires)) {
@ -837,6 +854,14 @@ class core_plugin_manager {
$reqs->status = self::REQUIREMENT_STATUS_OUTDATED;
}
// Now check if there is an explicit incompatible, supersedes requires.
if (isset($plugin->pluginincompatible) && $plugin->pluginincompatible != null) {
if (!$plugin->is_core_compatible_satisfied($moodlebranch)) {
$reqs->status = self::REQUIREMENT_STATUS_NEWER;
}
}
return $reqs;
}
@ -890,6 +915,49 @@ class core_plugin_manager {
return $reqs;
}
/**
* Helper method to determine whether a moodle version is explicitly supported.
*
* @param \core\plugininfo\base $plugin the plugin we are checking
* @param int $branch the moodle branch to check support for
* @return bool
*/
public function check_explicitly_supported($plugin, $branch) : bool {
// Check for correctly formed supported.
if (isset($plugin->pluginsupported)) {
// Broken apart for readability.
$error = false;
if (!is_array($plugin->pluginsupported)) {
$error = true;
}
if (!is_int($plugin->pluginsupported[0]) || !is_int($plugin->pluginsupported[1])) {
$error = true;
}
if (count($plugin->pluginsupported) != 2) {
$error = true;
}
if ($error) {
throw new coding_exception(get_string('err_supported_syntax', 'core_plugin'));
}
}
if (isset($plugin->pluginsupported) && $plugin->pluginsupported != null) {
if ($plugin->pluginsupported[0] <= $branch && $branch <= $plugin->pluginsupported[1]) {
return self::VERSION_SUPPORTED;
} else {
return self::VERSION_NOT_SUPPORTED;
}
} else {
// If supports aren't specified, but incompatible is, return not supported if not incompatible.
if (!isset($plugin->pluginsupported) && isset($plugin->pluginincompatible) && !empty($plugin->pluginincompatible)) {
if (!$plugin->is_core_compatible_satisfied($branch)) {
return self::VERSION_NOT_SUPPORTED;
}
}
return self::VERSION_NO_SUPPORTS;
}
}
/**
* Is the given plugin version available in the plugins directory?
*

View file

@ -53,6 +53,10 @@ abstract class base {
public $versiondb;
/** @var int|float|string required version of Moodle core */
public $versionrequires;
/** @var array explicitly supported branches of Moodle core */
public $pluginsupported;
/** @var int first incompatible branch of Moodle core */
public $pluginincompatible;
/** @var mixed human-readable release information */
public $release;
/** @var array other plugins that this one depends on, lazy-loaded by {@link get_other_required_plugins()} */
@ -218,6 +222,8 @@ abstract class base {
$this->versiondisk = null;
$this->versionrequires = null;
$this->pluginsupported = null;
$this->pluginincompatible = null;
$this->dependencies = array();
if (!isset($versions[$this->name])) {
@ -238,6 +244,28 @@ abstract class base {
if (isset($plugin->dependencies)) {
$this->dependencies = $plugin->dependencies;
}
// Check that supports and incompatible are wellformed, exception otherwise.
if (isset($plugin->supported)) {
// Checks for structure of supported.
$isint = (is_int($plugin->supported[0]) && is_int($plugin->supported[1]));
$isrange = ($plugin->supported[0] <= $plugin->supported[1] && count($plugin->supported) == 2);
if (is_array($plugin->supported) && $isint && $isrange) {
$this->pluginsupported = $plugin->supported;
} else {
throw new coding_exception('Incorrect syntax in $plugin->supported in '."$this->name");
}
}
if (isset($plugin->incompatible) && $plugin->incompatible !== null) {
if ((ctype_digit($plugin->incompatible) || is_int($plugin->incompatible)) && (int) $plugin->incompatible > 0) {
$this->pluginincompatible = intval($plugin->incompatible);
} else {
throw new coding_exception('Incorrect syntax in $plugin->incompatible in '."$this->name");
}
}
}
/**
@ -341,6 +369,20 @@ abstract class base {
}
}
/**
* Returns true if the the given moodle branch is not stated incompatible with the plugin
*
* @param int $branch the moodle branch number
* @return bool true if not incompatible with moodle branch
*/
public function is_core_compatible_satisfied(int $branch) : bool {
if (!empty($this->pluginincompatible) && ($branch >= $this->pluginincompatible)) {
return false;
} else {
return true;
}
}
/**
* Returns the status of the plugin
*