This commit is contained in:
Jun Pataleta 2024-04-17 23:42:22 +08:00
commit 9966241efb
No known key found for this signature in database
GPG key ID: F83510526D99E2C7
35 changed files with 127 additions and 204 deletions

View file

@ -16,7 +16,6 @@
namespace tool_mfa\hook;
use core\hook\described_hook;
use core\hook\stoppable_trait;
/**
@ -26,26 +25,10 @@ use core\hook\stoppable_trait;
* @copyright 2024 Juan Leyva
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
#[\core\attribute\label('Allow plugins to callback as soon possible after user has passed MFA.')]
#[\core\attribute\tags('user', 'login')]
class after_user_passed_mfa implements
described_hook,
\Psr\EventDispatcher\StoppableEventInterface {
\Psr\EventDispatcher\StoppableEventInterface
{
use stoppable_trait;
/**
* Describes the hook purpose.
*
* @return string
*/
public static function get_hook_description(): string {
return 'Allow plugins to callback as soon possible after user has passed MFA.';
}
/**
* List of tags that describe this hook.
*
* @return string[]
*/
public static function get_hook_tags(): array {
return ['login'];
}
}

View file

@ -16,6 +16,7 @@
namespace tool_mobile;
use core\session\utility\cookie_helper;
use html_writer;
/**
@ -78,4 +79,31 @@ class hook_callbacks {
html_writer::link($url, get_string('getmoodleonyourmobile', 'tool_mobile'), ['class' => 'mobilelink']),
);
}
/**
* Callback to recover $SESSION->wantsurl.
*
* @param \core_user\hook\after_login_completed $hook
*/
public static function after_login_completed(
\core_user\hook\after_login_completed $hook,
): void {
global $SESSION, $CFG;
// Check if the user is doing a mobile app launch, if that's the case, ensure $SESSION->wantsurl is correctly set.
if (!NO_MOODLE_COOKIES && !empty($_COOKIE['tool_mobile_launch'])) {
if (empty($SESSION->wantsurl) || strpos($SESSION->wantsurl, '/tool/mobile/launch.php') === false) {
$params = json_decode($_COOKIE['tool_mobile_launch'], true);
$SESSION->wantsurl = (new \moodle_url("/$CFG->admin/tool/mobile/launch.php", $params))->out(false);
}
}
// Set Partitioned and Secure attributes to the MoodleSession cookie if the user is using the Moodle app.
if (\core_useragent::is_moodle_app()) {
cookie_helper::add_attributes_to_cookie_response_header(
'MoodleSession' . $CFG->sessioncookie,
['Secure', 'Partitioned'],
);
}
}
}

View file

@ -1,49 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace tool_mobile\local\hooks\user;
use core\session\utility\cookie_helper;
/**
* Handles mobile app launches when a third-party auth plugin did not properly set $SESSION->wantsurl.
*
* @package tool_mobile
* @copyright 2024 Juan Leyva
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class after_complete_login {
/**
* Callback to recover $SESSION->wantsurl.
*
* @param \core\hook\user\after_complete_login $hook
*/
public static function callback(\core\hook\user\after_complete_login $hook): void {
global $SESSION, $CFG;
// Check if the user is doing a mobile app launch, if that's the case, ensure $SESSION->wantsurl is correctly set.
if (!NO_MOODLE_COOKIES && !empty($_COOKIE['tool_mobile_launch'])) {
if (empty($SESSION->wantsurl) || strpos($SESSION->wantsurl, '/tool/mobile/launch.php') === false) {
$params = json_decode($_COOKIE['tool_mobile_launch'], true);
$SESSION->wantsurl = (new \moodle_url("/$CFG->admin/tool/mobile/launch.php", $params))->out(false);
}
}
// Set Partitioned and Secure attributes to the MoodleSession cookie if the user is using the Moodle app.
if (\core_useragent::is_moodle_app()) {
cookie_helper::add_attributes_to_cookie_response_header('MoodleSession'.$CFG->sessioncookie, ['Secure', 'Partitioned']);
}
}
}

View file

@ -35,8 +35,8 @@ $callbacks = [
'priority' => 0,
],
[
'hook' => core\hook\user\after_complete_login::class,
'callback' => 'tool_mobile\local\hooks\user\after_complete_login::callback',
'hook' => \core_user\hook\after_login_completed::class,
'callback' => [\tool_mobile\hook_callbacks::class, 'after_login_completed'],
'priority' => 500,
],
[

View file

@ -19,13 +19,13 @@ namespace core_communication;
use context_course;
use core\hook\access\after_role_assigned;
use core\hook\access\after_role_unassigned;
use core_enrol\hook\before_enrol_instance_delete;
use core_enrol\hook\before_enrol_instance_deleted;
use core_enrol\hook\after_enrol_instance_status_updated;
use core_enrol\hook\after_user_enrolled;
use core_enrol\hook\before_user_enrolment_update;
use core_enrol\hook\before_user_enrolment_remove;
use core_enrol\hook\before_user_enrolment_updated;
use core_enrol\hook\before_user_enrolment_removed;
use core_course\hook\after_course_created;
use core_course\hook\before_course_delete;
use core_course\hook\before_course_deleted;
use core_course\hook\after_course_updated;
use core_group\hook\after_group_created;
use core_group\hook\after_group_deleted;
@ -33,7 +33,7 @@ use core_group\hook\after_group_membership_added;
use core_group\hook\after_group_membership_removed;
use core_group\hook\after_group_updated;
use core_user\hook\before_user_deleted;
use core_user\hook\before_user_update;
use core_user\hook\before_user_updated;
/**
* Hook listener for communication api.
@ -345,10 +345,10 @@ class hook_listener {
* Course can have communication data if it is a group or a course.
* This action is important to perform even if the experimental feature is disabled.
*
* @param before_course_delete $hook The course deleted hook.
* @param before_course_deleted $hook The course deleted hook.
*/
public static function delete_course_communication(
before_course_delete $hook,
before_course_deleted $hook,
): void {
// If the communication subsystem is not enabled then just ignore.
if (!api::is_available()) {
@ -382,10 +382,10 @@ class hook_listener {
/**
* Update the room membership for the user updates.
*
* @param before_user_update $hook The user updated hook.
* @param before_user_updated $hook The user updated hook.
*/
public static function update_user_room_memberships(
before_user_update $hook,
before_user_updated $hook,
): void {
// If the communication subsystem is not enabled then just ignore.
if (!api::is_available()) {
@ -533,10 +533,10 @@ class hook_listener {
/**
* Remove the communication instance memberships when an enrolment instance is deleted.
*
* @param before_enrol_instance_delete $hook The enrol instance deleted hook.
* @param before_enrol_instance_deleted $hook The enrol instance deleted hook.
*/
public static function remove_communication_memberships_for_enrol_instance_deletion(
before_enrol_instance_delete $hook,
before_enrol_instance_deleted $hook,
): void {
// If the communication subsystem is not enabled then just ignore.
if (!api::is_available()) {
@ -591,10 +591,10 @@ class hook_listener {
/**
* Update the communication instance membership for the user enrolment updates.
*
* @param before_user_enrolment_update $hook The user enrolment updated hook.
* @param before_user_enrolment_updated $hook The user enrolment updated hook.
*/
public static function update_communication_membership_for_updated_user_enrolment(
before_user_enrolment_update $hook,
before_user_enrolment_updated $hook,
): void {
// If the communication subsystem is not enabled then just ignore.
if (!api::is_available()) {
@ -630,10 +630,10 @@ class hook_listener {
/**
* Remove communication instance membership for an enrolled user.
*
* @param before_user_enrolment_remove $hook The user unenrolled hook.
* @param before_user_enrolment_removed $hook The user unenrolled hook.
*/
public static function remove_communication_membership_for_unenrolled_user(
before_user_enrolment_remove $hook,
before_user_enrolment_removed $hook,
): void {
// If the communication subsystem is not enabled then just ignore.
if (!api::is_available()) {

View file

@ -30,13 +30,13 @@ use stdClass;
#[\core\attribute\label('Allows plugins or features to perform actions after a course is created.')]
#[\core\attribute\tags('course')]
class after_course_created {
/**
* Constructor for the hook.
*
* @param stdClass $course The course instance.
*/
public function __construct(
/** @var stdClass The course instance */
public readonly stdClass $course,
) {
}

View file

@ -28,7 +28,6 @@ use stdClass;
#[\core\attribute\label('Allows plugins or features to perform actions after a course is updated.')]
#[\core\attribute\tags('course')]
class after_course_updated {
/**
* Constructor for the hook.
*
@ -37,8 +36,11 @@ class after_course_updated {
* @param bool $changeincoursecat Whether the course category has changed.
*/
public function __construct(
/** @var stdClass The course instance */
public readonly stdClass $course,
/** @var stdClass The old course instance */
public readonly stdClass $oldcourse,
/** @var bool Whether the course category has changed */
public readonly bool $changeincoursecat = false,
) {
}

View file

@ -28,13 +28,10 @@ use Psr\EventDispatcher\StoppableEventInterface;
*/
#[\core\attribute\label('Allows plugins or features to perform actions before a course is deleted.')]
#[\core\attribute\tags('course')]
class before_course_delete implements
StoppableEventInterface {
/**
* @var bool Whether the propagation of this event has been stopped.
*/
protected bool $stopped = false;
class before_course_deleted implements
StoppableEventInterface
{
use \core\hook\stoppable_trait;
/**
* Constructor for the hook.
@ -42,18 +39,8 @@ class before_course_delete implements
* @param stdClass $course The course instance.
*/
public function __construct(
/** @var stdClass The course instance */
public readonly stdClass $course,
) {
}
public function isPropagationStopped(): bool {
return $this->stopped;
}
/**
* Stop the propagation of this event.
*/
public function stop(): void {
$this->stopped = true;
}
}

View file

@ -34,7 +34,9 @@ class after_cm_name_edited implements described_hook {
* @param string $newname the new name
*/
public function __construct(
/** @var cm_info the course module */
protected cm_info $cm,
/** @var string the new name */
protected string $newname,
) {
}

View file

@ -28,7 +28,6 @@ use stdClass;
#[\core\attribute\label('Allows plugins or features to perform actions after the enrolment instance status is changed.')]
#[\core\attribute\tags('enrol')]
class after_enrol_instance_status_updated {
/**
* Constructor for the hook.
*
@ -36,7 +35,9 @@ class after_enrol_instance_status_updated {
* @param int $newstatus The new status.
*/
public function __construct(
/** @var stdClass The enrol instance */
public readonly stdClass $enrolinstance,
/** @var int The new status */
public readonly int $newstatus,
) {
}

View file

@ -28,7 +28,6 @@ use stdClass;
#[\core\attribute\label('Allows plugins or features to perform actions after a user is enrolled in a course.')]
#[\core\attribute\tags('enrol', 'user')]
class after_user_enrolled {
/**
* Constructor for the hook.
*
@ -36,7 +35,9 @@ class after_user_enrolled {
* @param stdClass $userenrolmentinstance The user enrolment instance.
*/
public function __construct(
/** @var stdClass The enrol instance */
public readonly stdClass $enrolinstance,
/** @var stdClass The user enrolment instance */
public readonly stdClass $userenrolmentinstance,
) {
}

View file

@ -27,14 +27,11 @@ use Psr\EventDispatcher\StoppableEventInterface;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
#[\core\attribute\label('Allows plugins or features to perform actions before the enrolment instance is deleted.')]
#[\core\attribute\tags('enrol')]
class before_enrol_instance_delete implements
StoppableEventInterface {
/**
* @var bool Whether the propagation of this event has been stopped.
*/
protected bool $stopped = false;
#[\core\attribute\tags('enrol', 'user')]
class before_enrol_instance_deleted implements
StoppableEventInterface
{
use \core\hook\stoppable_trait;
/**
* Constructor for the hook.
@ -42,18 +39,8 @@ class before_enrol_instance_delete implements
* @param stdClass $enrolinstance The enrol instance.
*/
public function __construct(
/** @var stdClass The enrol instance */
public readonly stdClass $enrolinstance,
) {
}
public function isPropagationStopped(): bool {
return $this->stopped;
}
/**
* Stop the propagation of this event.
*/
public function stop(): void {
$this->stopped = true;
}
}

View file

@ -21,14 +21,13 @@ use stdClass;
/**
* Hook before a user is un-enrolled from a course for an enrolment instance.
*
* @package core
* @package core_enrol
* @copyright 2024 Safat Shahin <safat.shahin@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
#[\core\attribute\label('Allows plugins or features to perform actions before a user enrolment is removed.')]
#[\core\attribute\tags('enrol', 'user')]
class before_user_enrolment_remove {
class before_user_enrolment_removed {
/**
* Constructor for the hook.
*
@ -36,7 +35,9 @@ class before_user_enrolment_remove {
* @param stdClass $userenrolmentinstance The user enrolment instance.
*/
public function __construct(
/** @var stdClass The enrol instance */
public readonly stdClass $enrolinstance,
/** @var stdClass The user enrolment instance */
public readonly stdClass $userenrolmentinstance,
) {
}

View file

@ -27,8 +27,7 @@ use stdClass;
*/
#[\core\attribute\label('Allows plugins or features to perform actions before a user enrolment is updated.')]
#[\core\attribute\tags('enrol', 'user')]
class before_user_enrolment_update {
class before_user_enrolment_updated {
/**
* Constructor for the hook.
*
@ -38,9 +37,13 @@ class before_user_enrolment_update {
* @param bool $timeendmodified Whether the time end of the enrolment has been modified.
*/
public function __construct(
/** @var stdClass The enrol instance */
public readonly stdClass $enrolinstance,
/** @var stdClass The user enrolment instance */
public readonly stdClass $userenrolmentinstance,
/** @var bool Whether the status of the enrolment has been modified */
public readonly bool $statusmodified,
/** @var bool Whether the time end of the enrolment has been modified */
public readonly bool $timeendmodified,
) {
}

View file

@ -28,13 +28,13 @@ use stdClass;
#[\core\attribute\label('Allows plugins or features to perform actions after a group is created.')]
#[\core\attribute\tags('group')]
class after_group_created {
/**
* Constructor for the hook.
*
* @param stdClass $groupinstance The group instance.
*/
public function __construct(
/** @var stdClass The group instance */
public readonly stdClass $groupinstance,
) {
}

View file

@ -28,13 +28,13 @@ use stdClass;
#[\core\attribute\label('Allows plugins or features to perform actions after a group is deleted.')]
#[\core\attribute\tags('group')]
class after_group_deleted {
/**
* Constructor for the hook.
*
* @param stdClass $groupinstance The group instance.
*/
public function __construct(
/** @var stdClass The group instance */
public readonly stdClass $groupinstance,
) {
}

View file

@ -28,7 +28,6 @@ use stdClass;
#[\core\attribute\label('Allows plugins or features to perform actions after members added to the group.')]
#[\core\attribute\tags('group', 'user')]
class after_group_membership_added {
/**
* Constructor for the hook.
*
@ -36,7 +35,9 @@ class after_group_membership_added {
* @param array $userids The user ids.
*/
public function __construct(
/** @var stdClass The group instance */
public readonly stdClass $groupinstance,
/** @var array The user ids */
public readonly array $userids,
) {
}

View file

@ -28,7 +28,6 @@ use stdClass;
#[\core\attribute\label('Allows plugins or features to perform actions after members removed from the group.')]
#[\core\attribute\tags('group', 'user')]
class after_group_membership_removed {
/**
* Constructor for the hook.
*
@ -36,7 +35,9 @@ class after_group_membership_removed {
* @param array $userids The user ids.
*/
public function __construct(
/** @var stdClass The group instance */
public readonly stdClass $groupinstance,
/** @var array The user ids */
public readonly array $userids,
) {
}

View file

@ -28,13 +28,13 @@ use stdClass;
#[\core\attribute\label('Allows plugins or features to perform actions after a group is updated.')]
#[\core\attribute\tags('group')]
class after_group_updated {
/**
* Constructor for the hook.
*
* @param stdClass $groupinstance The group instance.
*/
public function __construct(
/** @var stdClass The group instance */
public readonly stdClass $groupinstance,
) {
}

View file

@ -733,7 +733,7 @@ A callback with a higher priority will be called before one with lower priority.
$string['hookcallbacknotcallable'] = 'This callback is not callable. This could be because the class or method does not exist, or because the method is not public.';
$string['hookconfigoverride'] = 'Overridden';
$string['hookconfigoverride_help'] = 'The definition of this callback has been overridden in the site configuration file, config.php';
$string['hookdeprecates'] = 'Deprecated lib.php callbacks';
$string['hookdeprecates'] = 'Deprecated callbacks';
$string['hookdescription'] = 'Description';
$string['hookdescriptionmissing'] = 'Hook does not have a description method';
$string['hookclassmissing'] = 'Hook class not found';

View file

@ -26,18 +26,18 @@ use context;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
#[\core\attribute\label('Allows plugins or features to perform actions after a role is assigned to a user.')]
#[\core\attribute\tags('role,', 'user')]
#[\core\attribute\tags('role', 'user')]
class after_role_assigned {
/**
* Constructor for the hook.
*
* @param context $context The context of the role assignment.
* @param int $userid The user id of the user.
*
*/
public function __construct(
/** @var context The context of the role assignment */
public readonly context $context,
/** @var int The user id of the user */
public readonly int $userid,
) {
}

View file

@ -26,9 +26,8 @@ use context;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
#[\core\attribute\label('Allows plugins or features to perform actions after a role is unassigned for a user.')]
#[\core\attribute\tags('role,', 'user')]
#[\core\attribute\tags('role', 'user')]
class after_role_unassigned {
/**
* Constructor for the hook.
*
@ -37,7 +36,9 @@ class after_role_unassigned {
*
*/
public function __construct(
/** @var context The context of the role assignment */
public readonly context $context,
/** @var int The user id of the user */
public readonly int $userid,
) {
}

View file

@ -26,7 +26,7 @@ use core\attribute\label;
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
#[label('The DI container, which allows plugins to register any service requiring configuration or initialisation.')]
#[label('A hook to allow per-component configuration of the DI container.')]
class di_configuration {
/**
* Create the Dependency Injection configuration hook instance.
@ -34,6 +34,7 @@ class di_configuration {
* @param ContainerBuilder $builder
*/
public function __construct(
/** @var ContainerBuilder The PHP-DI Builder */
protected ContainerBuilder $builder,
) {
}

View file

@ -26,7 +26,7 @@ namespace core\hook\output;
*/
#[\core\attribute\tags('output')]
#[\core\attribute\label('Allows plugins to add any elements to the page &lt;head&gt; html tag.')]
#[\core\attribute\hook\replaces_callbacks('before_standard_html_head')]
#[\core\attribute\hook\replaces_callbacks('before_standard_top_of_body_html')]
final class before_standard_top_of_body_html_generation {
/**
* Hook to allow subscribers to add HTML content to the top of the page body.

View file

@ -54,11 +54,11 @@ $callbacks = [
'callback' => \core_communication\hook_listener::class . '::update_course_communication',
],
[
'hook' => \core_course\hook\before_course_delete::class,
'hook' => \core_course\hook\before_course_deleted::class,
'callback' => \core_communication\hook_listener::class . '::delete_course_communication',
],
[
'hook' => \core_user\hook\before_user_update::class,
'hook' => \core_user\hook\before_user_updated::class,
'callback' => \core_communication\hook_listener::class . '::update_user_room_memberships',
],
[
@ -78,7 +78,7 @@ $callbacks = [
'callback' => \core_communication\hook_listener::class . '::update_communication_memberships_for_enrol_status_change',
],
[
'hook' => \core_enrol\hook\before_enrol_instance_delete::class,
'hook' => \core_enrol\hook\before_enrol_instance_deleted::class,
'callback' => \core_communication\hook_listener::class . '::remove_communication_memberships_for_enrol_instance_deletion',
],
[
@ -86,11 +86,11 @@ $callbacks = [
'callback' => \core_communication\hook_listener::class . '::add_communication_membership_for_enrolled_user',
],
[
'hook' => \core_enrol\hook\before_user_enrolment_update::class,
'hook' => \core_enrol\hook\before_user_enrolment_updated::class,
'callback' => \core_communication\hook_listener::class . '::update_communication_membership_for_updated_user_enrolment',
],
[
'hook' => \core_enrol\hook\before_user_enrolment_remove::class,
'hook' => \core_enrol\hook\before_user_enrolment_removed::class,
'callback' => \core_communication\hook_listener::class . '::remove_communication_membership_for_unenrolled_user',
],
[

View file

@ -2237,7 +2237,7 @@ abstract class enrol_plugin {
}
// Dispatch the hook for pre user enrolment update actions.
$hook = new \core_enrol\hook\before_user_enrolment_update(
$hook = new \core_enrol\hook\before_user_enrolment_updated(
enrolinstance: $instance,
userenrolmentinstance: $ue,
statusmodified: $statusmodified,
@ -2297,7 +2297,7 @@ abstract class enrol_plugin {
}
// Dispatch the hook for pre user unenrolment actions.
$hook = new \core_enrol\hook\before_user_enrolment_remove(
$hook = new \core_enrol\hook\before_user_enrolment_removed(
enrolinstance: $instance,
userenrolmentinstance: $ue,
);
@ -2762,7 +2762,7 @@ abstract class enrol_plugin {
}
// Dispatch the hook for pre enrol instance delete actions.
$hook = new \core_enrol\hook\before_enrol_instance_delete(
$hook = new \core_enrol\hook\before_enrol_instance_deleted(
enrolinstance: $instance,
);
\core\di::get(\core\hook\manager::class)->dispatch($hook);

View file

@ -4097,7 +4097,7 @@ function complete_user_login($user, array $extrauserinfo = []) {
$event->trigger();
// Allow plugins to callback as soon possible after user has completed login.
di::get(\core\hook\manager::class)->dispatch(new \core\hook\user\after_complete_login());
di::get(\core\hook\manager::class)->dispatch(new \core_user\hook\after_login_completed());
// Check if the user is using a new browser or session (a new MoodleSession cookie is set in that case).
// If the user is accessing from the same IP, ignore everything (most of the time will be a new session in the same browser).
@ -4651,7 +4651,7 @@ function delete_course($courseorid, $showfeedback = true) {
}
// Dispatch the hook for pre course delete actions.
$hook = new \core_course\hook\before_course_delete(
$hook = new \core_course\hook\before_course_deleted(
course: $course,
);
\core\di::get(\core\hook\manager::class)->dispatch($hook);

View file

@ -607,7 +607,7 @@ class component_test extends advanced_testcase {
$this->assertCount(5, core_component::get_component_classes_in_namespace('core_user', 'output\\myprofile'));
// Without namespace it returns classes/ classes.
$this->assertCount(9, core_component::get_component_classes_in_namespace('tool_mobile', ''));
$this->assertCount(8, core_component::get_component_classes_in_namespace('tool_mobile', ''));
$this->assertCount(2, core_component::get_component_classes_in_namespace('tool_filetypes'));
// When no component is specified, classes are returned for the namespace in all components.

View file

@ -36,7 +36,9 @@ class attempt_state_changed {
* @param ?\stdClass $updatedattempt The updated database record of the new attempt, null if it has just been deleted.
*/
public function __construct(
/** @var ?\stdClass The original database record for the attempt, null if it has just been created. */
protected ?\stdClass $originalattempt,
/** @var ?\stdClass The updated database record of the new attempt, null if it has just been deleted. */
protected ?\stdClass $updatedattempt,
) {
if (is_null($this->originalattempt) && is_null($this->updatedattempt)) {

View file

@ -36,6 +36,7 @@ class structure_modified {
* @param structure $structure The new structure.
*/
public function __construct(
/** @var structure The new structure */
protected structure $structure
) {
}

View file

@ -14,38 +14,21 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core\hook\user;
namespace core_user\hook;
use core\hook\described_hook;
use core\hook\stoppable_trait;
/**
* Allow plugins to callback as soon possible after user has completed login.
*
* @package core
* @package core_user
* @copyright 2024 Juan Leyva
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class after_complete_login implements
described_hook,
\Psr\EventDispatcher\StoppableEventInterface {
#[\core\attribute\label('Allow plugins to callback as soon possible after user has completed login.')]
#[\core\attribute\tags('user', 'login')]
class after_login_completed implements
\Psr\EventDispatcher\StoppableEventInterface
{
use stoppable_trait;
/**
* Describes the hook purpose.
*
* @return string
*/
public static function get_hook_description(): string {
return 'Allow plugins to callback as soon possible after user has completed login.';
}
/**
* List of tags that describe this hook.
*
* @return string[]
*/
public static function get_hook_tags(): array {
return ['login'];
}
}

View file

@ -29,12 +29,9 @@ use Psr\EventDispatcher\StoppableEventInterface;
#[\core\attribute\label('Allows plugins or features to perform actions before a user is deleted.')]
#[\core\attribute\tags('user')]
class before_user_deleted implements
StoppableEventInterface {
/**
* @var bool Whether the propagation of this event has been stopped.
*/
protected bool $stopped = false;
StoppableEventInterface
{
use \core\hook\stoppable_trait;
/**
* Constructor for the hook.
@ -42,18 +39,8 @@ class before_user_deleted implements
* @param stdClass $user The user instance
*/
public function __construct(
/** @var stdClass The user instance */
public readonly stdClass $user,
) {
}
public function isPropagationStopped(): bool {
return $this->stopped;
}
/**
* Stop the propagation of this event.
*/
public function stop(): void {
$this->stopped = true;
}
}

View file

@ -27,8 +27,7 @@ use stdClass;
*/
#[\core\attribute\label('Allows plugins or features to perform actions before a user is updated.')]
#[\core\attribute\tags('user')]
class before_user_update {
class before_user_updated {
/**
* Constructor for the hook.
*
@ -36,7 +35,9 @@ class before_user_update {
* @param stdClass $currentuserdata The old user instance
*/
public function __construct(
/** @var stdClass The user instance */
public readonly stdClass $user,
/** @var stdClass The old user instance */
public readonly stdClass $currentuserdata,
) {
}

View file

@ -27,8 +27,7 @@ use core\hook\deprecated_callback_replacement;
* @copyright 2024 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class extend_bulk_user_actions implements described_hook, deprecated_callback_replacement {
class extend_bulk_user_actions implements deprecated_callback_replacement, described_hook {
/**
* Describes the hook purpose.
*
@ -56,7 +55,7 @@ class extend_bulk_user_actions implements described_hook, deprecated_callback_re
return ['bulk_user_actions'];
}
/** @var array $actions Stores all added user actions */
/** @var array Stores all added user actions */
private $actions = [];
/**

View file

@ -160,7 +160,7 @@ function user_update_user($user, $updatepassword = true, $triggerevent = true) {
$currentrecord = $DB->get_record('user', ['id' => $user->id]);
// Dispatch the hook for pre user update actions.
$hook = new \core_user\hook\before_user_update(
$hook = new \core_user\hook\before_user_updated(
user: $user,
currentuserdata: $currentrecord,
);