Commit bde002b8 authored by Petr Škoda's avatar Petr Škoda
Browse files

MDL-41437 rework plugin_manager caching and version info in blocks and modules

This patch includes:

* version column removed from modules table, now using standard config, this allows decimal version for modules
* version column removed from block table, now using standard config, this allows decimal version for blocks
* module version.php can safely use $plugins instead of module
* new plugin_manager bulk caching, this should help with MUC performance when logged in as admin
* all missing plugins are now in plugin overview (previously only blocks and modules)
* simplified code and improved coding style
* reworked plugin_manager unit tests - now using real plugins instead of mocks
* unit tests now fail if any plugin does not contain proper version.php file
* allow uninstall of deleted filters
parent 81881cb9
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
require_once('../config.php'); require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php'); require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/tablelib.php'); require_once($CFG->libdir.'/tablelib.php');
require_once($CFG->libdir.'/pluginlib.php');
require_login(); require_login();
require_capability('moodle/site:config', context_system::instance()); require_capability('moodle/site:config', context_system::instance());
...@@ -52,6 +53,7 @@ switch ($action) { ...@@ -52,6 +53,7 @@ switch ($action) {
set_config('registerauth', ''); set_config('registerauth', '');
} }
session_gc(); // remove stale sessions session_gc(); // remove stale sessions
plugin_manager::reset_caches();
break; break;
case 'enable': case 'enable':
...@@ -62,6 +64,7 @@ switch ($action) { ...@@ -62,6 +64,7 @@ switch ($action) {
set_config('auth', implode(',', $authsenabled)); set_config('auth', implode(',', $authsenabled));
} }
session_gc(); // remove stale sessions session_gc(); // remove stale sessions
plugin_manager::reset_caches();
break; break;
case 'down': case 'down':
......
<?php
// block.php - allows admin to edit all local configuration variables for a block
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
$blockid = required_param('block', PARAM_INT);
if(!$blockrecord = blocks_get_record($blockid)) {
print_error('blockdoesnotexist', 'error');
}
admin_externalpage_setup('blocksetting'.$blockrecord->name);
$block = block_instance($blockrecord->name);
if($block === false) {
print_error('blockcannotinistantiate', 'error');
}
// Define the data we're going to silently include in the instance config form here,
// so we can strip them from the submitted data BEFORE handling it.
$hiddendata = array(
'block' => $blockid,
'sesskey' => sesskey()
);
/// If data submitted, then process and store.
if ($config = data_submitted()) {
if (!confirm_sesskey()) {
print_error('confirmsesskeybad', 'error');
}
if(!$block->has_config()) {
print_error('blockcannotconfig', 'error');
}
$remove = array_keys($hiddendata);
foreach($remove as $item) {
unset($config->$item);
}
$block->config_save($config);
redirect("$CFG->wwwroot/$CFG->admin/blocks.php", get_string("changessaved"), 1);
exit;
}
/// Otherwise print the form.
$strmanageblocks = get_string('manageblocks');
$strblockname = $block->get_title();
echo $OUTPUT->header();
echo $OUTPUT->heading($strblockname);
echo $OUTPUT->notification('This block still uses an old-style config_global.html file. ' .
'It must be updated by a developer to use a settings.php file.');
echo $OUTPUT->box(get_string('configwarning', 'admin'), 'generalbox boxwidthnormal boxaligncenter');
echo '<br />';
echo '<form method="post" action="block.php">';
echo '<p>';
foreach($hiddendata as $name => $val) {
echo '<input type="hidden" name="'. $name .'" value="'. $val .'" />';
}
echo '</p>';
echo $OUTPUT->box_start();
include($CFG->dirroot.'/blocks/'. $block->name() .'/config_global.html');
echo $OUTPUT->box_end();
echo '</form>';
echo $OUTPUT->footer();
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
require_once('../config.php'); require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php'); require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/tablelib.php'); require_once($CFG->libdir.'/tablelib.php');
require_once($CFG->libdir.'/pluginlib.php');
admin_externalpage_setup('manageblocks'); admin_externalpage_setup('manageblocks');
...@@ -29,9 +30,6 @@ ...@@ -29,9 +30,6 @@
$strprotect = get_string('blockprotect', 'admin'); $strprotect = get_string('blockprotect', 'admin');
$strunprotect = get_string('blockunprotect', 'admin'); $strunprotect = get_string('blockunprotect', 'admin');
// Purge all caches related to blocks administration.
cache::make('core', 'plugininfo_block')->purge();
/// If data submitted, then process and store. /// If data submitted, then process and store.
if (!empty($hide) && confirm_sesskey()) { if (!empty($hide) && confirm_sesskey()) {
...@@ -39,6 +37,7 @@ ...@@ -39,6 +37,7 @@
print_error('blockdoesnotexist', 'error'); print_error('blockdoesnotexist', 'error');
} }
$DB->set_field('block', 'visible', '0', array('id'=>$block->id)); // Hide block $DB->set_field('block', 'visible', '0', array('id'=>$block->id)); // Hide block
plugin_manager::reset_caches();
admin_get_root(true, false); // settings not required - only pages admin_get_root(true, false); // settings not required - only pages
} }
...@@ -47,6 +46,7 @@ ...@@ -47,6 +46,7 @@
print_error('blockdoesnotexist', 'error'); print_error('blockdoesnotexist', 'error');
} }
$DB->set_field('block', 'visible', '1', array('id'=>$block->id)); // Show block $DB->set_field('block', 'visible', '1', array('id'=>$block->id)); // Show block
plugin_manager::reset_caches();
admin_get_root(true, false); // settings not required - only pages admin_get_root(true, false); // settings not required - only pages
} }
...@@ -120,12 +120,13 @@ ...@@ -120,12 +120,13 @@
foreach ($blocknames as $blockid=>$strblockname) { foreach ($blocknames as $blockid=>$strblockname) {
$block = $blocks[$blockid]; $block = $blocks[$blockid];
$blockname = $block->name; $blockname = $block->name;
$dbversion = get_config('block_'.$block->name, 'version');
if (!file_exists("$CFG->dirroot/blocks/$blockname/block_$blockname.php")) { if (!file_exists("$CFG->dirroot/blocks/$blockname/block_$blockname.php")) {
$blockobject = false; $blockobject = false;
$strblockname = '<span class="notifyproblem">'.$strblockname.' ('.get_string('missingfromdisk').')</span>'; $strblockname = '<span class="notifyproblem">'.$strblockname.' ('.get_string('missingfromdisk').')</span>';
$plugin = new stdClass(); $plugin = new stdClass();
$plugin->version = $block->version; $plugin->version = $dbversion;
} else { } else {
$plugin = new stdClass(); $plugin = new stdClass();
...@@ -186,10 +187,10 @@ ...@@ -186,10 +187,10 @@
$class = ' class="dimmed_text"'; // Leading space required! $class = ' class="dimmed_text"'; // Leading space required!
} }
if ($block->version == $plugin->version) { if ($dbversion == $plugin->version) {
$version = $block->version; $version = $dbversion;
} else { } else {
$version = "$block->version ($plugin->version)"; $version = "$dbversion ($plugin->version)";
} }
if (!$blockobject) { if (!$blockobject) {
......
...@@ -53,11 +53,13 @@ switch ($action) { ...@@ -53,11 +53,13 @@ switch ($action) {
print_error('cannotdisableformat', 'error', $return); print_error('cannotdisableformat', 'error', $return);
} }
set_config('disabled', 1, 'format_'. $formatname); set_config('disabled', 1, 'format_'. $formatname);
plugin_manager::reset_caches();
} }
break; break;
case 'enable': case 'enable':
if (!$formatplugins[$formatname]->is_enabled()) { if (!$formatplugins[$formatname]->is_enabled()) {
unset_config('disabled', 'format_'. $formatname); unset_config('disabled', 'format_'. $formatname);
plugin_manager::reset_caches();
} }
break; break;
case 'up': case 'up':
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
require_once('../config.php'); require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php'); require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/tablelib.php'); require_once($CFG->libdir.'/tablelib.php');
require_once($CFG->libdir.'/pluginlib.php');
$action = required_param('action', PARAM_ALPHANUMEXT); $action = required_param('action', PARAM_ALPHANUMEXT);
$editor = required_param('editor', PARAM_PLUGIN); $editor = required_param('editor', PARAM_PLUGIN);
...@@ -93,6 +94,7 @@ if (empty($active_editors)) { ...@@ -93,6 +94,7 @@ if (empty($active_editors)) {
} }
set_config('texteditors', implode(',', $active_editors)); set_config('texteditors', implode(',', $active_editors));
plugin_manager::reset_caches();
if ($return) { if ($return) {
redirect ($returnurl); redirect ($returnurl);
......
...@@ -27,6 +27,7 @@ define('NO_OUTPUT_BUFFERING', true); ...@@ -27,6 +27,7 @@ define('NO_OUTPUT_BUFFERING', true);
require_once('../config.php'); require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php'); require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/pluginlib.php');
$action = required_param('action', PARAM_ALPHANUMEXT); $action = required_param('action', PARAM_ALPHANUMEXT);
$enrol = required_param('enrol', PARAM_PLUGIN); $enrol = required_param('enrol', PARAM_PLUGIN);
...@@ -50,6 +51,7 @@ switch ($action) { ...@@ -50,6 +51,7 @@ switch ($action) {
case 'disable': case 'disable':
unset($enabled[$enrol]); unset($enabled[$enrol]);
set_config('enrol_plugins_enabled', implode(',', array_keys($enabled))); set_config('enrol_plugins_enabled', implode(',', array_keys($enabled)));
plugin_manager::reset_caches();
$syscontext->mark_dirty(); // resets all enrol caches $syscontext->mark_dirty(); // resets all enrol caches
break; break;
...@@ -60,6 +62,7 @@ switch ($action) { ...@@ -60,6 +62,7 @@ switch ($action) {
$enabled = array_keys($enabled); $enabled = array_keys($enabled);
$enabled[] = $enrol; $enabled[] = $enrol;
set_config('enrol_plugins_enabled', implode(',', $enabled)); set_config('enrol_plugins_enabled', implode(',', $enabled));
plugin_manager::reset_caches();
$syscontext->mark_dirty(); // resets all enrol caches $syscontext->mark_dirty(); // resets all enrol caches
break; break;
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
require_once(dirname(__FILE__) . '/../config.php'); require_once(dirname(__FILE__) . '/../config.php');
require_once($CFG->libdir . '/adminlib.php'); require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/pluginlib.php');
$action = optional_param('action', '', PARAM_ALPHANUMEXT); $action = optional_param('action', '', PARAM_ALPHANUMEXT);
$filterpath = optional_param('filterpath', '', PARAM_SAFEDIR); $filterpath = optional_param('filterpath', '', PARAM_SAFEDIR);
...@@ -44,9 +45,6 @@ ...@@ -44,9 +45,6 @@
$returnurl = "$CFG->wwwroot/$CFG->admin/filters.php"; $returnurl = "$CFG->wwwroot/$CFG->admin/filters.php";
admin_externalpage_setup('managefilters'); admin_externalpage_setup('managefilters');
// Purge all caches related to filter administration.
cache::make('core', 'plugininfo_filter')->purge();
$filters = filter_get_global_states(); $filters = filter_get_global_states();
// In case any new filters have been installed, but not put in the table yet. // In case any new filters have been installed, but not put in the table yet.
...@@ -59,7 +57,7 @@ ...@@ -59,7 +57,7 @@
/// Process actions ============================================================ /// Process actions ============================================================
if ($action) { if ($action) {
if (!isset($filters[$filterpath]) && !isset($newfilters[$filterpath])) { if ($action !== 'delete' and !isset($filters[$filterpath]) and !isset($newfilters[$filterpath])) {
throw new moodle_exception('filternotinstalled', 'error', $returnurl, $filterpath); throw new moodle_exception('filternotinstalled', 'error', $returnurl, $filterpath);
} }
...@@ -138,6 +136,7 @@ ...@@ -138,6 +136,7 @@
// Reset caches and return // Reset caches and return
if ($action) { if ($action) {
plugin_manager::reset_caches();
reset_text_filters_cache(); reset_text_filters_cache();
redirect($returnurl); redirect($returnurl);
} }
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
require_once(dirname(dirname(__FILE__)) . '/config.php'); require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir.'/adminlib.php'); require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/tablelib.php'); require_once($CFG->libdir.'/tablelib.php');
require_once($CFG->libdir.'/pluginlib.php');
admin_externalpage_setup('managelocalplugins'); admin_externalpage_setup('managelocalplugins');
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
require_once(dirname(__FILE__) . '/../config.php'); require_once(dirname(__FILE__) . '/../config.php');
require_once($CFG->dirroot . '/message/lib.php'); require_once($CFG->dirroot . '/message/lib.php');
require_once($CFG->libdir.'/adminlib.php'); require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/pluginlib.php');
// This is an admin page // This is an admin page
admin_externalpage_setup('managemessageoutputs'); admin_externalpage_setup('managemessageoutputs');
...@@ -44,6 +45,7 @@ if (!empty($disable) && confirm_sesskey()) { ...@@ -44,6 +45,7 @@ if (!empty($disable) && confirm_sesskey()) {
print_error('outputdoesnotexist', 'message'); print_error('outputdoesnotexist', 'message');
} }
$DB->set_field('message_processors', 'enabled', '0', array('id'=>$processor->id)); // Disable output $DB->set_field('message_processors', 'enabled', '0', array('id'=>$processor->id)); // Disable output
plugin_manager::reset_caches();
} }
if (!empty($enable) && confirm_sesskey()) { if (!empty($enable) && confirm_sesskey()) {
...@@ -51,6 +53,7 @@ if (!empty($enable) && confirm_sesskey()) { ...@@ -51,6 +53,7 @@ if (!empty($enable) && confirm_sesskey()) {
print_error('outputdoesnotexist', 'message'); print_error('outputdoesnotexist', 'message');
} }
$DB->set_field('message_processors', 'enabled', '1', array('id'=>$processor->id)); // Enable output $DB->set_field('message_processors', 'enabled', '1', array('id'=>$processor->id)); // Enable output
plugin_manager::reset_caches();
} }
if (!empty($uninstall) && confirm_sesskey()) { if (!empty($uninstall) && confirm_sesskey()) {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
require_once('../course/lib.php'); require_once('../course/lib.php');
require_once($CFG->libdir.'/adminlib.php'); require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/tablelib.php'); require_once($CFG->libdir.'/tablelib.php');
require_once($CFG->libdir.'/pluginlib.php');
// defines // defines
define('MODULE_TABLE','module_administration_table'); define('MODULE_TABLE','module_administration_table');
...@@ -27,9 +28,6 @@ ...@@ -27,9 +28,6 @@
$stractivitymodule = get_string("activitymodule"); $stractivitymodule = get_string("activitymodule");
$strshowmodulecourse = get_string('showmodulecourse'); $strshowmodulecourse = get_string('showmodulecourse');
// Purge all caches related to activity modules administration.
cache::make('core', 'plugininfo_mod')->purge();
/// If data submitted, then process and store. /// If data submitted, then process and store.
if (!empty($hide) and confirm_sesskey()) { if (!empty($hide) and confirm_sesskey()) {
...@@ -50,6 +48,7 @@ ...@@ -50,6 +48,7 @@
FROM {course_modules} FROM {course_modules}
WHERE visibleold=1 AND module=?)", WHERE visibleold=1 AND module=?)",
array($module->id)); array($module->id));
plugin_manager::reset_caches();
admin_get_root(true, false); // settings not required - only pages admin_get_root(true, false); // settings not required - only pages
} }
...@@ -66,6 +65,7 @@ ...@@ -66,6 +65,7 @@
FROM {course_modules} FROM {course_modules}
WHERE visible=1 AND module=?)", WHERE visible=1 AND module=?)",
array($module->id)); array($module->id));
plugin_manager::reset_caches();
admin_get_root(true, false); // settings not required - only pages admin_get_root(true, false); // settings not required - only pages
} }
...@@ -143,12 +143,12 @@ ...@@ -143,12 +143,12 @@
$visible = ""; $visible = "";
$class = ""; $class = "";
} }
$version = get_config('mod_'.$module->name, 'version');
$table->add_data(array( $table->add_data(array(
'<span'.$class.'>'.$strmodulename.'</span>', '<span'.$class.'>'.$strmodulename.'</span>',
$countlink, $countlink,
'<span'.$class.'>'.$module->version.'</span>', '<span'.$class.'>'.$version.'</span>',
$visible, $visible,
$uninstall, $uninstall,
$settings $settings
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
require_once(dirname(dirname(__FILE__)) . '/config.php'); require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir.'/adminlib.php'); require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/tablelib.php'); require_once($CFG->libdir.'/tablelib.php');
require_once($CFG->libdir.'/pluginlib.php');
admin_externalpage_setup('manageplagiarismplugins'); admin_externalpage_setup('manageplagiarismplugins');
......
...@@ -4,6 +4,7 @@ require_once(dirname(dirname(__FILE__)) . '/config.php'); ...@@ -4,6 +4,7 @@ require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/portfoliolib.php'); require_once($CFG->libdir . '/portfoliolib.php');
require_once($CFG->libdir . '/portfolio/forms.php'); require_once($CFG->libdir . '/portfolio/forms.php');
require_once($CFG->libdir . '/adminlib.php'); require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/pluginlib.php');
$portfolio = optional_param('pf', '', PARAM_ALPHANUMEXT); $portfolio = optional_param('pf', '', PARAM_ALPHANUMEXT);
$action = optional_param('action', '', PARAM_ALPHA); $action = optional_param('action', '', PARAM_ALPHA);
...@@ -43,9 +44,6 @@ $configstr = get_string('manageportfolios', 'portfolio'); ...@@ -43,9 +44,6 @@ $configstr = get_string('manageportfolios', 'portfolio');
$return = true; // direct back to the main page $return = true; // direct back to the main page
// Purge all caches related to portfolio administration.
cache::make('core', 'plugininfo_portfolio')->purge();
/** /**
* Helper function that generates a moodle_url object * Helper function that generates a moodle_url object
* relevant to the portfolio * relevant to the portfolio
...@@ -91,6 +89,7 @@ if (($action == 'edit') || ($action == 'new')) { ...@@ -91,6 +89,7 @@ if (($action == 'edit') || ($action == 'new')) {
} else { } else {
portfolio_static_function($plugin, 'create_instance', $plugin, $fromform->name, $fromform); portfolio_static_function($plugin, 'create_instance', $plugin, $fromform->name, $fromform);
} }
plugin_manager::reset_caches();
$savedstr = get_string('instancesaved', 'portfolio'); $savedstr = get_string('instancesaved', 'portfolio');
redirect($baseurl, $savedstr, 1); redirect($baseurl, $savedstr, 1);
exit; exit;
...@@ -119,6 +118,7 @@ if (($action == 'edit') || ($action == 'new')) { ...@@ -119,6 +118,7 @@ if (($action == 'edit') || ($action == 'new')) {
$instance->set('visible', $visible); $instance->set('visible', $visible);
$instance->save(); $instance->save();
plugin_manager::reset_caches();
$return = true; $return = true;
} else if ($action == 'delete') { } else if ($action == 'delete') {
$instance = portfolio_instance($portfolio); $instance = portfolio_instance($portfolio);
......
...@@ -92,6 +92,7 @@ if (($disable = optional_param('disable', '', PARAM_PLUGIN)) && confirm_sesskey( ...@@ -92,6 +92,7 @@ if (($disable = optional_param('disable', '', PARAM_PLUGIN)) && confirm_sesskey(
$disabledbehaviours[] = $disable; $disabledbehaviours[] = $disable;
set_config('disabledbehaviours', implode(',', $disabledbehaviours), 'question'); set_config('disabledbehaviours', implode(',', $disabledbehaviours), 'question');
} }
plugin_manager::reset_caches();
redirect($thispageurl); redirect($thispageurl);
} }
...@@ -109,6 +110,7 @@ if (($enable = optional_param('enable', '', PARAM_PLUGIN)) && confirm_sesskey()) ...@@ -109,6 +110,7 @@ if (($enable = optional_param('enable', '', PARAM_PLUGIN)) && confirm_sesskey())
unset($disabledbehaviours[$key]); unset($disabledbehaviours[$key]);
set_config('disabledbehaviours', implode(',', $disabledbehaviours), 'question'); set_config('disabledbehaviours', implode(',', $disabledbehaviours), 'question');
} }
plugin_manager::reset_caches();
redirect($thispageurl); redirect($thispageurl);
} }
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
require_once(dirname(__FILE__) . '/../config.php'); require_once(dirname(__FILE__) . '/../config.php');
require_once($CFG->libdir.'/adminlib.php'); require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/tablelib.php'); require_once($CFG->libdir.'/tablelib.php');
require_once($CFG->libdir.'/pluginlib.php');
admin_externalpage_setup('managereports'); admin_externalpage_setup('managereports');
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
require_once(dirname(dirname(__FILE__)) . '/config.php'); require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->dirroot . '/repository/lib.php'); require_once($CFG->dirroot . '/repository/lib.php');
require_once($CFG->libdir . '/adminlib.php'); require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/pluginlib.php');
$repository = optional_param('repos', '', PARAM_ALPHANUMEXT); $repository = optional_param('repos', '', PARAM_ALPHANUMEXT);
$action = optional_param('action', '', PARAM_ALPHANUMEXT); $action = optional_param('action', '', PARAM_ALPHANUMEXT);
...@@ -61,9 +62,6 @@ if (!empty($action)) { ...@@ -61,9 +62,6 @@ if (!empty($action)) {
require_sesskey(); require_sesskey();
} }
// Purge all caches related to repositories administration.
cache::make('core', 'plugininfo_repository')->purge();
/** /**
* Helper function that generates a moodle_url object * Helper function that generates a moodle_url object
* relevant to the repository * relevant to the repository
...@@ -151,6 +149,7 @@ if (($action == 'edit') || ($action == 'new')) { ...@@ -151,6 +149,7 @@ if (($action == 'edit') || ($action == 'new')) {
} }
if ($success) { if ($success) {
// configs saved // configs saved
plugin_manager::reset_caches();
redirect($baseurl); redirect($baseurl);
} else { } else {
print_error('instancenotsaved', 'repository', $baseurl);