mirror of
https://github.com/moodle/moodle.git
synced 2025-08-08 18:36:42 +02:00
Merge branch 'mdl-59562' of https://github.com/Peterburnett/moodle
This commit is contained in:
commit
20a7746b1e
13 changed files with 617 additions and 23 deletions
|
@ -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?
|
||||
*
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
12
lib/tests/fixtures/testable_plugin_manager.php
vendored
12
lib/tests/fixtures/testable_plugin_manager.php
vendored
|
@ -109,4 +109,16 @@ class testable_core_plugin_manager extends core_plugin_manager {
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds fake plugin information from record.
|
||||
*
|
||||
* @param stdClass $record
|
||||
* @return void
|
||||
*/
|
||||
public function add_fake_plugin_info($record): void {
|
||||
$this->load_present_plugins();
|
||||
|
||||
$this->presentplugins[$record->type][$record->name] = $record;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,12 +41,6 @@ class testable_plugininfo_base extends \core\plugininfo\base {
|
|||
$this->displayname = 'Testable fake pluginfo instance';
|
||||
}
|
||||
|
||||
public function load_disk_version() {
|
||||
$this->versiondisk = null;
|
||||
$this->versionrequires = null;
|
||||
$this->dependencies = array();
|
||||
}
|
||||
|
||||
public function load_db_version() {
|
||||
$this->versiondb = null;
|
||||
}
|
||||
|
|
|
@ -458,6 +458,19 @@ class core_plugin_manager_testcase extends advanced_testcase {
|
|||
'testable_plugininfo_base', $pluginman);
|
||||
$pluginfo->versiondisk = null;
|
||||
$this->assertEmpty($pluginman->resolve_requirements($pluginfo, 2015110900, 30));
|
||||
|
||||
// Test plugin fails for incompatible version.
|
||||
$pluginfo = testable_plugininfo_base::fake_plugin_instance('fake', '/dev/null', 'two', '/dev/null/fake',
|
||||
'testable_plugininfo_base', $pluginman);
|
||||
$pluginfo->versiondisk = 2015060600;
|
||||
$pluginfo->pluginincompatible = 30;
|
||||
$reqs = $pluginman->resolve_requirements($pluginfo, 2015110900, 30);
|
||||
$this->assertEquals($pluginman::REQUIREMENT_STATUS_NEWER, $reqs['core']->status);
|
||||
|
||||
// Test no failure for no incompatible version.
|
||||
$pluginfo->pluginincompatible = 30;
|
||||
$reqs = $pluginman->resolve_requirements($pluginfo, 2015110900, 29);
|
||||
$this->assertEquals($pluginman::REQUIREMENT_STATUS_OK, $reqs['core']->status);
|
||||
}
|
||||
|
||||
public function test_missing_dependencies() {
|
||||
|
@ -486,4 +499,118 @@ class core_plugin_manager_testcase extends advanced_testcase {
|
|||
$this->assertInstanceOf('\core\update\remote_info', $misdeps['foo_bar']);
|
||||
$this->assertEquals(2015100500, $misdeps['foo_bar']->version->version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for check_explicitly_supported function to ensure that versions are correctly reported.
|
||||
*
|
||||
* @dataProvider check_explicitly_supported_provider
|
||||
* @param array|null $supported Supported versions to inject
|
||||
* @param string|int|null $incompatible Incompatible version to inject.
|
||||
* @param int $version Version to test
|
||||
* @param int $expected
|
||||
* @return void
|
||||
*/
|
||||
public function test_explicitly_supported($supported, $incompatible, $version, $expected): void {
|
||||
$pluginman = testable_core_plugin_manager::instance();
|
||||
|
||||
// Prepare a fake pluginfo instance.
|
||||
$plugininfo = new testable_plugininfo_base();
|
||||
$plugininfo->type = 'fake';
|
||||
$plugininfo->typerootdir = '/dev/null';
|
||||
$plugininfo->name = 'example';
|
||||
$plugininfo->rootdir = '/dev/null/fake';
|
||||
$plugininfo->pluginman = $pluginman;
|
||||
$plugininfo->versiondisk = 2015060600;
|
||||
$plugininfo->supported = $supported;
|
||||
$plugininfo->incompatible = $incompatible;
|
||||
|
||||
$pluginman->add_fake_plugin_info($plugininfo);
|
||||
|
||||
$plugininfo->load_disk_version();
|
||||
|
||||
$this->assertEquals($expected, $pluginman->check_explicitly_supported($plugininfo, $version));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for check_explicitly_supported with a range of correctly defined version support values.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function check_explicitly_supported_provider(): array {
|
||||
return [
|
||||
'Range, branch in support, lowest' => [
|
||||
'supported' => [29, 31],
|
||||
'incompatible' => null,
|
||||
'version' => 29,
|
||||
'expected' => core_plugin_manager::VERSION_SUPPORTED,
|
||||
],
|
||||
'Range, branch in support, mid' => [
|
||||
'supported' => [29, 31],
|
||||
'incompatible' => null,
|
||||
'version' => 30,
|
||||
'expected' => core_plugin_manager::VERSION_SUPPORTED,
|
||||
],
|
||||
'Range, branch in support, highest' => [
|
||||
'supported' => [29, 31],
|
||||
'incompatible' => null,
|
||||
'version' => 31,
|
||||
'expected' => core_plugin_manager::VERSION_SUPPORTED,
|
||||
],
|
||||
|
||||
'Range, branch not in support, high' => [
|
||||
'supported' => [29, 31],
|
||||
'incompatible' => null,
|
||||
'version' => 32,
|
||||
'expected' => core_plugin_manager::VERSION_NOT_SUPPORTED,
|
||||
],
|
||||
'Range, branch not in support, low' => [
|
||||
'supported' => [29, 31],
|
||||
'incompatible' => null,
|
||||
'version' => 28,
|
||||
'expected' => core_plugin_manager::VERSION_NOT_SUPPORTED,
|
||||
],
|
||||
'Range, incompatible, high.' => [
|
||||
'supported' => [29, 31],
|
||||
'incompatible' => 32,
|
||||
'version' => 33,
|
||||
'expected' => core_plugin_manager::VERSION_NOT_SUPPORTED,
|
||||
],
|
||||
'Range, incompatible, low.' => [
|
||||
'supported' => [29, 31],
|
||||
'incompatible' => 32,
|
||||
'version' => 31,
|
||||
'expected' => core_plugin_manager::VERSION_SUPPORTED,
|
||||
],
|
||||
'Range, incompatible, equal.' => [
|
||||
'supported' => [29, 31],
|
||||
'incompatible' => 32,
|
||||
'version' => 32,
|
||||
'expected' => core_plugin_manager::VERSION_NOT_SUPPORTED,
|
||||
],
|
||||
'No supports' => [
|
||||
'supported' => null,
|
||||
'incompatible' => null,
|
||||
'version' => 32,
|
||||
'expected' => core_plugin_manager::VERSION_NO_SUPPORTS,
|
||||
],
|
||||
'No supports, but incompatible, older' => [
|
||||
'supported' => null,
|
||||
'incompatible' => 30,
|
||||
'version' => 32,
|
||||
'expected' => core_plugin_manager::VERSION_NOT_SUPPORTED,
|
||||
],
|
||||
'No supports, but incompatible, equal' => [
|
||||
'supported' => null,
|
||||
'incompatible' => 32,
|
||||
'version' => 32,
|
||||
'expected' => core_plugin_manager::VERSION_NOT_SUPPORTED,
|
||||
],
|
||||
'No supports, but incompatible, newer' => [
|
||||
'supported' => null,
|
||||
'incompatible' => 34,
|
||||
'version' => 32,
|
||||
'expected' => core_plugin_manager::VERSION_NO_SUPPORTS,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
282
lib/tests/plugininfo/base_test.php
Normal file
282
lib/tests/plugininfo/base_test.php
Normal file
|
@ -0,0 +1,282 @@
|
|||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Unit tests for plugin base class.
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2019 Andrew Nicols
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
namespace core\plugininfo;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use core_plugin_manager;
|
||||
use testable_core_plugin_manager;
|
||||
use testable_plugininfo_base;
|
||||
|
||||
|
||||
/**
|
||||
* Tests of the basic API of the plugin manager.
|
||||
*/
|
||||
class base_testcase extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Setup to ensure that fixtures are loaded.
|
||||
*/
|
||||
public static function setUpBeforeClass(): void {
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot.'/lib/tests/fixtures/testable_plugin_manager.php');
|
||||
require_once($CFG->dirroot.'/lib/tests/fixtures/testable_plugininfo_base.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tear down the testable plugin manager singleton between tests.
|
||||
*/
|
||||
public function tearDown() {
|
||||
// The caches of the testable singleton must be reset explicitly. It is
|
||||
// safer to kill the whole testable singleton at the end of every test.
|
||||
testable_core_plugin_manager::reset_caches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the load_disk_version function to check that it handles a variety of invalid supported fields.
|
||||
*
|
||||
* @dataProvider load_disk_version_invalid_supported_version_provider
|
||||
* @param array|null $supported Supported versions to inject
|
||||
* @param string|int|null $incompatible Incompatible version to inject.
|
||||
* @param int $version Version to test
|
||||
*/
|
||||
public function test_load_disk_version_invalid_supported_version($supported, $incompatible, $version): void {
|
||||
$pluginman = testable_core_plugin_manager::instance();
|
||||
|
||||
// Prepare a fake plugininfo instance.
|
||||
$plugininfo = new testable_plugininfo_base();
|
||||
$plugininfo->type = 'fake';
|
||||
$plugininfo->typerootdir = '/dev/null';
|
||||
$plugininfo->name = 'example';
|
||||
$plugininfo->rootdir = '/dev/null/fake';
|
||||
$plugininfo->pluginman = $pluginman;
|
||||
$plugininfo->versiondisk = 2015060600;
|
||||
$plugininfo->supported = $supported;
|
||||
$plugininfo->incompatible = $incompatible;
|
||||
|
||||
$pluginman->add_fake_plugin_info($plugininfo);
|
||||
|
||||
$this->expectException(\coding_exception::class);
|
||||
$this->expectExceptionMessage('Incorrect syntax in $plugin->supported in example');
|
||||
$plugininfo->load_disk_version();
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for the load_disk_version tests for testing with invalid supported fields.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function load_disk_version_invalid_supported_version_provider(): array {
|
||||
return [
|
||||
'Invalid supported range.' => [
|
||||
'supported' => [31, 29],
|
||||
'incompatible' => null,
|
||||
'version' => 32,
|
||||
],
|
||||
'Explicit list, low' => [
|
||||
'supported' => [29, 30, 31, 32],
|
||||
'incompatible' => null,
|
||||
'version' => 28,
|
||||
],
|
||||
'Explicit list, high' => [
|
||||
'supported' => [29, 30, 31, 32],
|
||||
'incompatible' => null,
|
||||
'version' => 33,
|
||||
],
|
||||
'Explicit list, in list' => [
|
||||
'supported' => [29, 30, 31, 32, 33],
|
||||
'incompatible' => null,
|
||||
'version' => 31,
|
||||
],
|
||||
'Explicit list, missing value, unsupported' => [
|
||||
'supported' => [29, 30, 32],
|
||||
'incompatible' => null,
|
||||
'version' => 31,
|
||||
],
|
||||
'Explicit list, missing value, supported' => [
|
||||
'supported' => [29, 30, 32],
|
||||
'incompatible' => null,
|
||||
'version' => 30,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the load_disk_version function to check that it handles a variety of invalid incompatible fields.
|
||||
*
|
||||
* @dataProvider load_disk_version_invalid_incompatible_version_provider
|
||||
* @param mixed $incompatible
|
||||
*/
|
||||
public function test_load_disk_version_invalid_incompatible_version($incompatible): void {
|
||||
$pluginman = testable_core_plugin_manager::instance();
|
||||
|
||||
// Prepare a fake plugininfo instance.
|
||||
$plugininfo = new testable_plugininfo_base();
|
||||
$plugininfo->type = 'fake';
|
||||
$plugininfo->typerootdir = '/dev/null';
|
||||
$plugininfo->name = 'example';
|
||||
$plugininfo->rootdir = '/dev/null/fake';
|
||||
$plugininfo->pluginman = $pluginman;
|
||||
$plugininfo->versiondisk = 2015060600;
|
||||
$plugininfo->incompatible = $incompatible;
|
||||
|
||||
$pluginman->add_fake_plugin_info($plugininfo);
|
||||
|
||||
$this->expectException(\coding_exception::class);
|
||||
$this->expectExceptionMessage('Incorrect syntax in $plugin->incompatible in example');
|
||||
$plugininfo->load_disk_version();
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for the load_disk_version tests for testing with invalid incompatible fields.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function load_disk_version_invalid_incompatible_version_provider(): array {
|
||||
return [
|
||||
[[38]],
|
||||
[['38']],
|
||||
[3.8],
|
||||
['3.8'],
|
||||
[''],
|
||||
['somestring'],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the load_disk_version function to check that it handles a range of correct supported and incompatible field
|
||||
* definitions.
|
||||
*
|
||||
* @dataProvider test_load_disk_version_branch_supports_provider
|
||||
* @param array|null $supported Supported versions to inject
|
||||
* @param string|int|null $incompatible Incompatible version to inject.
|
||||
* @param int $version Version to test
|
||||
*/
|
||||
public function test_load_disk_version_branch_supports($supported, $incompatible, $version): void {
|
||||
$pluginman = testable_core_plugin_manager::instance();
|
||||
|
||||
// Prepare a fake plugininfo instance.
|
||||
$plugininfo = new testable_plugininfo_base();
|
||||
$plugininfo->type = 'fake';
|
||||
$plugininfo->typerootdir = '/dev/null';
|
||||
$plugininfo->name = 'example';
|
||||
$plugininfo->rootdir = '/dev/null/fake';
|
||||
$plugininfo->pluginman = $pluginman;
|
||||
$plugininfo->versiondisk = 2015060600;
|
||||
$plugininfo->supported = $supported;
|
||||
$plugininfo->incompatible = $incompatible;
|
||||
|
||||
$pluginman->add_fake_plugin_info($plugininfo);
|
||||
|
||||
$plugininfo->load_disk_version();
|
||||
|
||||
$this->assertEquals($supported, $plugininfo->supported);
|
||||
$this->assertEquals($incompatible, $plugininfo->incompatible);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test cases for tests of load_disk_version for testing the supported/incompatible fields.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function test_load_disk_version_branch_supports_provider(): array {
|
||||
return [
|
||||
'Range, branch in support, lowest' => [
|
||||
'supported' => [29, 31],
|
||||
'incompatible' => null,
|
||||
'version' => 29,
|
||||
],
|
||||
'Range, branch in support, mid' => [
|
||||
'supported' => [29, 31],
|
||||
'incompatible' => null,
|
||||
'version' => 30,
|
||||
],
|
||||
'Range, branch in support, highest' => [
|
||||
'supported' => [29, 31],
|
||||
'incompatible' => null,
|
||||
'version' => 31,
|
||||
],
|
||||
|
||||
'Range, branch not in support, high' => [
|
||||
'supported' => [29, 31],
|
||||
'incompatible' => null,
|
||||
'version' => 32,
|
||||
],
|
||||
'Range, branch not in support, low' => [
|
||||
'supported' => [29, 31],
|
||||
'incompatible' => null,
|
||||
'version' => 28,
|
||||
],
|
||||
'Range, incompatible, high.' => [
|
||||
'supported' => [29, 31],
|
||||
'incompatible' => 32,
|
||||
'version' => 33,
|
||||
],
|
||||
'Range, incompatible, low.' => [
|
||||
'supported' => [29, 31],
|
||||
'incompatible' => 32,
|
||||
'version' => 31,
|
||||
],
|
||||
'Range, incompatible, equal.' => [
|
||||
'supported' => [29, 31],
|
||||
'incompatible' => 32,
|
||||
'version' => 32,
|
||||
],
|
||||
'No supports' => [
|
||||
'supported' => null,
|
||||
'incompatible' => null,
|
||||
'version' => 32,
|
||||
],
|
||||
'No supports, but incompatible, older' => [
|
||||
'supported' => null,
|
||||
'incompatible' => 30,
|
||||
'version' => 32,
|
||||
],
|
||||
'No supports, but incompatible, equal' => [
|
||||
'supported' => null,
|
||||
'incompatible' => 32,
|
||||
'version' => 32,
|
||||
],
|
||||
'No supports, but incompatible, newer' => [
|
||||
'supported' => null,
|
||||
'incompatible' => 34,
|
||||
'version' => 32,
|
||||
],
|
||||
'String incompatible' => [
|
||||
'supported' => null,
|
||||
'incompatible' => '34',
|
||||
'version' => 32,
|
||||
],
|
||||
'Empty incompatible' => [
|
||||
'supported' => null,
|
||||
'incompatible' => null,
|
||||
'version' => 32,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -12,6 +12,13 @@ information provided here is intended especially for developers.
|
|||
* plagiarism_save_form_elements() has been deprecated. Please use {plugin name}_coursemodule_edit_post_actions() instead.
|
||||
* plagiarism_get_form_elements_module() has been deprecated. Please use {plugin name}_coursemodule_standard_elements() instead.
|
||||
* Changed default sessiontimeout to 8 hours to cover most normal working days
|
||||
* Plugins can now explicitly declare supported and incompatible Moodle versions in version.php
|
||||
- $plugin->supported = [37,39];
|
||||
supported takes an array of ascending numbers, that correspond to a range of branch numbers of supported versions, inclusive.
|
||||
Moodle versions that are outside of this range will produce a message notifying at install time, but will allow for installation.
|
||||
- $plugin->incompatible = 36;
|
||||
incompatible takes a single int corresponding to the first incompatible branch. Any Moodle versions including and
|
||||
above this will be prevented from installing the plugin, and a message will be given when attempting installation.
|
||||
|
||||
=== 3.8 ===
|
||||
* Add CLI option to notify all cron tasks to stop: admin/cli/cron.php --stop
|
||||
|
|
|
@ -84,6 +84,32 @@ class upgrade_requires_exception extends moodle_exception {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception thrown when attempting to install a plugin that declares incompatibility with moodle version
|
||||
*
|
||||
* @package core
|
||||
* @subpackage upgrade
|
||||
* @copyright 2019 Peter Burnett <peterburnett@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class plugin_incompatible_exception extends moodle_exception {
|
||||
/**
|
||||
* Constructor function for exception
|
||||
*
|
||||
* @param \core\plugininfo\base $plugin The plugin causing the exception
|
||||
* @param int $pluginversion The version of the plugin causing the exception
|
||||
*/
|
||||
public function __construct($plugin, $pluginversion) {
|
||||
global $CFG;
|
||||
$a = new stdClass();
|
||||
$a->pluginname = $plugin;
|
||||
$a->pluginversion = $pluginversion;
|
||||
$a->moodleversion = $CFG->branch;
|
||||
|
||||
parent::__construct('pluginunsupported', 'error', "$CFG->wwwroot/$CFG->admin/index.php", $a);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @package core
|
||||
* @subpackage upgrade
|
||||
|
@ -579,6 +605,13 @@ function upgrade_plugins($type, $startcallback, $endcallback, $verbose) {
|
|||
}
|
||||
}
|
||||
|
||||
// Throw exception if plugin is incompatible with moodle version.
|
||||
if (!empty($plugin->incompatible)) {
|
||||
if ($CFG->branch <= $plugin->incompatible) {
|
||||
throw new plugin_incompatible_exception($component, $plugin->version);
|
||||
}
|
||||
}
|
||||
|
||||
// try to recover from interrupted install.php if needed
|
||||
if (file_exists($fullplug.'/db/install.php')) {
|
||||
if (get_config($plugin->fullname, 'installrunning')) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue