Skip to content

Commit

Permalink
MDL-49329 admin: Add ability to cancel upgrade of the plugin
Browse files Browse the repository at this point in the history
If there is an available archived zip with the version of the plugin
currently installed, we can use it to cancel/abort the upgrade of the
plugin. This is internally handled as the installation of the archived
zip and goes through all the validation and confirmation.

Additionally, some other parts were improved. Most notably, renderer no
longer decides itself if some installation can be cancelled but it
always asks the controller (plugin manager).

The button for installation was moved to the left so there should be
first buttons to add things, and then buttons to cancel things (which is
common in normal forms).
  • Loading branch information
mudrd8mz committed Oct 9, 2015
1 parent 80c3c65 commit c20e9ae
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 76 deletions.
141 changes: 110 additions & 31 deletions admin/index.php
Expand Up @@ -112,6 +112,9 @@
$abortinstall = optional_param('abortinstall', null, PARAM_COMPONENT); // Cancel installation of the given new plugin.
$abortinstallx = optional_param('abortinstallx', null, PARAM_BOOL); // Cancel installation of all new plugins.
$confirmabortinstall = optional_param('confirmabortinstall', false, PARAM_BOOL); // Installation cancel confirmed.
$abortupgrade = optional_param('abortupgrade', null, PARAM_COMPONENT); // Cancel upgrade of the given existing plugin.
$abortupgradex = optional_param('abortupgradex', null, PARAM_BOOL); // Cancel upgrade of all upgradable plugins.
$confirmabortupgrade = optional_param('confirmabortupgrade', false, PARAM_BOOL); // Upgrade cancel confirmed.
$installupdate = optional_param('installupdate', null, PARAM_COMPONENT); // Install given available update.
$installupdateversion = optional_param('installupdateversion', null, PARAM_INT); // Version of the available update to install.
$installupdatex = optional_param('installupdatex', false, PARAM_BOOL); // Install all available plugin updates.
Expand Down Expand Up @@ -352,17 +355,33 @@

$pluginman = core_plugin_manager::instance();

// Check for available updates.
if ($fetchupdates) {
// No sesskey support guaranteed here, because sessions might not work yet.
$updateschecker = \core\update\checker::instance();
if ($updateschecker->enabled()) {
$updateschecker->fetch();
}
redirect($PAGE->url);
}

// Cancel all plugin installations.
if ($abortinstallx) {
// No sesskey support guaranteed here, because sessions might not work yet.
if ($confirmabortinstall) {
$pluginman->cancel_all_plugin_installations();
redirect($PAGE->url);
} else {
$continue = new moodle_url($PAGE->url, array('abortinstallx' => $abortinstallx, 'confirmabortinstall' => 1));
echo $output->upgrade_confirm_abort_install_page(true, $continue);
die();
$abortables = $pluginman->list_cancellable_installations();
if ($abortables) {
if ($confirmabortinstall) {
foreach ($abortables as $plugin) {
$pluginman->cancel_plugin_installation($plugin->component);
}
redirect($PAGE->url);
} else {
$continue = new moodle_url($PAGE->url, array('abortinstallx' => $abortinstallx, 'confirmabortinstall' => 1));
echo $output->upgrade_confirm_abort_install_page($abortables, $continue);
die();
}
}
redirect($PAGE->url);
}

// Cancel single plugin installation.
Expand All @@ -373,9 +392,40 @@
redirect($PAGE->url);
} else {
$continue = new moodle_url($PAGE->url, array('abortinstall' => $abortinstall, 'confirmabortinstall' => 1));
echo $output->upgrade_confirm_abort_install_page($abortinstall, $continue);
die();
$abortable = $pluginman->get_plugin_info($abortinstall);
if ($pluginman->can_cancel_plugin_installation($abortable)) {
echo $output->upgrade_confirm_abort_install_page(array($abortable), $continue);
die();
}
redirect($PAGE->url);
}
}

// Cancel all plugins upgrades (that is, restore archived versions).
if ($abortupgradex) {
// No sesskey support guaranteed here, because sessions might not work yet.
$restorable = $pluginman->list_restorable_archives();
if ($restorable) {
upgrade_install_plugins($restorable, $confirmabortupgrade,
get_string('cancelupgradehead', 'core_plugin'),
new moodle_url($PAGE->url, array('abortupgradex' => 1, 'confirmabortupgrade' => 1))
);
}
redirect($PAGE->url);
}

// Cancel single plugin upgrade (that is, install the archived version).
if ($abortupgrade) {
// No sesskey support guaranteed here, because sessions might not work yet.
$restorable = $pluginman->list_restorable_archives();
if (isset($restorable[$abortupgrade])) {
$restorable = array($restorable[$abortupgrade]);
upgrade_install_plugins($restorable, $confirmabortupgrade,
get_string('cancelupgradehead', 'core_plugin'),
new moodle_url($PAGE->url, array('abortupgrade' => $abortupgrade, 'confirmabortupgrade' => 1))
);
}
redirect($PAGE->url);
}

// Install all available missing dependencies.
Expand Down Expand Up @@ -425,15 +475,6 @@
}
}

if ($fetchupdates) {
// No sesskey support guaranteed here, because sessions might not work yet.
$updateschecker = \core\update\checker::instance();
if ($updateschecker->enabled()) {
$updateschecker->fetch();
}
redirect($PAGE->url);
}

echo $output->upgrade_plugin_check_page(core_plugin_manager::instance(), \core\update\checker::instance(),
$version, $showallplugins, $PAGE->url, new moodle_url($PAGE->url, array('confirmplugincheck' => 1)));
die();
Expand Down Expand Up @@ -487,17 +528,33 @@
$PAGE->set_heading($strplugincheck);
$PAGE->set_cacheable(false);

// Check for available updates.
if ($fetchupdates) {
require_sesskey();
$updateschecker = \core\update\checker::instance();
if ($updateschecker->enabled()) {
$updateschecker->fetch();
}
redirect($PAGE->url);
}

// Cancel all plugin installations.
if ($abortinstallx) {
require_sesskey();
if ($confirmabortinstall) {
$pluginman->cancel_all_plugin_installations();
redirect($PAGE->url);
} else {
$continue = new moodle_url($PAGE->url, array('abortinstallx' => $abortinstallx, 'confirmabortinstall' => 1));
echo $output->upgrade_confirm_abort_install_page(true, $continue);
die();
$abortables = $pluginman->list_cancellable_installations();
if ($abortables) {
if ($confirmabortinstall) {
foreach ($abortables as $plugin) {
$pluginman->cancel_plugin_installation($plugin->component);
}
redirect($PAGE->url);
} else {
$continue = new moodle_url($PAGE->url, array('abortinstallx' => $abortinstallx, 'confirmabortinstall' => 1));
echo $output->upgrade_confirm_abort_install_page($abortables, $continue);
die();
}
}
redirect($PAGE->url);
}

// Cancel single plugin installation.
Expand All @@ -508,16 +565,38 @@
redirect($PAGE->url);
} else {
$continue = new moodle_url($PAGE->url, array('abortinstall' => $abortinstall, 'confirmabortinstall' => 1));
echo $output->upgrade_confirm_abort_install_page($abortinstall, $continue);
die();
$abortable = $pluginman->get_plugin_info($abortinstall);
if ($pluginman->can_cancel_plugin_installation($abortable)) {
echo $output->upgrade_confirm_abort_install_page(array($abortable), $continue);
die();
}
redirect($PAGE->url);
}
}

if ($fetchupdates) {
// Cancel all plugins upgrades (that is, restore archived versions).
if ($abortupgradex) {
require_sesskey();
$updateschecker = \core\update\checker::instance();
if ($updateschecker->enabled()) {
$updateschecker->fetch();
$restorable = $pluginman->list_restorable_archives();
if ($restorable) {
upgrade_install_plugins($restorable, $confirmabortupgrade,
get_string('cancelupgradehead', 'core_plugin'),
new moodle_url($PAGE->url, array('abortupgradex' => 1, 'confirmabortupgrade' => 1))
);
}
redirect($PAGE->url);
}

// Cancel single plugin upgrade (that is, install the archived version).
if ($abortupgrade) {
require_sesskey();
$restorable = $pluginman->list_restorable_archives();
if (isset($restorable[$abortupgrade])) {
$restorable = array($restorable[$abortupgrade]);
upgrade_install_plugins($restorable, $confirmabortupgrade,
get_string('cancelupgradehead', 'core_plugin'),
new moodle_url($PAGE->url, array('abortupgrade' => $abortupgrade, 'confirmabortupgrade' => 1))
);
}
redirect($PAGE->url);
}
Expand Down
74 changes: 37 additions & 37 deletions admin/renderer.php
Expand Up @@ -231,30 +231,13 @@ public function upgrade_plugin_check_page(core_plugin_manager $pluginman, \core\
/**
* Display a page to confirm plugin installation cancelation.
*
* @param bool|string $plugin true if cancelling all, component name otherwsie
* @param array $abortable list of \core\update\plugininfo
* @param moodle_url $continue
* @return string
*/
public function upgrade_confirm_abort_install_page($plugin, moodle_url $continue) {
public function upgrade_confirm_abort_install_page(array $abortable, moodle_url $continue) {

$pluginman = core_plugin_manager::instance();
$abortable = array();

if ($plugin === true) {
foreach ($pluginman->get_plugins() as $type => $pluginfos) {
foreach ($pluginfos as $pluginfo) {
if ($pluginman->can_cancel_plugin_installation($pluginfo)) {
$abortable[] = $pluginfo;
}
}
}

} else {
$pluginfo = $pluginman->get_plugin_info($plugin);
if ($pluginman->can_cancel_plugin_installation($pluginfo)) {
$abortable[] = $pluginfo;
}
}

if (empty($abortable)) {
// The UI should not allow this.
Expand Down Expand Up @@ -885,7 +868,9 @@ public function plugins_check_table(core_plugin_manager $pluginman, $version, ar
// Number of plugins requiring attention.
$sumattention = 0;
// List of all components we can cancel installation of.
$installabortable = array();
$installabortable = $pluginman->list_cancellable_installations();
// List of all components we can cancel upgrade of.
$upgradeabortable = $pluginman->list_restorable_archives();

foreach ($plugininfo as $type => $plugins) {

Expand Down Expand Up @@ -963,16 +948,22 @@ public function plugins_check_table(core_plugin_manager $pluginman, $version, ar
}
$status = html_writer::span(get_string('status_' . $statuscode, 'core_plugin'), $statusclass);

if ($statuscode == core_plugin_manager::PLUGIN_STATUS_NEW and !$plugin->is_standard()) {
if ($pluginman->is_plugin_folder_removable($plugin->component)) {
$installabortable[] = $plugin->component;
$status .= $this->output->single_button(
new moodle_url($this->page->url, array('abortinstall' => $plugin->component)),
get_string('cancelinstallone', 'core_plugin'),
'post',
array('class' => 'actionbutton')
);
}
if (!empty($installabortable[$plugin->component])) {
$status .= $this->output->single_button(
new moodle_url($this->page->url, array('abortinstall' => $plugin->component)),
get_string('cancelinstallone', 'core_plugin'),
'post',
array('class' => 'actionbutton cancelinstallone')
);
}

if (!empty($upgradeabortable[$plugin->component])) {
$status .= $this->output->single_button(
new moodle_url($this->page->url, array('abortupgrade' => $plugin->component)),
get_string('cancelupgradeone', 'core_plugin'),
'post',
array('class' => 'actionbutton cancelupgradeone')
);
}

$availableupdates = $plugin->available_updates();
Expand Down Expand Up @@ -1042,6 +1033,17 @@ public function plugins_check_table(core_plugin_manager $pluginman, $version, ar
}

$out .= $this->output->container_start('actions');

$installableupdates = $pluginman->filter_installable($pluginman->available_updates());
if ($installableupdates) {
$out .= $this->output->single_button(
new moodle_url($this->page->url, array('installupdatex' => 1)),
get_string('updateavailableinstallall', 'core_admin', count($installableupdates)),
'post',
array('class' => 'singlebutton updateavailableinstallall')
);
}

if ($installabortable) {
$out .= $this->output->single_button(
new moodle_url($this->page->url, array('abortinstallx' => 1)),
Expand All @@ -1051,13 +1053,12 @@ public function plugins_check_table(core_plugin_manager $pluginman, $version, ar
);
}

$installableupdates = $pluginman->filter_installable($pluginman->available_updates());
if ($installableupdates) {
if ($upgradeabortable) {
$out .= $this->output->single_button(
new moodle_url($this->page->url, array('installupdatex' => 1)),
get_string('updateavailableinstallall', 'core_admin', count($installableupdates)),
new moodle_url($this->page->url, array('abortupgradex' => 1)),
get_string('cancelupgradeall', 'core_plugin', count($upgradeabortable)),
'post',
array('class' => 'singlebutton updateavailableinstallall')
array('class' => 'singlebutton cancelupgradeall')
);
}

Expand Down Expand Up @@ -1175,7 +1176,7 @@ protected function missing_dependencies(core_plugin_manager $pluginman) {
);
}

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

$out .= $this->output->container_end(); // .plugins-check-dependencies-actions
Expand Down Expand Up @@ -1622,7 +1623,6 @@ public function plugins_control_panel(core_plugin_manager $pluginman, array $opt

if ($plugin->is_standard()) {
$row->attributes['class'] .= ' standard';
//$source = html_writer::div(get_string('sourcestd', 'core_plugin'), 'source label');
$source = '';
} else {
$row->attributes['class'] .= ' extension';
Expand Down
2 changes: 1 addition & 1 deletion lang/en/admin.php
Expand Up @@ -1083,7 +1083,7 @@
$string['updateavailable_moreinfo'] = 'More info...';
$string['updateavailable_release'] = 'Moodle {$a}';
$string['updateavailable_version'] = 'Version {$a}';
$string['updateavailableinstall'] = 'Install';
$string['updateavailableinstall'] = 'Install this update';
$string['updateavailableinstallall'] = 'Install available updates ({$a})';
$string['updateavailableinstallallhead'] = 'Installing available updates';
$string['updateavailablenot'] = 'Your Moodle code is up-to-date!';
Expand Down
5 changes: 4 additions & 1 deletion lang/en/plugin.php
Expand Up @@ -28,10 +28,13 @@
$string['actions'] = 'Actions';
$string['availability'] = 'Availability';
$string['cancelinstallall'] = 'Cancel new installations ({$a})';
$string['cancelinstallone'] = 'Cancel installation';
$string['cancelinstallone'] = 'Cancel this installation';
$string['cancelinstallhead'] = 'Cancelling installation of plugins';
$string['cancelinstallinfo'] = 'Following plugins are not fully installed yet and their installation can be cancelled. To do so, the plugin folder must be removed from your server now. Make sure that is really what you want to prevent accidental data loss (such as your own code modifications).';
$string['cancelinstallinfodir'] = 'Folder to be deleted: {$a}';
$string['cancelupgradeall'] = 'Cancel upgrades ({$a})';
$string['cancelupgradehead'] = 'Restoring previous version of plugins';
$string['cancelupgradeone'] = 'Cancel this upgrade';
$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}"';
Expand Down

0 comments on commit c20e9ae

Please sign in to comment.