diff --git a/.upgradenotes/MDL-79011-2024081603161496.yml b/.upgradenotes/MDL-79011-2024081603161496.yml new file mode 100644 index 00000000000..8b109af88f5 --- /dev/null +++ b/.upgradenotes/MDL-79011-2024081603161496.yml @@ -0,0 +1,7 @@ +issueNumber: MDL-79011 +notes: + core: + - message: >- + The `after_config()` callback has been converted to a hook, + `\core\hook\after_config`. + type: improved diff --git a/admin/tool/mfa/classes/hook_callbacks.php b/admin/tool/mfa/classes/hook_callbacks.php new file mode 100644 index 00000000000..af7cec79cb7 --- /dev/null +++ b/admin/tool/mfa/classes/hook_callbacks.php @@ -0,0 +1,56 @@ +. + +namespace tool_mfa; + +use core\hook\after_config; + +/** + * Callbacks for hooks. + * + * @package tool_mfa + * @copyright 2024 Andrew Lyons + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class hook_callbacks { + /** + * Listener for the after_config hook. + * + * @param after_config $hook + */ + public static function after_config(\core\hook\after_config $hook): void { + global $CFG, $SESSION; + + if (during_initial_install() || isset($CFG->upgraderunning)) { + // Do nothing during installation or upgrade. + return; + } + + // Tests for hooks being fired to test patches. + // Store in $CFG, $SESSION not present at this point. + if (PHPUNIT_TEST) { + $CFG->mfa_config_hook_test = true; + } + + // Check for not logged in. + if (isloggedin() && !isguestuser()) { + // If not authenticated, force login required. + if (empty($SESSION->tool_mfa_authenticated)) { + \tool_mfa\manager::require_auth(); + } + } + } +} diff --git a/admin/tool/mfa/db/hooks.php b/admin/tool/mfa/db/hooks.php index ae8576cddb0..e6f91b4cd10 100644 --- a/admin/tool/mfa/db/hooks.php +++ b/admin/tool/mfa/db/hooks.php @@ -27,7 +27,11 @@ defined('MOODLE_INTERNAL') || die(); $callbacks = [ [ 'hook' => core_user\hook\extend_bulk_user_actions::class, - 'callback' => 'tool_mfa\local\hooks\extend_bulk_user_actions::callback', + 'callback' => [\tool_mfa\local\hooks\extend_bulk_user_actions::class, 'callback'], 'priority' => 0, ], + [ + 'hook' => \core\hook\after_config::class, + 'callback' => [\tool_mfa\hook_callbacks::class, 'after_config'], + ], ]; diff --git a/admin/tool/mfa/lib.php b/admin/tool/mfa/lib.php index a7232ba5834..111a38c796a 100644 --- a/admin/tool/mfa/lib.php +++ b/admin/tool/mfa/lib.php @@ -106,6 +106,23 @@ function tool_mfa_after_config(): void { } } +/** + * Any plugin typically an admin tool can add new bulk user actions + * + * @return array + */ +function tool_mfa_bulk_user_actions(): array { + if (!has_capability('moodle/site:config', context_system::instance())) { + return []; + } + return [ + 'tool_mfa_reset_factors' => new action_link( + new moodle_url('/admin/tool/mfa/reset_factor.php'), + get_string('resetfactor', 'tool_mfa'), + ), + ]; +} + /** * Serves any files for the guidance page. * diff --git a/lib/classes/hook/after_config.php b/lib/classes/hook/after_config.php new file mode 100644 index 00000000000..e837d097f8d --- /dev/null +++ b/lib/classes/hook/after_config.php @@ -0,0 +1,49 @@ +. + +namespace core\hook; + +/** + * Class after_config + * + * @package core + * @copyright 2024 Andrew Lyons + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +#[\core\attribute\tags('configuration', 'core')] +#[\core\attribute\label('Allows plugins to perform actions immediately after configuration')] +#[\core\attribute\hook\replaces_callbacks('after_config')] +class after_config { + /** + * Process legacy callbacks. + */ + public function process_legacy_callbacks(): void { + $pluginswithfunction = get_plugins_with_function( + function: 'after_config', + migratedtohook: true, + ); + foreach ($pluginswithfunction as $plugins) { + foreach ($plugins as $function) { + try { + $function(); + } catch (\Throwable $e) { + debugging("Exception calling '$function'", DEBUG_DEVELOPER, $e->getTrace()); + } + } + } + + } +} diff --git a/lib/setup.php b/lib/setup.php index 0a14e5f3981..269c105bcaf 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -1195,13 +1195,6 @@ if (false) { initialise_local_config_cache(); // Allow plugins to callback as soon possible after setup.php is loaded. -$pluginswithfunction = get_plugins_with_function('after_config', 'lib.php'); -foreach ($pluginswithfunction as $plugins) { - foreach ($plugins as $function) { - try { - $function(); - } catch (Throwable $e) { - debugging("Exception calling '$function'", DEBUG_DEVELOPER, $e->getTrace()); - } - } -} +$afterconfighook = new \core\hook\after_config(); +$afterconfighook->process_legacy_callbacks(); +\core\di::get(\core\hook\manager::class)->dispatch($afterconfighook);