From 29ce0058629852145eff342db44468ab6c777475 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 17 Feb 2017 09:29:34 +0800 Subject: [PATCH] MDL-55528 admin: Add a new generic admin setting type --- .../templates/setting_manage_plugins.mustache | 60 +++++ admin/updatesetting.php | 80 +++++++ lang/en/admin.php | 3 +- lang/en/plugin.php | 1 + lib/adminlib.php | 205 ++++++++++++++++++ 5 files changed, 348 insertions(+), 1 deletion(-) create mode 100644 admin/templates/setting_manage_plugins.mustache create mode 100644 admin/updatesetting.php diff --git a/admin/templates/setting_manage_plugins.mustache b/admin/templates/setting_manage_plugins.mustache new file mode 100644 index 00000000000..65d941d86a9 --- /dev/null +++ b/admin/templates/setting_manage_plugins.mustache @@ -0,0 +1,60 @@ + + + + + {{#infocolumnname}} + + {{/infocolumnname}} + + + + + + + + {{#plugins}} + + + {{#infocolumnname}} + + {{/infocolumnname}} + + + + + + {{/plugins}} + +
{{#str}}name, moodle{{/str}}{{infocolumnname}}{{#str}}order, moodle{{/str}}{{#str}}isenabled, plugin{{/str}}{{#str}}settings, moodle{{/str}}{{#str}}uninstall, plugin{{/str}}
{{plugin}} + {{info}} + + {{#moveuplink}} + + {{#moveupicon}}{{>core/pix_icon}}{{/moveupicon}} + + {{/moveuplink}} + {{^moveuplink}} + {{#spacericon}}{{>core/pix_icon}}{{/spacericon}} + {{/moveuplink}} + + {{#movedownlink}} + + {{#movedownicon}}{{>core/pix_icon}}{{/movedownicon}} + + {{/movedownlink}} + {{^movedownlink}} + {{#spacericon}}{{>core/pix_icon}}{{/spacericon}} + {{/movedownlink}} + + + {{#toggleicon}}{{>core/pix_icon}}{{/toggleicon}} + + + {{#settingslink}} + {{#str}}settings,plugin{{/str}} + {{/settingslink}} + + {{#uninstalllink}} + {{#str}}uninstall,plugin{{/str}} + {{/uninstalllink}} +
diff --git a/admin/updatesetting.php b/admin/updatesetting.php new file mode 100644 index 00000000000..a6b3b1dcfc1 --- /dev/null +++ b/admin/updatesetting.php @@ -0,0 +1,80 @@ +. + +/** + * Generic plugin config manipulation script. + * + * @package admin + * @copyright 2017 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +define('NO_OUTPUT_BUFFERING', true); + +require_once('../config.php'); +require_once($CFG->libdir.'/adminlib.php'); + +$action = required_param('action', PARAM_ALPHANUMEXT); +$plugin = required_param('plugin', PARAM_PLUGIN); +$type = required_param('type', PARAM_PLUGIN); + +$PAGE->set_url('/admin/updatesetting.php'); +$PAGE->set_context(context_system::instance()); + +require_login(); +require_capability('moodle/site:config', context_system::instance()); +require_sesskey(); + +$plugintypeclass = "\\core\\plugininfo\\{$type}"; + +$plugins = \core_plugin_manager::instance()->get_plugins_of_type($type); +$sortorder = array_values($plugintypeclass::get_enabled_plugins()); + +$return = $plugintypeclass::get_manage_url(); + +if (!array_key_exists($plugin, $plugins)) { + redirect($return); +} + +switch ($action) { + case 'disable': + $plugins[$plugin]->set_enabled(false); + break; + + case 'enable': + $plugins[$plugin]->set_enabled(true); + break; + + case 'up': + if (($pos = array_search($plugin, $sortorder)) > 0) { + $tmp = $sortorder[$pos - 1]; + $sortorder[$pos - 1] = $sortorder[$pos]; + $sortorder[$pos] = $tmp; + $plugintypeclass::set_enabled_plugins($sortorder); + } + break; + + case 'down': + if ((($pos = array_search($plugin, $sortorder)) !== false) && ($pos < count($sortorder) - 1)) { + $tmp = $sortorder[$pos + 1]; + $sortorder[$pos + 1] = $sortorder[$pos]; + $sortorder[$pos] = $tmp; + $plugintypeclass::set_enabled_plugins($sortorder); + } + break; +} + +redirect($return); diff --git a/lang/en/admin.php b/lang/en/admin.php index 1a80be9de3f..facf54380f9 100644 --- a/lang/en/admin.php +++ b/lang/en/admin.php @@ -529,6 +529,7 @@ $string['experimentalsettings'] = 'Experimental settings'; $string['extendedusernamechars'] = 'Allow extended characters in usernames'; $string['extramemorylimit'] = 'Extra PHP memory limit'; $string['fatalsessionautostart'] = '

Serious configuration error detected, please notify server administrator.

To operate properly, Moodle requires that administrator changes PHP settings.

session.auto_start must be set to off.

This setting is controlled by editing php.ini, Apache/IIS
configuration or .htaccess file on the server.

'; +$string['fileconversioncleanuptask'] = 'Cleanup of temporary records for file conversions.'; $string['filecreated'] = 'New file created'; $string['filestoredin'] = 'Save file into folder :'; $string['filestoredinhelp'] = 'Where the file will be stored'; @@ -1245,4 +1246,4 @@ $string['cacheapplicationhelp'] = 'Cached items are shared among all users and e $string['mobile'] = 'Mobile'; // Deprecated since Moodle 3.3. $string['loginpasswordautocomplete'] = 'Prevent password autocompletion on login form'; -$string['loginpasswordautocomplete_help'] = 'If enabled, users are not allowed to save their account password in their browser.'; \ No newline at end of file +$string['loginpasswordautocomplete_help'] = 'If enabled, users are not allowed to save their account password in their browser.'; diff --git a/lang/en/plugin.php b/lang/en/plugin.php index 8e1d5e93313..9ed63798bf0 100644 --- a/lang/en/plugin.php +++ b/lang/en/plugin.php @@ -54,6 +54,7 @@ $string['err_response_http_code'] = 'Unable to fetch available updates data - un $string['filterall'] = 'Show all'; $string['filtercontribonly'] = 'Show additional plugins only'; $string['filterupdatesonly'] = 'Show updateable only'; +$string['isenabled'] = 'Enabled?'; $string['misdepinfoplugin'] = 'Plugin info'; $string['misdepinfoversion'] = 'Version info'; $string['misdepsavail'] = 'Available missing dependencies'; diff --git a/lib/adminlib.php b/lib/adminlib.php index 1915fa0db87..e1ce048cf68 100644 --- a/lib/adminlib.php +++ b/lib/adminlib.php @@ -7388,6 +7388,211 @@ class admin_page_managefilters extends admin_externalpage { } } +/** + * Generic class for managing plugins in a table that allows re-ordering and enable/disable of each plugin. + * Requires a get_rank method on the plugininfo class for sorting. + * + * @copyright 2017 Damyon Wiese + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +abstract class admin_setting_manage_plugins extends admin_setting { + + /** + * Get the admin settings section name (just a unique string) + * @return string + */ + public function get_section_name() { + return 'manage' . $this->get_plugin_type() . 'plugins'; + } + + /** + * Get the admin settings section title (use get_string). + * @return string + */ + abstract public function get_section_title(); + + /** + * Get the type of plugin to manage. + * @return string + */ + abstract public function get_plugin_type(); + + /** + * Get the name of the second column. + * @return string + */ + public function get_info_column_name() { + return ''; + } + + /** + * Get the type of plugin to manage. + * + * @param plugininfo The plugin info class. + * @return string + */ + abstract public function get_info_column($plugininfo); + + /** + * Calls parent::__construct with specific arguments + */ + public function __construct() { + $this->nosave = true; + parent::__construct($this->get_section_name(), $this->get_section_title(), '', ''); + } + + /** + * Always returns true, does nothing + * + * @return true + */ + public function get_setting() { + return true; + } + + /** + * Always returns true, does nothing + * + * @return true + */ + public function get_defaultsetting() { + return true; + } + + /** + * Always returns '', does not write anything + * + * @param mixed $data + * @return string Always returns '' + */ + public function write_setting($data) { + // Do not write any setting. + return ''; + } + + /** + * Checks if $query is one of the available plugins of this type + * + * @param string $query The string to search for + * @return bool Returns true if found, false if not + */ + public function is_related($query) { + if (parent::is_related($query)) { + return true; + } + + $query = core_text::strtolower($query); + $plugins = core_plugin_manager::instance()->get_plugins_of_type($this->get_plugin_type()); + foreach ($plugins as $name => $plugin) { + $localised = $plugin->displayname; + if (strpos(core_text::strtolower($name), $query) !== false) { + return true; + } + if (strpos(core_text::strtolower($localised), $query) !== false) { + return true; + } + } + return false; + } + + /** + * The URL for the management page for this plugintype. + * + * @return moodle_url + */ + protected function get_manage_url() { + return new moodle_url('/admin/updatesetting.php'); + } + + /** + * Builds the HTML to display the control. + * + * @param string $data Unused + * @param string $query + * @return string + */ + public function output_html($data, $query = '') { + global $CFG, $OUTPUT, $DB, $PAGE; + + $spacer = new pix_icon('spacer', '', 'moodle'); + $moveup = new pix_icon('t/up', get_string('up'), 'moodle'); + $movedown = new pix_icon('t/down', get_string('down'), 'moodle'); + + $context = (object) [ + 'manageurl' => new moodle_url($this->get_manage_url(), [ + 'type' => $this->get_plugin_type(), + 'sesskey' => sesskey(), + ]), + 'infocolumnname' => $this->get_info_column_name(), + 'spacericon' => $spacer->export_for_template($OUTPUT), + 'moveupicon' => $moveup->export_for_template($OUTPUT), + 'movedownicon' => $movedown->export_for_template($OUTPUT), + 'plugins' => [], + ]; + + $pluginmanager = core_plugin_manager::instance(); + $allplugins = $pluginmanager->get_plugins_of_type($this->get_plugin_type()); + $enabled = $pluginmanager->get_enabled_plugins($this->get_plugin_type()); + $plugins = array_merge($enabled, $allplugins); + foreach ($plugins as $key => $plugin) { + $pluginlink = new moodle_url($context->manageurl, ['plugin' => $key]); + + $pluginkey = (object) [ + 'plugin' => $plugin->displayname, + 'enabled' => $plugin->is_enabled(), + 'togglelink' => '', + 'toggleicon' => '', + 'moveuplink' => '', + 'movedownlink' => '', + 'settingslink' => $plugin->get_settings_url(), + 'uninstalllink' => '', + 'info' => '', + ]; + + // Enable/Disable link. + $togglelink = new moodle_url($pluginlink); + if ($plugin->is_enabled()) { + $toggleicon = new pix_icon('i/hide', get_string('disable', 'moodle'), 'moodle'); + $togglelink->param('action', 'disable'); + + if (count($context->plugins)) { + // This is not the first plugin. + $pluginkey->moveuplink = new moodle_url($pluginlink, ['action' => 'up']); + } + + if (count($enabled) > count($context->plugins) + 1) { + // This is not the last plugin. + $pluginkey->movedownlink = new moodle_url($pluginlink, ['action' => 'down']); + } + + $pluginkey->info = $this->get_info_column($plugin); + } else { + $toggleicon = new pix_icon('i/show', get_string('enable', 'moodle'), 'moodle'); + $togglelink->param('action', 'enable'); + } + + $pluginkey->toggleicon = $toggleicon->export_for_template($OUTPUT); + $pluginkey->togglelink = $togglelink; + + $frankenstyle = $plugin->type . '_' . $plugin->name; + if ($uninstalllink = core_plugin_manager::instance()->get_uninstall_url($frankenstyle, 'manage')) { + // This plugin supports uninstallation. + $pluginkey->uninstalllink = $uninstalllink; + } + + if (!empty($this->get_info_column_name())) { + // This plugintype has an info column. + $pluginkey->info = $this->get_info_column($plugin); + } + + $context->plugins[] = $pluginkey; + } + + $str = $OUTPUT->render_from_template('core_admin/setting_manage_plugins', $context); + return highlight($query, $str); + } +} + /** * Special class for media player plugins management. *