diff --git a/classes/helper.php b/classes/helper.php index 48ef85b..6d599b6 100644 --- a/classes/helper.php +++ b/classes/helper.php @@ -21,6 +21,7 @@ use tool_dynamic_cohorts\cohort_manager; use tool_dynamic_cohorts\condition_base; use tool_dynamic_cohorts\rule; +use tool_dynamic_cohorts\rule_manager; defined('MOODLE_INTERNAL') || die(); @@ -76,7 +77,7 @@ class helper { public const STUDENT_ROLE = 'student'; /** - * Set up configuration item. + * Add a new configuration item. * * @param int $itemid Item ID number * @param string $itemtype Item type (tag, course, category). @@ -84,7 +85,7 @@ class helper { * @param stdClass|null $course Course to set up enrolment method. If not set, the no enrolment method will be created. * @return void */ - public static function set_up_item(int $itemid, string $itemtype, string $itemname, ?stdClass $course = null): void { + public static function add_item(int $itemid, string $itemtype, string $itemname, ?stdClass $course = null): void { $cohort = self::get_cohort_by_item($itemid, $itemtype); if (empty($cohort)) { @@ -105,7 +106,7 @@ public static function set_up_item(int $itemid, string $itemtype, string $itemna // Create a dynamic cohort rule associated with this cohort. self::add_rule($cohort, $itemtype); // Add a tag to a custom profile field. - self::update_profile_field($itemtype, $itemname); + self::add_profile_field_item($itemtype, $itemname); // Create enrolment method for the cohort for a given course. if (!empty($course)) { @@ -113,6 +114,36 @@ public static function set_up_item(int $itemid, string $itemtype, string $itemna } } + /** + * Remove configuration item. + * + * @param int $itemid Item ID number + * @param string $itemtype Item type (tag, course, category). + * @param string $itemname Item name. + * @return void + */ + public static function remove_item(int $itemid, string $itemtype, string $itemname): void { + global $DB; + + // Find cohort. + $cohort = self::get_cohort_by_item($itemid, $itemtype); + if ($cohort) { + // Find all courses with this cohort and delete enrolment method. + self::remove_enrolment_method($itemid, $itemtype); + // Find a rule with this cohort and delete rule and conditions. + $rules = $DB->get_records('tool_dynamic_cohorts', ['cohortid' => $cohort->id]); + foreach ($rules as $rule) { + $rule = rule::get_record(['id' => $rule->id]); + rule_manager::delete_rule($rule); + } + // Delete cohort. + cohort_delete_cohort($cohort); + // Delete tag value from custom profile field list. + self::delete_profile_field_item($itemtype, $itemname); + // Clean up user data? + } + } + /** * Get cohort by provided item type and item id. * @@ -173,11 +204,11 @@ public static function add_enrolment_method(stdClass $course, stdClass $cohort): /** * A helper to remove enrolment method from a given course based on item details. * - * @param stdClass $course Given course. * @param int $itemid Item ID. * @param string $itemtype Item type (tag, course, category). + * @param int $courseid Optional course ID. */ - public static function remove_enrolment_method(stdClass $course, int $itemid, string $itemtype): void { + public static function remove_enrolment_method(int $itemid, string $itemtype, int $courseid = 0): void { global $DB; $cohort = self::get_cohort_by_item($itemid, $itemtype); @@ -189,9 +220,12 @@ public static function remove_enrolment_method(stdClass $course, int $itemid, st 'enrol' => 'cohort', 'customint1' => $cohort->id, 'roleid' => $studentrole->id, - 'courseid' => $course->id, ]; + if (!empty($courseid)) { + $fields['courseid'] = $courseid; + } + $instances = $DB->get_records('enrol', $fields); if ($instances) { @@ -213,20 +247,51 @@ public static function remove_enrolment_method(stdClass $course, int $itemid, st * * @return void */ - public static function update_profile_field(string $shortname, string $newitem): void { + public static function add_profile_field_item(string $shortname, string $newitem): void { global $DB; $field = $DB->get_record('user_info_field', ['shortname' => $shortname]); - $fielddata = []; - if (!empty($field->param1)) { - $fielddata = explode("\n", $field->param1); + + if ($field) { + $fielddata = []; + if (!empty($field->param1)) { + $fielddata = explode("\n", $field->param1); + } + + if (!in_array($newitem, $fielddata)) { + $fielddata[] = $newitem; + sort($fielddata); + $field->param1 = implode("\n", $fielddata); + $DB->update_record('user_info_field', $field); + } } + } - if (!in_array($newitem, $fielddata)) { - $fielddata[] = $newitem; - sort($fielddata); - $field->param1 = implode("\n", $fielddata); - $DB->update_record('user_info_field', $field); + /** + * Delete a given item from profile field. + * + * @param string $shortname Field short name. + * @param string $itemname A new item to add to the field. + * + * @return void + */ + public static function delete_profile_field_item(string $shortname, string $itemname): void { + global $DB; + + $field = $DB->get_record('user_info_field', ['shortname' => $shortname]); + if ($field) { + $fielddata = []; + if (!empty($field->param1)) { + $fielddata = explode("\n", $field->param1); + } + + if (in_array($itemname, $fielddata)) { + $key = array_search($itemname, $fielddata); + unset($fielddata[$key]); + sort($fielddata); + $field->param1 = implode("\n", $fielddata); + $DB->update_record('user_info_field', $field); + } } } diff --git a/classes/observer.php b/classes/observer.php index 570c9ba..46b4cbf 100644 --- a/classes/observer.php +++ b/classes/observer.php @@ -20,6 +20,9 @@ use core\event\course_created; use core\event\tag_added; use core\event\tag_removed; +use core\event\tag_deleted; +use tool_dynamic_cohorts\rule; +use tool_dynamic_cohorts\rule_manager; /** * Event observer class. @@ -46,7 +49,7 @@ public static function tag_added(tag_added $event): void { $tagname = $event->other['tagrawname']; $course = get_course($event->other['itemid']); - helper::set_up_item($tagid, helper::ITEM_TYPE_TAG, $tagname, $course); + helper::add_item($tagid, helper::ITEM_TYPE_TAG, $tagname, $course); } /** @@ -63,7 +66,18 @@ public static function tag_removed(tag_removed $event): void { $tagid = $event->other['tagid']; $course = get_course($event->other['itemid']); - helper::remove_enrolment_method($course, $tagid, helper::ITEM_TYPE_TAG); + helper::remove_enrolment_method($tagid, helper::ITEM_TYPE_TAG, $course->id); + } + + /** + * Process tag_deleted event. + * + * @param tag_deleted $event The event. + */ + public static function tag_deleted(tag_deleted $event): void { + $tagid = $event->objectid; + $tagname = $event->other['rawname']; + helper::remove_item($tagid, helper::ITEM_TYPE_TAG, $tagname); } /** @@ -75,10 +89,10 @@ public static function course_created(course_created $event): void { global $DB; $course = get_course($event->courseid); - helper::set_up_item($course->id, helper::ITEM_TYPE_COURSE, $course->{helper::COURSE_NAME}, $course); + helper::add_item($course->id, helper::ITEM_TYPE_COURSE, $course->{helper::COURSE_NAME}, $course); $category = $DB->get_record('course_categories', ['id' => $course->category]); - helper::set_up_item($category->id, helper::ITEM_TYPE_CATEGORY, $category->name, $course); + helper::add_item($category->id, helper::ITEM_TYPE_CATEGORY, $category->name, $course); } /** @@ -90,6 +104,6 @@ public static function course_category_created(course_category_created $event): global $DB; $category = $DB->get_record('course_categories', ['id' => $event->objectid]); - helper::set_up_item($category->id, helper::ITEM_TYPE_CATEGORY, $category->name); + helper::add_item($category->id, helper::ITEM_TYPE_CATEGORY, $category->name); } } diff --git a/db/events.php b/db/events.php index b1867ec..97c899d 100644 --- a/db/events.php +++ b/db/events.php @@ -29,6 +29,14 @@ 'eventname' => '\core\event\tag_added', 'callback' => '\tool_enrolprofile\observer::tag_added', ], + [ + 'eventname' => '\core\event\tag_removed', + 'callback' => '\tool_enrolprofile\observer::tag_removed', + ], + [ + 'eventname' => '\core\event\tag_deleted', + 'callback' => '\tool_enrolprofile\observer::tag_deleted', + ], [ 'eventname' => '\core\event\course_created', 'callback' => '\tool_enrolprofile\observer::course_created', @@ -37,8 +45,5 @@ 'eventname' => '\core\event\course_category_created', 'callback' => '\tool_enrolprofile\observer::course_category_created', ], - [ - 'eventname' => '\core\event\tag_removed', - 'callback' => '\tool_enrolprofile\observer::tag_removed', - ], + ]; diff --git a/tests/observer_test.php b/tests/observer_test.php index 14f334b..da2a7fe 100644 --- a/tests/observer_test.php +++ b/tests/observer_test.php @@ -195,6 +195,50 @@ public function test_tag_removed(): void { $this->assertEmpty($enrol); } + /** + * Check logic when deleting a tag. + */ + public function test_tag_deleted(): void { + global $DB; + + $course = $this->getDataGenerator()->create_course(); + $tagname = 'A tag'; + + core_tag_tag::set_item_tags('core', 'course', $course->id, context_course::instance($course->id), [$tagname]); + + $cohort = $DB->get_record('cohort', ['name' => $tagname]); + $enrol = $DB->get_record('enrol', ['courseid' => $course->id, 'enrol' => 'cohort', 'customint1' => $cohort->id]); + $this->assertNotEmpty($enrol); + + $tag = $DB->get_record('tag', ['rawname' => $tagname]); + $this->assertNotEmpty($tag); + + $profilefielddata = $DB->get_field('user_info_field', 'param1', ['id' => $this->tagprofilefield->id]); + $this->assertNotEmpty($profilefielddata); + $this->assertTrue(in_array($tagname, explode("\n", $profilefielddata))); + + $rule = $DB->get_record('tool_dynamic_cohorts', ['name' => $tagname]); + $this->assertNotEmpty($rule); + $conditions = $DB->get_records('tool_dynamic_cohorts_c', ['ruleid' => $rule->id]); + $this->assertCount(2, $conditions); + + core_tag_tag::delete_tags([$tag->id]); + + // Tag deleted. + $this->assertEmpty($DB->get_record('tag', ['rawname' => $tagname])); + // Cohort deleted. + $this->assertEmpty($DB->get_record('cohort', ['name' => $tagname])); + // Enrolment methods deleted. + $this->assertEmpty($DB->get_records('enrol', ['enrol' => 'cohort', 'customint1' => $cohort->id])); + // Rule and conditions deleted. + $this->assertEmpty($DB->get_record('tool_dynamic_cohorts', ['name' => $tagname])); + $this->assertEmpty($DB->get_record('tool_dynamic_cohorts', ['cohortid' => $cohort->id])); + $this->assertEmpty($DB->get_records('tool_dynamic_cohorts_c', ['ruleid' => $rule->id])); + // Profile field data updated. + $profilefielddata = $DB->get_field('user_info_field', 'param1', ['id' => $this->tagprofilefield->id]); + $this->assertTrue(!in_array($tagname, explode("\n", $profilefielddata))); + } + /** * Check logic when creating a course. */