From e2de093fe81e6f37d31aaf7d26730b79f94cf967 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Mon, 13 Feb 2023 12:59:35 +0800 Subject: [PATCH] MDL-76867 editor_tiny: Add plugin management page --- lib/editor/tiny/classes/manager.php | 24 ++++--- .../classes/table/plugin_management_table.php | 42 +++++++++++++ lib/editor/tiny/lang/en/editor_tiny.php | 2 + lib/editor/tiny/settings.php | 15 +++-- lib/editor/tiny/subplugins.php | 63 +++++++++++++++++++ .../tests/behat/manage_subplugins.feature | 30 +++++++++ lib/editor/tiny/version.php | 2 +- 7 files changed, 160 insertions(+), 18 deletions(-) create mode 100644 lib/editor/tiny/classes/table/plugin_management_table.php create mode 100644 lib/editor/tiny/subplugins.php create mode 100644 lib/editor/tiny/tests/behat/manage_subplugins.feature diff --git a/lib/editor/tiny/classes/manager.php b/lib/editor/tiny/classes/manager.php index 30facc3d3d9f9..5f7241bcec761 100644 --- a/lib/editor/tiny/classes/manager.php +++ b/lib/editor/tiny/classes/manager.php @@ -41,17 +41,17 @@ public function get_plugin_configuration( array $fpoptions = [], ?editor $editor = null ): array { - $disabledplugins = $this->get_disabled_plugins(); - // Get the list of plugins. // Note: Disabled plugins are already removed from this list. $plugins = $this->get_shipped_plugins(); // Fetch configuration for Moodle plugins. $moodleplugins = \core_component::get_plugin_list_with_class('tiny', 'plugininfo'); + $enabledplugins = \editor_tiny\plugininfo\tiny::get_enabled_plugins(); foreach ($moodleplugins as $plugin => $classname) { - if (in_array($plugin, $disabledplugins) || in_array("{$plugin}/plugin", $disabledplugins)) { - // Skip getting data for disabled plugins. + [, $pluginname] = explode('_', $plugin, 2); + if (!in_array($pluginname, $enabledplugins)) { + // This plugin has been disabled. continue; } @@ -75,10 +75,6 @@ public function get_plugin_configuration( $editor ); - if (!empty($config)) { - $plugininfo['config'] = $config; - } - // We suffix the plugin name for Moodle plugins with /plugin to avoid conflicts with Tiny plugins. $plugins["{$plugin}/plugin"] = $plugininfo; } @@ -190,7 +186,7 @@ protected function get_available_plugins(): array { $plugins = $this->get_shipped_plugins(); $plugins += $this->get_moodle_plugins(); - $disabledplugins = $this->get_disabled_plugins(); + $disabledplugins = $this->get_disabled_tinymce_plugins(); $plugins = array_filter($plugins, function ($plugin) use ($disabledplugins) { return !in_array($plugin, $disabledplugins); }, ARRAY_FILTER_USE_KEY); @@ -216,8 +212,8 @@ protected function get_shipped_plugins(): array { $plugins += $this->get_premium_plugins(); } - $disabledplugins = $this->get_disabled_plugins(); - return array_filter($plugins, function($plugin) use ($disabledplugins) { + $disabledplugins = $this->get_disabled_tinymce_plugins(); + return array_filter($plugins, function ($plugin) use ($disabledplugins) { return !in_array($plugin, $disabledplugins); }, ARRAY_FILTER_USE_KEY); } @@ -480,11 +476,13 @@ protected function get_tinymce_plugins(): array { } /** - * Get a list of the disabled plugins. + * Get a list of the built-in TinyMCE plugins which we want to disable. + * + * These are usually disabled because we have replaced them, or they are not compatible with Moodle in some way. * * @return string[] */ - protected function get_disabled_plugins(): array { + protected function get_disabled_tinymce_plugins(): array { return [ // Disable the image and media plugins. // These are not generally compatible with Moodle. diff --git a/lib/editor/tiny/classes/table/plugin_management_table.php b/lib/editor/tiny/classes/table/plugin_management_table.php new file mode 100644 index 0000000000000..3b58c37f1e30a --- /dev/null +++ b/lib/editor/tiny/classes/table/plugin_management_table.php @@ -0,0 +1,42 @@ +. + +namespace editor_tiny\table; + +use moodle_url; + +/** + * Tiny admin settings. + * + * @package editor_tiny + * @copyright 2023 Andrew Lyons + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class plugin_management_table extends \core_admin\table\plugin_management_table { + protected function get_plugintype(): string { + return 'tiny'; + } + + public function guess_base_url(): void { + $this->define_baseurl( + new moodle_url('/admin/settings.php', ['section' => 'editorsettingstiny']) + ); + } + + protected function get_action_url(array $params = []): moodle_url { + return new moodle_url('/lib/editor/tiny/subplugins.php', $params); + } +} diff --git a/lib/editor/tiny/lang/en/editor_tiny.php b/lib/editor/tiny/lang/en/editor_tiny.php index fd2abbb95ee6c..45713a2ba1922 100644 --- a/lib/editor/tiny/lang/en/editor_tiny.php +++ b/lib/editor/tiny/lang/en/editor_tiny.php @@ -28,6 +28,8 @@ $string['privacy:reason'] = 'The TinyMCE editor does not store any preferences or user data.'; $string['branding'] = 'TinyMCE branding'; $string['branding_desc'] = 'Support TinyMCE by displaying the logo in the bottom corner of the text editor. The logo links to the TinyMCE website.'; +$string['plugin_enabled'] = 'The {$a} plugin has been enabled.'; +$string['plugin_disabled'] = 'The {$a} plugin has been disabled.'; $string['tiny:hash'] = '#'; $string['tiny:accessibility'] = 'Accessibility'; $string['tiny:action'] = 'Action'; diff --git a/lib/editor/tiny/settings.php b/lib/editor/tiny/settings.php index 99af681b87240..598c099e28d3e 100644 --- a/lib/editor/tiny/settings.php +++ b/lib/editor/tiny/settings.php @@ -27,6 +27,13 @@ $ADMIN->add('editorsettings', new admin_category('editortiny', $editor->displayname, $editor->is_enabled() === false)); $settings = new admin_settingpage('editorsettingstiny', new lang_string('settings', 'editor_tiny')); +$settings->add(new \core_admin\admin\admin_setting_plugin_manager( + 'tiny', + \editor_tiny\table\plugin_management_table::class, + 'editor_tiny_settings', + get_string('editorsettings', 'editor'), +)); + if ($ADMIN->fulltree) { $setting = new admin_setting_configcheckbox( 'editor_tiny/branding', @@ -38,15 +45,15 @@ $settings->add($setting); } +// Note: We add editortiny to the settings page here manually rather than deferring to the plugininfo class. +// This ensures that it shows in the category list too. +$ADMIN->add('editortiny', $settings); + foreach (core_plugin_manager::instance()->get_plugins_of_type('tiny') as $plugin) { /** @var \editor_tiny\plugininfo\tiny $plugin */ $plugin->load_settings($ADMIN, 'editortiny', $hassiteconfig); } -// Note: We add editortiny to the settings page here manually rather than deferring to the plugininfo class. -// This ensures that it shows in the category list too. -$ADMIN->add('editortiny', $settings); - // Required or the editor plugininfo will add this section twice. unset($settings); $settings = null; diff --git a/lib/editor/tiny/subplugins.php b/lib/editor/tiny/subplugins.php new file mode 100644 index 0000000000000..1f8e16bd4798c --- /dev/null +++ b/lib/editor/tiny/subplugins.php @@ -0,0 +1,63 @@ +. + +/** + * Tiny subplugin management. + * + * @package editor_tinymce + * @copyright 2023 Andrew Lyons + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require(__DIR__ . '/../../../config.php'); +require_once("{$CFG->libdir}/adminlib.php"); + +$action = optional_param('action', '', PARAM_ALPHA); +$plugin = optional_param('plugin', '', PARAM_PLUGIN); + +$PAGE->set_context(context_system::instance()); +$PAGE->set_url('/lib/editor/tinymce/subplugins.php'); + +require_login(); +require_capability('moodle/site:config', context_system::instance()); +require_sesskey(); + +$tinymanager = \core_plugin_manager::resolve_plugininfo_class('tiny'); +$pluginname = get_string('pluginname', "tiny_{$plugin}"); + +switch ($action) { + case 'disable': + if ($tinymanager::enable_plugin($plugin, 0)) { + \core\notification::add( + get_string('plugin_disabled', 'editor_tiny', $pluginname), + \core\notification::SUCCESS + ); + } + break; + case 'enable': + if ($tinymanager::enable_plugin($plugin, 1)) { + \core\notification::add( + get_string('plugin_enabled', 'editor_tiny', $pluginname), + \core\notification::SUCCESS + ); + } + break; + default: +} + +redirect(new moodle_url('/admin/settings.php', [ + 'section' => 'editorsettingstiny', +])); diff --git a/lib/editor/tiny/tests/behat/manage_subplugins.feature b/lib/editor/tiny/tests/behat/manage_subplugins.feature new file mode 100644 index 0000000000000..6919d15de226d --- /dev/null +++ b/lib/editor/tiny/tests/behat/manage_subplugins.feature @@ -0,0 +1,30 @@ +@core @core_admin +Feature: An administrator can manage TinyMCE subplugins + In order to alter the user experience + As an admin + I can manage TinyMCE subplugins + + @javascript + Scenario: An administrator can control the enabled state of TinyMCE subplugins using JavaScript + Given I am logged in as "admin" + And I navigate to "Plugins > Text editors > TinyMCE > General settings" in site administration + When I click on "Disable the Tiny equation editor plugin" "link" + Then I should see "The Tiny equation editor plugin has been disabled" + And "Disable the Tiny equation editor plugin" "link" should not exist + But "Enable the Tiny equation editor plugin" "link" should exist + When I click on "Enable the Tiny equation editor plugin" "link" + Then I should see "The Tiny equation editor plugin has been enabled" + And "Enable the Tiny equation editor plugin" "link" should not exist + But "Disable the Tiny equation editor plugin" "link" should exist + + Scenario: An administrator can control the enabled state of TinyMCE subplugins without JavaScript + Given I am logged in as "admin" + And I navigate to "Plugins > Text editors > TinyMCE > General settings" in site administration + When I click on "Disable the Tiny equation editor plugin" "link" + Then I should see "The Tiny equation editor plugin has been disabled" + And "Disable the Tiny equation editor plugin" "link" should not exist + But "Enable the Tiny equation editor plugin" "link" should exist + When I click on "Enable the Tiny equation editor plugin" "link" + Then I should see "The Tiny equation editor plugin has been enabled" + And "Enable the Tiny equation editor plugin" "link" should not exist + But "Disable the Tiny equation editor plugin" "link" should exist diff --git a/lib/editor/tiny/version.php b/lib/editor/tiny/version.php index e84e9e0aca7f9..70c8611eaf9ed 100644 --- a/lib/editor/tiny/version.php +++ b/lib/editor/tiny/version.php @@ -24,6 +24,6 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2022112800; // The current plugin version (Date: YYYYMMDDXX). +$plugin->version = 2023021301; // The current plugin version (Date: YYYYMMDDXX). $plugin->requires = 2022111800; $plugin->component = 'editor_tiny'; // Full name of the plugin (used for diagnostics).