MDL-49329 admin: Move requirements resolving to the plugin manager
authorDavid Mudrák <david@moodle.com>
Sat, 26 Sep 2015 07:21:04 +0000 (09:21 +0200)
committerDavid Mudrák <david@moodle.com>
Thu, 8 Oct 2015 21:32:02 +0000 (23:32 +0200)
The patch moves the resolving logic from the renderer (where it should
not really be) to the plugin manager (controller). This is needed
because we will need the very same logic to be used at other places.

admin/renderer.php
lib/classes/plugin_manager.php

index e203a4f..d135cfc 100644 (file)
@@ -1045,60 +1045,57 @@ class core_admin_renderer extends plugin_renderer_base {
      * @return string HTML code
      */
     protected function required_column(\core\plugininfo\base $plugin, core_plugin_manager $pluginman, $version) {
+
         $requires = array();
 
-        if (!empty($plugin->versionrequires)) {
-            if ($plugin->versionrequires <= $version) {
-                $class = 'requires-ok';
-                $label = '';
-            } else {
-                $class = 'requires-failed';
-                $label = html_writer::span(get_string('dependencyfails', 'core_plugin'), 'label label-important');
-            }
-            $requires[] = html_writer::tag('li',
-                html_writer::span(get_string('moodleversion', 'core_plugin', $plugin->versionrequires), 'dep dep-core').' '.$label,
-                array('class' => $class));
-        }
+        foreach ($pluginman->resolve_requirements($plugin, $version) as $reqname => $reqinfo) {
+            if ($reqname === 'core') {
+                if ($reqinfo->status == $pluginman::REQUIREMENT_STATUS_OK) {
+                    $class = 'requires-ok';
+                    $label = '';
+                } else {
+                    $class = 'requires-failed';
+                    $label = html_writer::span(get_string('dependencyfails', 'core_plugin'), 'label label-important');
+                }
+                $requires[] = html_writer::tag('li',
+                    html_writer::span(get_string('moodleversion', 'core_plugin', $plugin->versionrequires), 'dep dep-core').
+                    ' '.$label, array('class' => $class));
 
-        foreach ($plugin->get_other_required_plugins() as $component => $requiredversion) {
-            $otherplugin = $pluginman->get_plugin_info($component);
-            $actions = array();
-
-            if (is_null($otherplugin)) {
-                // The required plugin is not installed.
-                $label = html_writer::span(get_string('dependencyfails', 'core_plugin'), 'label label-important');
-                $class = 'requires-failed requires-missing';
-                $installurl = new moodle_url('https://moodle.org/plugins/view.php', array('plugin' => $component));
-                $uploadurl = new moodle_url('/admin/tool/installaddon/');
-                $actions[] = html_writer::link($installurl, get_string('dependencyinstall', 'core_plugin'));
-                $actions[] = html_writer::link($uploadurl, get_string('dependencyupload', 'core_plugin'));
-
-            } else if ($requiredversion != ANY_VERSION and $otherplugin->versiondisk < $requiredversion) {
-                // The required plugin is installed but needs to be updated.
-                $label = html_writer::span(get_string('dependencyfails', 'core_plugin'), 'label label-important');
-                $class = 'requires-failed requires-outdated';
-                if (!$otherplugin->is_standard()) {
+            } else {
+                $actions = array();
+
+                if ($reqinfo->status == $pluginman::REQUIREMENT_STATUS_OK) {
+                    $label = '';
+                    $class = 'requires-ok';
+
+                } else if ($reqinfo->status == $pluginman::REQUIREMENT_STATUS_MISSING) {
+                    $label = html_writer::span(get_string('dependencyfails', 'core_plugin'), 'label label-important');
+                    $class = 'requires-failed requires-missing';
+                    // TODO Display the install link only if really available there.
+                    $installurl = new moodle_url('https://moodle.org/plugins/view.php', array('plugin' => $reqname));
+                    $uploadurl = new moodle_url('/admin/tool/installaddon/');
+                    $actions[] = html_writer::link($installurl, get_string('dependencyinstall', 'core_plugin'));
+                    $actions[] = html_writer::link($uploadurl, get_string('dependencyupload', 'core_plugin'));
+
+                } else if ($reqinfo->status == $pluginman::REQUIREMENT_STATUS_OUTDATED) {
+                    $label = html_writer::span(get_string('dependencyfails', 'core_plugin'), 'label label-important');
+                    $class = 'requires-failed requires-outdated';
                     $updateurl = new moodle_url($this->page->url, array('sesskey' => sesskey(), 'fetchupdates' => 1));
                     $actions[] = html_writer::link($updateurl, get_string('checkforupdates', 'core_plugin'));
                 }
 
-            } else {
-                // Already installed plugin with sufficient version.
-                $label = '';
-                $class = 'requires-ok';
-            }
+                if ($reqinfo->reqver != ANY_VERSION) {
+                    $str = 'otherpluginversion';
+                } else {
+                    $str = 'otherplugin';
+                }
 
-            if ($requiredversion != ANY_VERSION) {
-                $str = 'otherpluginversion';
-            } else {
-                $str = 'otherplugin';
+                $requires[] = html_writer::tag('li', html_writer::span(
+                    get_string($str, 'core_plugin', array('component' => $reqname, 'version' => $reqinfo->reqver)),
+                    'dep dep-plugin').' '.$label.' '.html_writer::span(implode(' | ', $actions), 'actions'),
+                    array('class' => $class)
+                );
             }
-
-            $requires[] = html_writer::tag('li',
-                    html_writer::span(get_string($str, 'core_plugin',
-                            array('component' => $component, 'version' => $requiredversion)), 'dep dep-plugin').' '.$label.
-                    ' '.html_writer::span(implode(' | ', $actions), 'actions'),
-                    array('class' => $class));
         }
 
         if (!$requires) {
index 09096d8..57f0474 100644 (file)
@@ -53,6 +53,13 @@ class core_plugin_manager {
     /** the plugin is installed but missing from disk */
     const PLUGIN_STATUS_MISSING     = 'missing';
 
+    /** the given requirement/dependency is fulfilled */
+    const REQUIREMENT_STATUS_OK = 'ok';
+    /** the plugin requires higher core/other plugin version than is currently installed */
+    const REQUIREMENT_STATUS_OUTDATED = 'outdated';
+    /** the required dependency is not installed */
+    const REQUIREMENT_STATUS_MISSING = 'missing';
+
     /** @var core_plugin_manager holds the singleton instance */
     protected static $singletoninstance;
     /** @var array of raw plugins information */
@@ -750,6 +757,112 @@ class core_plugin_manager {
         return $return;
     }
 
+    /**
+     * Resolve requirements and dependencies of a plugin.
+     *
+     * Returns an array of objects describing the requirement/dependency,
+     * indexed by the frankenstyle name of the component. The returned array
+     * can be empty. The objects in the array have following properties:
+     *
+     *  ->(numeric)hasver
+     *  ->(numeric)reqver
+     *  ->(string)status
+     *
+     * @param \core\plugininfo\base $plugin the plugin we are checking
+     * @param null|string|int|double $moodleversion explicit moodle core version to check against, defaults to $CFG->version
+     * @param null|string|int $moodlebranch explicit moodle core branch to check against, defaults to $CFG->branch
+     * @return array of objects
+     */
+    public function resolve_requirements(\core\plugininfo\base $plugin, $moodleversion=null, $moodlebranch=null) {
+        global $CFG;
+
+        if ($moodleversion === null) {
+            $moodleversion = $CFG->version;
+        }
+
+        if ($moodlebranch === null) {
+            $moodlebranch = $CFG->branch;
+        }
+
+        $reqs = array();
+        $reqcore = $this->resolve_core_requirements($plugin, $moodleversion);
+
+        if (!empty($reqcore)) {
+            $reqs['core'] = $reqcore;
+        }
+
+        foreach ($plugin->get_other_required_plugins() as $reqplug => $reqver) {
+            $reqs[$reqplug] = $this->resolve_dependency_requirements($plugin, $reqplug, $reqver, $moodlebranch);
+        }
+
+        return $reqs;
+    }
+
+    /**
+     * Helper method to resolve plugin's requirements on the moodle core.
+     *
+     * @param \core\plugininfo\base $plugin the plugin we are checking
+     * @param string|int|double $moodleversion moodle core branch to check against
+     * @return stdObject
+     */
+    protected function resolve_core_requirements(\core\plugininfo\base $plugin, $moodleversion) {
+
+        $reqs = new stdClass();
+
+        $reqs->hasver = $moodleversion;
+
+        if (empty($plugin->versionrequires)) {
+            $reqs->reqver = ANY_VERSION;
+        } else {
+            $reqs->reqver = $plugin->versionrequires;
+        }
+
+        if ($plugin->is_core_dependency_satisfied($moodleversion)) {
+            $reqs->status = self::REQUIREMENT_STATUS_OK;
+        } else {
+            $reqs->status = self::REQUIREMENT_STATUS_OUTDATED;
+        }
+
+        return $reqs;
+    }
+
+    /**
+     * Helper method to resolve plugin's dependecies on other plugins.
+     *
+     * @param \core\plugininfo\base $plugin the plugin we are checking
+     * @param string $otherpluginname
+     * @param string|int $requiredversion
+     * @param string|int $moodlebranch explicit moodle core branch to check against, defaults to $CFG->branch
+     * @return stdClass
+     */
+    protected function resolve_dependency_requirements(\core\plugininfo\base $plugin, $otherpluginname,
+            $requiredversion, $moodlebranch) {
+
+        $reqs = new stdClass();
+        $otherplugin = $this->get_plugin_info($otherpluginname);
+
+        if ($otherplugin !== null) {
+            // The required plugin is installed.
+            $reqs->hasver = $otherplugin->versiondisk;
+            $reqs->reqver = $requiredversion;
+            // Check it has sufficient version.
+            if ($requiredversion == ANY_VERSION or $otherplugin->versiondisk >= $requiredversion) {
+                $reqs->status = self::REQUIREMENT_STATUS_OK;
+            } else {
+                $reqs->status = self::REQUIREMENT_STATUS_OUTDATED;
+            }
+
+        } else {
+            // The required plugin is not installed.
+            $reqs->hasver = null;
+            $reqs->reqver = $requiredversion;
+            $reqs->status = self::REQUIREMENT_STATUS_MISSING;
+            // TODO: Check if the $otherpluginname is available in the plugins directory.
+        }
+
+        return $reqs;
+    }
+
     /**
      * Is it possible to uninstall the given plugin?
      *