From 61c923a07afbbea7b5a82f9dd96d26b14c537b35 Mon Sep 17 00:00:00 2001 From: Dmitrii Metelkin Date: Wed, 6 Mar 2024 11:25:12 +1100 Subject: [PATCH] issue #6: add rule related events --- classes/event/rule_created.php | 74 +++++++++++++++++++++++++++++++ classes/event/rule_deleted.php | 74 +++++++++++++++++++++++++++++++ classes/event/rule_updated.php | 75 ++++++++++++++++++++++++++++++++ classes/rule_manager.php | 10 ++++- lang/en/tool_dynamic_cohorts.php | 3 ++ tests/rule_manager_test.php | 66 +++++++++++++++++++++++++++- 6 files changed, 300 insertions(+), 2 deletions(-) create mode 100644 classes/event/rule_created.php create mode 100644 classes/event/rule_deleted.php create mode 100644 classes/event/rule_updated.php diff --git a/classes/event/rule_created.php b/classes/event/rule_created.php new file mode 100644 index 0000000..34a3b04 --- /dev/null +++ b/classes/event/rule_created.php @@ -0,0 +1,74 @@ +. + +namespace tool_dynamic_cohorts\event; + +use core\event\base; + + /** + * Event triggered when a rule created. + * + * @property-read array $other { + * Extra information about event. + * - string ruleid: new rule id. + * } + * + * @package tool_dynamic_cohorts + * @copyright 2024 Catalyst IT + * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class rule_created extends base { + + /** + * Initialise the rule data. + */ + protected function init() { + $this->data['edulevel'] = self::LEVEL_OTHER; + $this->data['crud'] = 'u'; + $this->context = \context_system::instance(); + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name(): string { + return get_string('event:rulecreated', 'tool_dynamic_cohorts'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description(): string { + return "User with id '{$this->userid}' created a dynamic cohort rule with id '{$this->other['ruleid']}'"; + } + + /** + * Validates the custom data. + * + * @throws \coding_exception if missing required data. + */ + protected function validate_data() { + parent::validate_data(); + + if (!isset($this->other['ruleid'])) { + throw new \coding_exception('The \'ruleid\' value must be set in other.'); + } + } +} diff --git a/classes/event/rule_deleted.php b/classes/event/rule_deleted.php new file mode 100644 index 0000000..1ccf9cb --- /dev/null +++ b/classes/event/rule_deleted.php @@ -0,0 +1,74 @@ +. + +namespace tool_dynamic_cohorts\event; + +use core\event\base; + + /** + * Event triggered when a rule deleted. + * + * @property-read array $other { + * Extra information about event. + * - string ruleid: deleted rule id. + * } + * + * @package tool_dynamic_cohorts + * @copyright 2024 Catalyst IT + * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class rule_deleted extends base { + + /** + * Initialise the rule data. + */ + protected function init() { + $this->data['edulevel'] = self::LEVEL_OTHER; + $this->data['crud'] = 'u'; + $this->context = \context_system::instance(); + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name(): string { + return get_string('event:ruledeleted', 'tool_dynamic_cohorts'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description(): string { + return "User with id '{$this->userid}' deleted a dynamic cohort rule with id '{$this->other['ruleid']}'"; + } + + /** + * Validates the custom data. + * + * @throws \coding_exception if missing required data. + */ + protected function validate_data() { + parent::validate_data(); + + if (!isset($this->other['ruleid'])) { + throw new \coding_exception('The \'ruleid\' value must be set in other.'); + } + } +} diff --git a/classes/event/rule_updated.php b/classes/event/rule_updated.php new file mode 100644 index 0000000..ce96f71 --- /dev/null +++ b/classes/event/rule_updated.php @@ -0,0 +1,75 @@ +. + +namespace tool_dynamic_cohorts\event; + +use core\event\base; + + /** + * Event triggered when a rule updated. + * + * @property-read array $other { + * Extra information about event. + * - string ruleid: updated rule id. + * } + * + * @package tool_dynamic_cohorts + * @copyright 2024 Catalyst IT + * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class rule_updated extends base { + + /** + * Initialise the rule data. + */ + protected function init() { + $this->data['edulevel'] = self::LEVEL_OTHER; + $this->data['crud'] = 'u'; + $this->context = \context_system::instance(); + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name(): string { + return get_string('event:ruleupdated', 'tool_dynamic_cohorts'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description(): string { + return "User with id '{$this->userid}' updated a dynamic cohort rule with id '{$this->other['ruleid']}'"; + } + + /** + * Validates the custom data. + * + * @throws \coding_exception if missing required data. + */ + protected function validate_data() { + parent::validate_data(); + + if (!isset($this->other['ruleid'])) { + throw new \coding_exception('The \'ruleid\' value must be set in other.'); + } + } + +} diff --git a/classes/rule_manager.php b/classes/rule_manager.php index 3cfd2d7..8ba07af 100644 --- a/classes/rule_manager.php +++ b/classes/rule_manager.php @@ -18,6 +18,9 @@ use moodle_url; use moodle_exception; +use tool_dynamic_cohorts\event\rule_created; +use tool_dynamic_cohorts\event\rule_deleted; +use tool_dynamic_cohorts\event\rule_updated; defined('MOODLE_INTERNAL') || die(); @@ -96,11 +99,13 @@ public static function process_form(\stdClass $formdata): rule { if (empty($formdata->id)) { $rule = new rule(0, $ruledata); $rule->create(); + rule_created::create(['other' => ['ruleid' => $rule->get('id')]])->trigger(); } else { $rule = new rule($formdata->id); $oldcohortid = $rule->get('cohortid'); $rule->from_record($ruledata); $rule->update(); + rule_updated::create(['other' => ['ruleid' => $rule->get('id')]])->trigger(); } cohort_manager::unmanage_cohort($oldcohortid); @@ -145,10 +150,13 @@ private static function validate_submitted_data(\stdClass $formdata): void { * * @param rule $rule */ - public static function delete_rule(rule $rule) { + public static function delete_rule(rule $rule): void { + $oldruleid = $rule->get('id'); $conditions = $rule->get_condition_records(); if ($rule->delete()) { + rule_deleted::create(['other' => ['ruleid' => $oldruleid]])->trigger(); + // Delete related condition in a loop to be able to trigger events. foreach ($conditions as $condition) { $condition->delete(); diff --git a/lang/en/tool_dynamic_cohorts.php b/lang/en/tool_dynamic_cohorts.php index 392d125..83bde56 100644 --- a/lang/en/tool_dynamic_cohorts.php +++ b/lang/en/tool_dynamic_cohorts.php @@ -42,6 +42,9 @@ $string['edit_rule'] = 'Edit rule'; $string['enabled'] = 'Enabled'; $string['enable_confirm'] = 'Are you sure you want to enable rule {$a}?'; +$string['event:rulecreated'] = 'Rule created'; +$string['event:ruleupdated'] = 'Rule updated'; +$string['event:ruledeleted'] = 'Rule deleted'; $string['managerules'] = 'Manage rules'; $string['managecohorts'] = 'Manage cohorts'; $string['name'] = 'Rule name'; diff --git a/tests/rule_manager_test.php b/tests/rule_manager_test.php index 3402993..60bfcd8 100644 --- a/tests/rule_manager_test.php +++ b/tests/rule_manager_test.php @@ -18,6 +18,9 @@ use moodle_url; use moodle_exception; +use tool_dynamic_cohorts\event\rule_created; +use tool_dynamic_cohorts\event\rule_deleted; +use tool_dynamic_cohorts\event\rule_updated; /** * Tests for rule manager class. @@ -255,7 +258,7 @@ public function test_process_rule_form_with_cohort_managed_by_another_rule() { } /** - * Test trying to submit form data and not updating the cohort. + * Test submitting form data keeps cohort. */ public function test_process_rule_form_update_rule_form_keeping_cohort() { global $DB; @@ -273,6 +276,43 @@ public function test_process_rule_form_update_rule_form_keeping_cohort() { $formdata = ['id' => $rule->get('id'), 'name' => 'Test1', 'cohortid' => $cohort->id, 'description' => 'D', 'conditionjson' => '', 'bulkprocessing' => 1]; rule_manager::process_form((object)$formdata); + + $this->assertEquals('tool_dynamic_cohorts', $DB->get_field('cohort', 'component', ['id' => $cohort->id])); + } + + /** + * Test triggering events. + */ + public function test_process_rule_form_triggers_events() { + $this->resetAfterTest(); + + $cohort = $this->getDataGenerator()->create_cohort(); + + $eventsink = $this->redirectEvents(); + $formdata = ['name' => 'Test1', 'cohortid' => $cohort->id, 'description' => 'D', + 'conditionjson' => '', 'bulkprocessing' => 1]; + $rule = rule_manager::process_form((object) $formdata); + + $events = array_filter($eventsink->get_events(), function ($event) { + return $event instanceof rule_created; + }); + + $this->assertCount(1, $events); + $this->assertEquals($rule->get('id'), reset($events)->other['ruleid']); + $eventsink->clear(); + + // Update the rule, changing the name. Should work as cohort is the same. + $formdata = ['id' => $rule->get('id'), 'name' => 'Test1', + 'cohortid' => $cohort->id, 'description' => 'D', 'conditionjson' => '', 'bulkprocessing' => 1]; + rule_manager::process_form((object) $formdata); + + $events = array_filter($eventsink->get_events(), function ($event) { + return $event instanceof rule_updated; + }); + + $this->assertCount(1, $events); + $this->assertEquals($rule->get('id'), reset($events)->other['ruleid']); + $eventsink->clear(); } /** @@ -346,4 +386,28 @@ public function test_deleting_rule_releases_cohorts() { rule_manager::delete_rule($rule2); $this->assertEquals('', $DB->get_field('cohort', 'component', ['id' => $cohort2->id])); } + + /** + * Test deleting a rule triggers event. + */ + public function test_deleting_rule_triggers_event() { + $this->resetAfterTest(); + + $cohort = $this->getDataGenerator()->create_cohort(['component' => 'tool_dynamic_cohorts']); + + $rule = new rule(0, (object)['name' => 'Test rule', 'cohortid' => $cohort->id]); + $rule->save(); + $expectedruleid = $rule->get('id'); + + $eventsink = $this->redirectEvents(); + + rule_manager::delete_rule($rule); + + $events = array_filter($eventsink->get_events(), function ($event) { + return $event instanceof rule_deleted; + }); + + $this->assertCount(1, $events); + $this->assertEquals($expectedruleid, reset($events)->other['ruleid']); + } }