Skip to content

Commit

Permalink
MDL-49329 admin: Display missing dependencies on plugins check screen
Browse files Browse the repository at this point in the history
The patch improves the dependencies resolution in the plugin manager so
that the information about availability of the missing dependency is
included and can be displayed at the Plugins check screen during the
upgrade.
  • Loading branch information
mudrd8mz committed Oct 8, 2015
1 parent 4890032 commit 5a92cd0
Show file tree
Hide file tree
Showing 9 changed files with 542 additions and 24 deletions.
233 changes: 219 additions & 14 deletions admin/renderer.php
Expand Up @@ -207,7 +207,6 @@ public function upgrade_plugin_check_page(core_plugin_manager $pluginman, \core\

$output .= $this->header();
$output .= $this->box_start('generalbox');
$output .= $this->container_start('generalbox', 'notice');
$output .= html_writer::tag('p', get_string('pluginchecknotice', 'core_plugin'));
if ($checker->enabled()) {
$output .= $this->container_start('checkforupdates');
Expand All @@ -218,8 +217,8 @@ public function upgrade_plugin_check_page(core_plugin_manager $pluginman, \core\
}
$output .= $this->container_end();
}
$output .= $this->container_end();

$output .= $this->missing_dependencies($pluginman);
$output .= $this->plugins_check_table($pluginman, $version, array('full' => $showallplugins));
$output .= $this->box_end();
$output .= $this->upgrade_reload($reloadurl);
Expand Down Expand Up @@ -1037,6 +1036,168 @@ public function plugins_check_table(core_plugin_manager $pluginman, $version, ar
return $out;
}

/**
* Displays the information about missing dependencies
*
* @param core_plugin_manager $pluginman
* @return string
*/
protected function missing_dependencies(core_plugin_manager $pluginman) {

$dependencies = $pluginman->missing_dependencies();

if (empty($dependencies)) {
return '';
}

$available = array();
$unavailable = array();
$unknown = array();

foreach ($dependencies as $component => $remoteinfo) {
if ($remoteinfo === false) {
// The required version is not available. Let us check is there
// is at least some version in the plugins directory.
$remoteinfoanyversion = $pluginman->get_remote_plugin_info($component, ANY_VERSION);
if ($remoteinfoanyversion === false) {
$unknown[$component] = $component;
} else {
$unavailable[$component] = $remoteinfoanyversion;
}
} else {
$available[$component] = $remoteinfo;
}
}

$out = $this->output->container_start('plugins-check-dependencies');

if ($unavailable or $unknown) {
$out .= $this->output->heading(get_string('misdepsunavail', 'core_plugin'));
if ($unknown) {
$out .= $this->output->notification(get_string('misdepsunknownlist', 'core_plugin', implode($unknown, ', ')));
}
if ($unavailable) {
$unavailablelist = array();
foreach ($unavailable as $component => $remoteinfoanyversion) {
$unavailablelistitem = html_writer::link('https://moodle.org/plugins/view.php?plugin='.$component,
'<strong>'.$remoteinfoanyversion->name.'</strong>');
if ($remoteinfoanyversion->version) {
$unavailablelistitem .= ' ('.$component.' &gt; '.$remoteinfoanyversion->version->version.')';
} else {
$unavailablelistitem .= ' ('.$component.')';
}
$unavailablelist[] = $unavailablelistitem;
}
$out .= $this->output->notification(get_string('misdepsunavaillist', 'core_plugin',
implode($unavailablelist, ', ')));
}
$out .= $this->output->container_start('plugins-check-dependencies-actions');
$out .= ' '.html_writer::link(new moodle_url('/admin/tool/installaddon/'),
get_string('dependencyuploadmissing', 'core_plugin'));
$out .= $this->output->container_end(); // .plugins-check-dependencies-actions
}

if ($available) {
$out .= $this->output->heading(get_string('misdepsavail', 'core_plugin'));
$out .= $this->available_missing_dependencies_list($pluginman, $available);
$out .= $this->output->container_start('plugins-check-dependencies-actions');

// TODO implement the button functionality.
$out .= html_writer::link(
new moodle_url('/admin/tool/installaddon/'),
get_string('dependencyinstallmissing', 'core_plugin'),
array('class' => 'btn')
);
$out.= ' | '.html_writer::link(new moodle_url('/admin/tool/installaddon/'),
get_string('dependencyuploadmissing', 'core_plugin'));
$out .= $this->output->container_end(); // .plugins-check-dependencies-actions
}

$out .= $this->output->container_end(); // .plugins-check-dependencies

return $out;
}

/**
* Displays the list if available missing dependencies.
*
* @param core_plugin_manager $pluginman
* @param array $dependencies
* @return string
*/
protected function available_missing_dependencies_list(core_plugin_manager $pluginman, array $dependencies) {
global $CFG;

$table = new html_table();
$table->id = 'plugins-check-available-dependencies';
$table->head = array(
get_string('displayname', 'core_plugin'),
get_string('release', 'core_plugin'),
get_string('version', 'core_plugin'),
get_string('supportedmoodleversions', 'core_plugin'),
get_string('info', 'core'),
);
$table->colclasses = array('displayname', 'release', 'version', 'supportedmoodleversions', 'info');
$table->data = array();

foreach ($dependencies as $plugin) {

$supportedmoodles = array();
foreach ($plugin->version->supportedmoodles as $moodle) {
if ($CFG->branch == str_replace('.', '', $moodle->release)) {
$supportedmoodles[] = html_writer::span($moodle->release, 'label label-success');
} else {
$supportedmoodles[] = html_writer::span($moodle->release, 'label');
}
}

$requriedby = $pluginman->other_plugins_that_require($plugin->component);
if ($requriedby) {
foreach ($requriedby as $ix => $val) {
$inf = $pluginman->get_plugin_info($val);
if ($inf) {
$requriedby[$ix] = $inf->displayname.' ('.$inf->component.')';
}
}
$info = html_writer::div(
get_string('requiredby', 'core_plugin', implode(', ', $requriedby)),
'requiredby'
);
} else {
$info = '';
}

$info .= html_writer::span(
html_writer::link('https://moodle.org/plugins/view.php?plugin='.$plugin->component,
get_string('misdepinfoplugin', 'core_plugin')),
'misdepinfoplugin'
);

$info .= ' | '.html_writer::span(
html_writer::link('https://moodle.org/plugins/pluginversion.php?id='.$plugin->version->id,
get_string('misdepinfoversion', 'core_plugin')),
'misdepinfoversion'
);

$info .= ' | '.html_writer::link($plugin->version->downloadurl, get_string('download'),
array('class' => 'btn btn-small'));

// TODO Implement the button functionality.
$info .= ' | '.html_writer::link($plugin->version->downloadurl, get_string('dependencyinstall', 'core_plugin'),
array('class' => 'btn btn-small'));

$table->data[] = array(
html_writer::div($plugin->name, 'name').' '.html_writer::div($plugin->component, 'component'),
$plugin->version->release,
$plugin->version->version,
implode($supportedmoodles, ' '),
$info
);
}

return html_writer::table($table);
}

/**
* Formats the information that needs to go in the 'Requires' column.
* @param \core\plugininfo\base $plugin the plugin we are rendering the row for.
Expand All @@ -1047,6 +1208,8 @@ public function plugins_check_table(core_plugin_manager $pluginman, $version, ar
protected function required_column(\core\plugininfo\base $plugin, core_plugin_manager $pluginman, $version) {

$requires = array();
$displayuploadlink = false;
$displayupdateslink = false;

foreach ($pluginman->resolve_requirements($plugin, $version) as $reqname => $reqinfo) {
if ($reqname === 'core') {
Expand All @@ -1069,19 +1232,37 @@ protected function required_column(\core\plugininfo\base $plugin, core_plugin_ma
$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'));
if ($reqinfo->availability == $pluginman::REQUIREMENT_AVAILABLE) {
$label = html_writer::span(get_string('dependencymissing', 'core_plugin'), 'label label-warning');
$label .= ' '.html_writer::span(get_string('dependencyavailable', 'core_plugin'), 'label label-warning');
$class = 'requires-failed requires-missing requires-available';
$actions[] = html_writer::link(
new moodle_url('https://moodle.org/plugins/view.php', array('plugin' => $reqname)),
get_string('misdepinfoplugin', 'core_plugin')
);

} else {
$label = html_writer::span(get_string('dependencymissing', 'core_plugin'), 'label label-important');
$label .= ' '.html_writer::span(get_string('dependencyunavailable', 'core_plugin'),
'label label-important');
$class = 'requires-failed requires-missing requires-unavailable';
}
$displayuploadlink = true;

} 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'));
if ($reqinfo->availability == $pluginman::REQUIREMENT_AVAILABLE) {
$label = html_writer::span(get_string('dependencyfails', 'core_plugin'), 'label label-warning');
$label .= ' '.html_writer::span(get_string('dependencyavailable', 'core_plugin'), 'label label-warning');
$class = 'requires-failed requires-outdated requires-available';
$displayupdateslink = true;

} else {
$label = html_writer::span(get_string('dependencyfails', 'core_plugin'), 'label label-important');
$label .= ' '.html_writer::span(get_string('dependencyunavailable', 'core_plugin'),
'label label-important');
$class = 'requires-failed requires-outdated requires-unavailable';
}
$displayuploadlink = true;
}

if ($reqinfo->reqver != ANY_VERSION) {
Expand All @@ -1101,7 +1282,31 @@ protected function required_column(\core\plugininfo\base $plugin, core_plugin_ma
if (!$requires) {
return '';
}
return html_writer::tag('ul', implode("\n", $requires));

$out = html_writer::tag('ul', implode("\n", $requires));

if ($displayuploadlink) {
$out .= html_writer::div(
html_writer::link(
new moodle_url('/admin/tool/installaddon/'),
get_string('dependencyuploadmissing', 'core_plugin')
),
'dependencyuploadmissing'
);
}

if ($displayupdateslink) {
$out .= html_writer::div(
html_writer::link(
new moodle_url($this->page->url, array('sesskey' => sesskey(), 'fetchupdates' => 1)),
get_string('checkforupdates', 'core_plugin')
),
'checkforupdates'
);
}

return $out;

}

/**
Expand Down
12 changes: 12 additions & 0 deletions lang/en/plugin.php
Expand Up @@ -30,9 +30,14 @@
$string['checkforupdates'] = 'Check for available updates';
$string['checkforupdateslast'] = 'Last check done on {$a}';
$string['detectedmisplacedplugin'] = 'Plugin "{$a->component}" is installed in incorrect location "{$a->current}", expected location is "{$a->expected}"';
$string['dependencyavailable'] = 'Available';
$string['dependencyfails'] = 'Fails';
$string['dependencyinstall'] = 'Install';
$string['dependencyinstallmissing'] = 'Install all missing dependencies';
$string['dependencymissing'] = 'Missing';
$string['dependencyunavailable'] = 'Unavailable';
$string['dependencyupload'] = 'Upload';
$string['dependencyuploadmissing'] = 'Upload ZIP files';
$string['displayname'] = 'Plugin name';
$string['err_response_curl'] = 'Unable to fetch available updates data - unexpected cURL error.';
$string['err_response_format_version'] = 'Unexpected version of the response format. Please try to re-check for available updates.';
Expand All @@ -42,6 +47,12 @@
$string['filtercontribonlyactive'] = 'Showing additional plugins only';
$string['filterupdatesonly'] = 'Show updateable only';
$string['filterupdatesonlyactive'] = 'Showing updateable only';
$string['misdepinfoplugin'] = 'Plugin info';
$string['misdepinfoversion'] = 'Version info';
$string['misdepsavail'] = 'Available missing dependencies';
$string['misdepsunavail'] = 'Unavailable missing dependencies';
$string['misdepsunavaillist'] = 'No version found to fulfill the dependency requirements: {$a}.';
$string['misdepsunknownlist'] = 'Not in the Plugins directory: <strong>{$a}</strong>.';
$string['moodleversion'] = 'Moodle {$a}';
$string['nonehighlighted'] = 'No plugins require your attention now';
$string['nonehighlightedinfo'] = 'Display the list of all installed plugins anyway';
Expand Down Expand Up @@ -87,6 +98,7 @@
$string['status_nodb'] = 'No database';
$string['status_upgrade'] = 'To be upgraded';
$string['status_uptodate'] = 'Installed';
$string['supportedmoodleversions'] = 'Supported Moodle versions';
$string['systemname'] = 'Identifier';
$string['type_auth'] = 'Authentication method';
$string['type_auth_plural'] = 'Authentication methods';
Expand Down

0 comments on commit 5a92cd0

Please sign in to comment.