From 9f1c596dbd9dbf92155c25c8da139ab8c955f4fe Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Mon, 13 Feb 2023 14:45:40 +0800 Subject: [PATCH] MDL-76867 core_admin: Migrate module management table to dynamic table --- .../table/activity_management_table.php | 118 +++++++++++++++ admin/modules.php | 142 +++--------------- .../tests/behat/apply_presets.feature | 4 +- lang/en/admin.php | 2 + lib/tests/plugininfo/editor_test.php | 68 +++++++++ lib/tests/plugininfo/mod_test.php | 52 +++++++ 6 files changed, 265 insertions(+), 121 deletions(-) create mode 100644 admin/classes/table/activity_management_table.php create mode 100644 lib/tests/plugininfo/editor_test.php create mode 100644 lib/tests/plugininfo/mod_test.php diff --git a/admin/classes/table/activity_management_table.php b/admin/classes/table/activity_management_table.php new file mode 100644 index 00000000000..4ea65a73644 --- /dev/null +++ b/admin/classes/table/activity_management_table.php @@ -0,0 +1,118 @@ +. + +namespace core_admin\table; + +use core_plugin_manager; +use dml_exception; +use html_writer; +use moodle_url; +use stdClass; + +/** + * Activity Module admin settings. + * + * @package core_admin + * @copyright 2023 Andrew Lyons + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class activity_management_table extends plugin_management_table { + + public function setup() { + $this->set_attribute('id', 'modules'); + $this->set_attribute('class', 'admintable generaltable'); + parent::setup(); + } + + protected function get_table_id(): string { + return 'module-administration-table'; + } + + protected function get_plugintype(): string { + return 'mod'; + } + + public function guess_base_url(): void { + $this->define_baseurl( + new moodle_url('/admin/modules.php') + ); + } + + protected function get_action_url(array $params = []): moodle_url { + return new moodle_url('/admin/modules.php', $params); + } + + protected function get_column_list(): array { + $columns = parent::get_column_list(); + return array_merge( + array_slice($columns, 0, 1, true), + ['activities' => get_string('activities')], + array_slice($columns, 1, null, true), + ); + } + + protected function col_name(stdClass $row): string { + global $OUTPUT; + + $status = $row->plugininfo->get_status(); + if ($status === core_plugin_manager::PLUGIN_STATUS_MISSING) { + return html_writer::span( + get_string('missingfromdisk'), + 'notifyproblem' + ); + } + + return html_writer::span( + html_writer::img( + $OUTPUT->image_url('monologo', $row->plugininfo->name), + '', + [ + 'class' => 'icon', + ], + ) . get_string('modulename', $row->plugininfo->name) + ); + } + + /** + * Show the number of activities present, with a link to courses containing activity if relevant. + * + * @param mixed $row + * @return string + */ + protected function col_activities(stdClass $row): string { + global $DB, $OUTPUT; + try { + $count = $DB->count_records_select($row->plugininfo->name, "course <> 0"); + } catch (dml_exception $e) { + $count = -1; + } + + if ($count > 0) { + return $OUTPUT->action_link( + new moodle_url('/course/search.php', [ + 'modulelist' => $row->plugininfo->name, + ]), + $count, + null, + ['title' => get_string('showmodulecourse')] + ); + } else if ($count < 0) { + return get_string('error'); + } else { + return $count; + } + } +} diff --git a/admin/modules.php b/admin/modules.php index a8a04b365f2..4104b4b202c 100644 --- a/admin/modules.php +++ b/admin/modules.php @@ -31,133 +31,37 @@ define('MODULE_TABLE', 'module_administration_table'); admin_externalpage_setup('managemodules'); -$show = optional_param('show', '', PARAM_PLUGIN); -$hide = optional_param('hide', '', PARAM_PLUGIN); - -// Print headings. -$stractivities = get_string("activities"); -$struninstall = get_string('uninstallplugin', 'core_admin'); -$strversion = get_string("version"); -$strhide = get_string("hide"); -$strshow = get_string("show"); -$strsettings = get_string("settings"); -$stractivities = get_string("activities"); -$stractivitymodule = get_string("activitymodule"); -$strshowmodulecourse = get_string('showmodulecourse'); +$plugin = optional_param('plugin', '', PARAM_PLUGIN); +$action = optional_param('action', '', PARAM_ALPHA); // If data submitted, then process and store. -if (!empty($hide) && confirm_sesskey()) { - $class = \core_plugin_manager::resolve_plugininfo_class('mod'); - if ($class::enable_plugin($hide, false)) { - // Settings not required - only pages. - admin_get_root(true, false); - } - redirect(new moodle_url('/admin/modules.php')); -} +if (!empty($action) && !empty($plugin) && confirm_sesskey()) { + $manager = \core_plugin_manager::resolve_plugininfo_class('mod'); + $pluginname = get_string('pluginname', $plugin); + + if ($action === 'disable' && $manager::enable_plugin($plugin, 0)) { + \core\notification::add( + get_string('plugin_disabled', 'core_admin', $pluginname), + \core\notification::SUCCESS + ); + // Settings not required - only pages. + admin_get_root(true, false); + } else if ($action === 'enable' && $manager::enable_plugin($plugin, 1)) { + \core\notification::add( + get_string('plugin_enabled', 'core_admin', $pluginname), + \core\notification::SUCCESS + ); -if (!empty($show) && confirm_sesskey()) { - $class = \core_plugin_manager::resolve_plugininfo_class('mod'); - if ($class::enable_plugin($show, true)) { // Settings not required - only pages. admin_get_root(true, false); } + + // Redirect back to the modules page with out any params. redirect(new moodle_url('/admin/modules.php')); } echo $OUTPUT->header(); -echo $OUTPUT->heading($stractivities); - -// Get and sort the existing modules. -if (!$modules = $DB->get_records('modules', [], 'name ASC')) { - throw new \moodle_exception('moduledoesnotexist', 'error'); -} - -// Print the table of all modules. -// Construct the flexible table ready to display. -$table = new flexible_table(MODULE_TABLE); -$table->define_columns(['name', 'instances', 'version', 'hideshow', 'uninstall', 'settings']); -$table->define_headers([$stractivitymodule, $stractivities, $strversion, "$strhide/$strshow", $strsettings, $struninstall]); -$table->define_baseurl($CFG->wwwroot . '/' . $CFG->admin . '/modules.php'); -$table->set_attribute('id', 'modules'); -$table->set_attribute('class', 'admintable generaltable'); -$table->setup(); - -$pluginmanager = core_plugin_manager::instance(); - -foreach ($modules as $module) { - $plugininfo = $pluginmanager->get_plugin_info('mod_' . $module->name); - $status = $plugininfo->get_status(); - - if ($status === core_plugin_manager::PLUGIN_STATUS_MISSING) { - $strmodulename = '' . $module->name . ' (' . get_string('missingfromdisk') . ')'; - $missing = true; - } else { - $icon = "image_url('monologo', $module->name) . "\" class=\"icon\" alt=\"\" />"; - $strmodulename = $icon . ' ' . get_string('modulename', $module->name); - $missing = false; - } - - $uninstall = ''; - if ($uninstallurl = core_plugin_manager::instance()->get_uninstall_url('mod_' . $module->name, 'manage')) { - $uninstall = html_writer::link($uninstallurl, $struninstall); - } - - if ( - file_exists("$CFG->dirroot/mod/$module->name/settings.php") || - file_exists("$CFG->dirroot/mod/$module->name/settingstree.php") - ) { - $settings = "name\">$strsettings"; - } else { - $settings = ""; - } - - try { - $count = $DB->count_records_select($module->name, "course<>0"); - } catch (dml_exception $e) { - $count = -1; - } - if ($count > 0) { - $countlink = $OUTPUT->action_link( - new moodle_url('/course/search.php', ['modulelist' => $module->name]), - $count, - null, - ['title' => $strshowmodulecourse] - ); - } else if ($count < 0) { - $countlink = get_string('error'); - } else { - $countlink = "$count"; - } - - if ($missing) { - $visible = ''; - $class = ''; - } else if ($module->visible) { - $visible = "name&sesskey=" . sesskey() . "\" title=\"$strhide\">" . - $OUTPUT->pix_icon('t/hide', $strhide) . ''; - $class = ''; - } else { - $visible = "name&sesskey=" . sesskey() . "\" title=\"$strshow\">" . - $OUTPUT->pix_icon('t/show', $strshow) . ''; - $class = 'dimmed_text'; - } - if ($module->name == "forum") { - $uninstall = ""; - $visible = ""; - $class = ""; - } - $version = get_config('mod_' . $module->name, 'version'); - - $table->add_data([ - $strmodulename, - $countlink, - $version, - $visible, - $settings, - $uninstall, - ], $class); -} - -$table->finish_html(); - +echo $OUTPUT->heading(get_string("activities")); +$table = new \core_admin\table\activity_management_table(); +$table->out(); echo $OUTPUT->footer(); diff --git a/admin/tool/admin_presets/tests/behat/apply_presets.feature b/admin/tool/admin_presets/tests/behat/apply_presets.feature index 163ccc942ae..1372e6b32c2 100644 --- a/admin/tool/admin_presets/tests/behat/apply_presets.feature +++ b/admin/tool/admin_presets/tests/behat/apply_presets.feature @@ -14,7 +14,7 @@ Feature: I can apply presets Scenario: Applying Starter Moodle preset changes status and settings # Checking the settings before applying Full Moodle preset (we're only testing one of each type). Given I navigate to "Plugins > Activity modules > Manage activities" in site administration - And "Hide" "icon" should exist in the "Chat" "table_row" + And "Disable the Chat plugin" "icon" should exist in the "Chat" "table_row" And I navigate to "Plugins > Availability restrictions > Manage restrictions" in site administration And "Hide" "icon" should exist in the "Restriction by grouping" "table_row" And I navigate to "Plugins > Blocks > Manage blocks" in site administration @@ -109,7 +109,7 @@ Feature: I can apply presets And the field "Enable badges" matches value "0" And the field "Enable competencies" matches value "0" And I navigate to "Plugins > Activity modules > Manage activities" in site administration - And "Hide" "icon" should not exist in the "Chat" "table_row" + And "Disable the Chat plugin" "icon" should not exist in the "Chat" "table_row" And I navigate to "Plugins > Availability restrictions > Manage restrictions" in site administration And "Hide" "icon" should not exist in the "Restriction by grouping" "table_row" And I navigate to "Plugins > Blocks > Manage blocks" in site administration diff --git a/lang/en/admin.php b/lang/en/admin.php index e20ab5d5793..f808377c273 100644 --- a/lang/en/admin.php +++ b/lang/en/admin.php @@ -994,6 +994,8 @@ $string['pleaserefreshregistration'] = 'Your site is registered. Registration la $string['pleaserefreshregistrationunknown'] = 'Your site has been registered but the registration date is unknown. Please update your registration using the \'Update registration\' button or ensure that the \'Site registration\' scheduled task is enabled so your registration is automatically updated.'; $string['pleaserefreshregistrationnewdata'] = 'Registration information has been changed. Please confirm it using the \'Update registration\' button.'; $string['plugin'] = 'Plugin'; +$string['plugin_disabled'] = 'The {$a} plugin has been disabled'; +$string['plugin_enabled'] = 'The {$a} plugin has been enabled'; $string['plugins'] = 'Plugins'; $string['pluginscheck'] = 'Plugin dependencies check'; $string['pluginscheckfailed'] = 'Dependencies check failed for {$a->pluginslist}'; diff --git a/lib/tests/plugininfo/editor_test.php b/lib/tests/plugininfo/editor_test.php new file mode 100644 index 00000000000..a3d2b863ad5 --- /dev/null +++ b/lib/tests/plugininfo/editor_test.php @@ -0,0 +1,68 @@ +. + +declare(strict_types=1); + +namespace core\plugininfo; + +use advanced_testcase; + +/** + * Unit tests for the editor plugininfo class + * + * @package core + * @covers \core\plugininfo\editor + * @copyright 2023 Andrew Lyons + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class editor_test extends advanced_testcase { + + /** + * Test that editor::get_enabled_plugins() returns the correct list of enabled plugins. + */ + public function test_get_enabled_plugins(): void { + $this->resetAfterTest(); + + // All plugins are enabled by default. + $plugins = editor::get_enabled_plugins(); + $this->assertArrayHasKey('tiny', $plugins); + $this->assertArrayHasKey('textarea', $plugins); + + // Disable tiny. + editor::enable_plugin('textarea', 0); + + $plugins = editor::get_enabled_plugins(); + $this->assertArrayHasKey('tiny', $plugins); + $this->assertArrayNotHasKey('textarea', $plugins); + } + + /** + * Test that editor::enable_plugin set to disable all plugins will leave the textarea enabled. + */ + public function test_enable_plugin_all(): void { + $this->resetAfterTest(); + + // All plugins are enabled by default. + $plugins = editor::get_enabled_plugins(); + foreach ($plugins as $plugin) { + editor::enable_plugin($plugin, 0); + } + + $plugins = editor::get_enabled_plugins(); + $this->assertCount(1, $plugins); + $this->assertArrayHasKey('textarea', $plugins); + } +} diff --git a/lib/tests/plugininfo/mod_test.php b/lib/tests/plugininfo/mod_test.php new file mode 100644 index 00000000000..f7ee4b8c8c4 --- /dev/null +++ b/lib/tests/plugininfo/mod_test.php @@ -0,0 +1,52 @@ +. + +declare(strict_types=1); + +namespace core\plugininfo; + +use advanced_testcase; + +/** + * Unit tests for the mod plugininfo class + * + * @package core + * @covers \core\plugininfo\mod + * @copyright 2023 Andrew Lyons + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class mod_test extends advanced_testcase { + public function test_get_enabled_plugins(): void { + $this->resetAfterTest(); + + // The bigbluebuttonbn plugin is disabled by default. + // Check all default formats. + $plugins = mod::get_enabled_plugins(); + $this->assertArrayHasKey('assign', $plugins); + $this->assertArrayHasKey('chat', $plugins); + $this->assertArrayHasKey('forum', $plugins); + $this->assertArrayNotHasKey('bigbluebuttonbn', $plugins); + + // Disable assignment. + mod::enable_plugin('assign', 0); + + $plugins = mod::get_enabled_plugins(); + $this->assertArrayHasKey('chat', $plugins); + $this->assertArrayHasKey('forum', $plugins); + $this->assertArrayNotHasKey('assign', $plugins); + $this->assertArrayNotHasKey('bigbluebuttonbn', $plugins); + } +}