diff --git a/local/telconfig/classes/course_data_builder.php b/local/telconfig/classes/course_data_builder.php index b7db93fd8fa..f37e27a4bb4 100644 --- a/local/telconfig/classes/course_data_builder.php +++ b/local/telconfig/classes/course_data_builder.php @@ -40,7 +40,19 @@ public static function build_course_metadata($course): array { // Extract tags require_once($CFG->dirroot . '/tag/lib.php'); $tags = \core_tag_tag::get_item_tags('core', 'course', $course->id); - $keywords = array_map(fn($tag) => strtolower($tag->rawname), $tags); + $keywords = array_reduce($tags, function ($carry, $tag) { + return array_merge($carry, self::tokenise_keywords($tag->rawname)); + }, []); + + + // Merge in section and resource keywords + $keywords = array_merge( + $keywords, + self::get_section_keywords($course), + self::get_resource_keywords($course) + ); + + $keywords = array_values(array_unique($keywords)); // Prepare data $data = [ @@ -66,4 +78,65 @@ public static function build_course_metadata($course): array { return []; // Always return an array } } + + private static function get_section_keywords($course): array { + $keywords = []; + $modinfo = get_fast_modinfo($course); + $sections = $modinfo->get_section_info_all(); + + foreach ($sections as $section) { + // Skip hidden sections + if (!$section->uservisible || !$section->visible || empty($section->name)) { + continue; + } + + // Tokenise and merge keywords + $keywords = array_merge($keywords, self::tokenise_keywords($section->name)); + } + + return $keywords; + } + + private static function get_resource_keywords($course): array { + global $DB; + $keywords = []; + + // Now fetch all course modules from DB + $coursemodules = $DB->get_records('course_modules', ['course' => $course->id]); + + foreach ($coursemodules as $cm) { + // Skip deleted or hidden modules + if (!empty($cm->deletioninprogress) || empty($cm->visible)) { + continue; + } + + // Get module type (e.g., 'resource', 'quiz', etc.) + $module = $DB->get_record('modules', ['id' => $cm->module], '*', IGNORE_MISSING); + if (!$module) { + continue; + } + + // Dynamically get the module instance (e.g., from 'resource', 'quiz', etc.) + $instancetable = $module->name; + $instance = $DB->get_record($instancetable, ['id' => $cm->instance], '*', IGNORE_MISSING); + if ($instance && !empty($instance->name)) { + $keywords = array_merge($keywords, self::tokenise_keywords($instance->name)); + } + } + + return $keywords; + } + + + private static function tokenise_keywords(string $input): array { + $input = strtolower(trim($input)); + if (empty($input)) { + return []; + } + + $tokens = preg_split('/\s+/', $input); // split on spaces + $keywords = array_merge([$input], $tokens); // include full phrase and individual words + + return array_unique($keywords); // remove duplicates + } } diff --git a/local/telconfig/classes/observer.php b/local/telconfig/classes/observer.php index 1eb7a13e75e..98f13d006ba 100644 --- a/local/telconfig/classes/observer.php +++ b/local/telconfig/classes/observer.php @@ -23,7 +23,7 @@ public static function enrol_instance_changed(\core\event\base $event): void { // Get enrol instance $enrol = $DB->get_record('enrol', ['id' => $event->objectid], '*', MUST_EXIST); - + // Only act if it's for 'self' enrolment. if (!isset($event->other['enrol']) || $event->other['enrol'] !== 'self') { return; @@ -59,12 +59,79 @@ public static function local_course_updated(\core\event\base $event): void { try { $course = $DB->get_record('course', ['id' => $event->objectid], '*', MUST_EXIST); + // Only proceed if the course has self enrolment enabled + if (!self::is_course_self_enrollable($course->id)) { + return; + } + // Rebuild and send metadata to API (as an update). $data = course_data_builder::build_course_metadata($course); helper::send_findwise_api($data); } catch (\dml_exception $e) { - debugging("Failed to process course update: " . $e->getMessage(), DEBUG_DEVELOPER); + debugging("Failed to process local course update: " . $e->getMessage(), DEBUG_DEVELOPER); + } + } + + /** + * Triggered when a section is updated. + * + * @param \core\event\base $event + * @return void + */ + public static function local_section_changed(\core\event\base $event): void { + global $DB; + + try { + $course = $DB->get_record('course', ['id' => $event->courseid], '*', MUST_EXIST); + + // Only proceed if the course has self enrolment enabled + if (!self::is_course_self_enrollable($course->id)) { + return; + } + + // Handle the update, e.g., send new metadata + $data = course_data_builder::build_course_metadata($course); // or enrich this with section title + helper::send_findwise_api($data); + + } catch (\Throwable $e) { + debugging('Error handling local section change: ' . $e->getMessage(), DEBUG_DEVELOPER); } } + + /** + * Triggered when a module is updated. + * + * @param \core\event\base $event + * @return void + */ + public static function local_module_changed(\core\event\base $event): void { + global $DB; + + try { + $courseid = $event->courseid; + $course = $DB->get_record('course', ['id' => $courseid], '*', MUST_EXIST); + + // Only proceed if the course has self enrolment enabled + if (!self::is_course_self_enrollable($course->id)) { + return; + } + + // Build metadata + $data = course_data_builder::build_course_metadata($course); // or enrich with mod/section name + helper::send_findwise_api($data); + + } catch (\Throwable $e) { + debugging('Error handling local module change: ' . $e->getMessage(), DEBUG_DEVELOPER); + } + } + private static function is_course_self_enrollable(int $courseid): bool { + global $DB; + + return $DB->record_exists('enrol', [ + 'courseid' => $courseid, + 'enrol' => 'self', + 'status' => ENROL_INSTANCE_ENABLED, + ]); + } } diff --git a/local/telconfig/db/events.php b/local/telconfig/db/events.php index d6b56b72b4c..29da2fc800d 100644 --- a/local/telconfig/db/events.php +++ b/local/telconfig/db/events.php @@ -13,4 +13,40 @@ 'priority' => 9999, 'internal' => false, ], + [ + 'eventname' => '\core\event\course_section_created', + 'callback' => '\local_telconfig\observer::local_section_changed', + 'priority' => 9999, + 'internal' => false, + ], + [ + 'eventname' => '\core\event\course_section_updated', + 'callback' => '\local_telconfig\observer::local_section_changed', + 'priority' => 9999, + 'internal' => false, + ], + [ + 'eventname' => '\core\event\course_section_deleted', + 'callback' => '\local_telconfig\observer::local_section_changed', + 'priority' => 9999, + 'internal' => false, + ], + [ + 'eventname' => '\core\event\course_module_created', + 'callback' => '\local_telconfig\observer::local_module_changed', + 'priority' => 9999, + 'internal' => false, + ], + [ + 'eventname' => '\core\event\course_module_updated', + 'callback' => '\local_telconfig\observer::local_module_changed', + 'priority' => 9999, + 'internal' => false, + ], + [ + 'eventname' => '\core\event\course_module_deleted', + 'callback' => '\local_telconfig\observer::local_module_changed', + 'priority' => 9999, + 'internal' => false, + ], ];