When a step closes a popup window the page DOM is not available
until we switch again to the main window; we should avoid exceptions
at framework level when hooking the after step process, this
includes the new exceptions catcher modification.
get_plugin_list was calling clean_param($pluginname, PARAM_PLUGIN) a
lot (600+ times per page), and that is much slower than you would guess.
A specific function for this case, (which we then also use from
clean_param) is a performance win.
These changes give about a 10% speed-up in this function. The significant changes are:
1. Simplify the if logic to remove unnecssary cases.
2. Dont pass default argument values to htmlspecialchars, just using the
defaults is faster.
3. I can confirm that /i regex is faster than the equivalent regex without the i.
I also added more unit tests to test the edge cases.
I also broke the unit tests into more, smaller, named tests, so that
when things start failing, more tests are run, and it is clearer what
the problem is.
In a couple of cases, I adjusted the $ideal lenght in the test. A
careful counting of the characters in the test input (added as comments)
suggests that the new values make for better tests.
If the plugin has been only deployed to the disk without installing into
the database, do not allow going through the uninstallation procedure.
Not only it does not have much sense. But it can also lead to some
tricky situation due to dependencies. Better to block it and wait till
the plugin is either fully installed or removed from the disk.
The get_uninstall_url() method of all subclasses of plugininfo_base
class is now expected to always return moodle_url. Subclasses can use
the new method is_uninstall_allowed() to control the availability of the
'Uninstall' link at the Plugins overview page (previously they would do
it by get_uninstall_url() returning null). By default, URL to a new
general plugin uninstall tool is returned. Unless the plugin type needs
extra steps that can't be handled by plugininfo_xxx::uninstall() method
or xmldb_xxx_uninstall() function, this default URL should satisfy all
plugin types.
The overall logic is implemented in plugin_manager::can_install_plugin()
that respects the plugininfo class decision and vetoes it in certain
cases (typically when plugin or its subplugin is required by some other
plugin).
This patch improves and adds unit tests for the plugin_manager class.
These unit tests cover the existing functionalities. Tests for the
new features related directly with MDL-38259 will be added in a separate
commit (to make it clear what's related to it).