Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions local/telconfig/classes/api_client.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,15 @@ public function post(string $url, array $data): string|false {
$context = stream_context_create($options);
return @file_get_contents($url, false, $context);
}

public function delete(string $url): string|false {
$options = [
'http' => [
'method' => 'DELETE',
'timeout' => 5,
]
];
$context = stream_context_create($options);
return @file_get_contents($url, false, $context);
}
}
69 changes: 69 additions & 0 deletions local/telconfig/classes/course_data_builder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?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/>.

/**
* Helper class locally used.
*
* @package local_telconfig
* @copyright
* @license
*/

namespace local_telconfig;

defined('MOODLE_INTERNAL') || die();

class course_data_builder {
public static function build_course_metadata($course): array {
global $DB, $CFG;

try {

// Get course context and teachers (authors)
$context = \context_course::instance($course->id);
$teachers = get_role_users(3, $context); // 3 = editingteacher by default
$authors = array_values(array_map(fn($u) => fullname($u), $teachers));

// 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) => $tag->rawname, $tags);

// Prepare data
$data = [
'_id' => 'M' . $course->id,
'course_id' => $course->id,
'authored_date' => date('Y-m-d', $course->startdate),
'authors' => $authors,
'catalogue_ids' => [$course->category],
'description' => format_text($course->summary, FORMAT_HTML),
'keywords' => array_values($keywords),
'location_paths' => [], // category hierarchy if needed
'publication_date' => date('Y-m-d', $course->startdate),
'rating' => 0,
'resource_reference_id' => 0,
'resource_type' => 'Course',
'title' => $course->fullname,
];

return $data;

} catch (\Throwable $e) {
debugging('Error in course_data_builder: ' . $e->getMessage(), DEBUG_DEVELOPER);
return []; // Always return an array
}
}
}
17 changes: 14 additions & 3 deletions local/telconfig/classes/helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ class helper {
* @param array $data
* @return void
*/
public static function send_findwise_api(array $data, ?api_client $client = null): void {
public static function send_findwise_api(array $data, string $method = 'POST', ?api_client $client = null): void {
$indexurl = get_config('local_telconfig', 'findwiseindexurl');
$indexmethod = get_config('local_telconfig', 'findwiseindexmethod');
$collection = get_config('local_telconfig', 'findwisecollection');
$apitoken = get_config('local_telconfig', 'findwiseapitoken');

if (empty($indexurl) || empty($apitoken)) {
return;
return;
}

$indexurl = rtrim($indexurl, '/') . '/' . $indexmethod . '?token=' . urlencode($apitoken);
Expand All @@ -51,7 +51,18 @@ public static function send_findwise_api(array $data, ?api_client $client = null
$client ??= new api_client();

try {
$response = $client->post($apiurl, $data);
if ($method === 'DELETE') {
// Add logic to construct a deletion URL with course ID
if (isset($data['course_id'])) {
$deleteurl = rtrim($apiurl, '/') . '&id=M' . $data['course_id'];
$response = $client->delete($deleteurl);
} else {
debugging('send_findwise_api: Cannot perform DELETE without course_id in $data.', DEBUG_DEVELOPER);
return;
}
} else {
$response = $client->post($apiurl, $data); // POST or PUT
}

if ($response === false) {
debugging('send_findwise_api: Failed to send data to findwise API.', DEBUG_DEVELOPER);
Expand Down
41 changes: 19 additions & 22 deletions local/telconfig/classes/observer.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

namespace local_telconfig;
use local_telconfig\course_data_builder;
use local_telconfig\helper;
// This file is part of Moodle - http://moodle.org/
// Moodle is free software: you can redistribute it and/or modify
Expand All @@ -18,33 +19,29 @@ class observer {
public static function enrol_instance_changed(\core\event\base $event): void {
global $DB;

// Only act if it's for 'self' enrolment.
if (!isset($event->other['enrol']) || $event->other['enrol'] !== 'self') {
return;
}

try {

// Get enrol instance
$enrol = $DB->get_record('enrol', ['id' => $event->objectid], '*', MUST_EXIST);

$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;
}

// Get course info
$course = $DB->get_record('course', ['id' => $event->courseid], '*', MUST_EXIST);

$data = [
'_id' => $course->id,
'event' => $event->eventname,
'enrolid' => $enrol->id,
'courseid' => $course->id,
'coursename' => $course->fullname,
'shortname' => $course->shortname,
'summary' => $course->summary,
'startdate' => $course->startdate,
'enddate' => $course->enddate,
'enrolstatus' => $enrol->status, // 0 = enabled, 1 = disabled
'time' => time()
];

helper::send_findwise_api($data);
if ((int)$enrol->status === ENROL_INSTANCE_ENABLED) {
// Fetch the enrolment instance data.
$data = course_data_builder::build_course_metadata($course);
helper::send_findwise_api($data);
} else {
// Delete from external API when disabled.
$data = ['course_id' => $course->id];
helper::send_findwise_api($data,'DELETE');
}

} catch (\dml_exception $e) {
debugging("Failed to fetch course/enrol data: " . $e->getMessage(), DEBUG_DEVELOPER);
}
Expand Down
2 changes: 1 addition & 1 deletion local/telconfig/lang/en/local_telconfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
$string['Findwisesettings_desc'] = 'Findwise API configurations.';
$string['findwiseindexurl'] = 'Findwise index url';
$string['findwiseindexurl_desc'] = 'Findwise index url desc.';
$string['findwiseindexmethod'] = 'Findwise index url';
$string['findwiseindexmethod'] = 'Findwise index method';
$string['findwiseindexmethod_desc'] = 'Findwise index method desc.';
$string['findwisecollection'] = 'Findwise collection';
$string['findwisecollection_desc'] = 'Findwise collection desc.';
Expand Down
71 changes: 71 additions & 0 deletions local/telconfig/tests/course_data_builder_test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?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/>.

// File: local/telconfig/tests/course_data_builder_test.php

namespace local_telconfig\tests;

use advanced_testcase;
use context_course;
use core_tag_tag;
use local_telconfig\course_data_builder;

defined('MOODLE_INTERNAL') || die();

class course_data_builder_test extends advanced_testcase {


public function test_build_course_metadata_returns_expected_array() {
global $DB;

$this->resetAfterTest(true);

// Create a course using Moodle's generator
$course = $this->getDataGenerator()->create_course([
'fullname' => 'Test Course',
'summary' => 'Test summary',
'startdate' => strtotime('2022-01-01')
]);

// Enrol a teacher in the course
$teacher = $this->getDataGenerator()->create_user(['firstname' => 'Alice', 'lastname' => 'Teacher']);
$roleid = 3; // editingteacher
$context = context_course::instance($course->id);
role_assign($roleid, $teacher->id, $context->id);

// Add tags to course
core_tag_tag::set_item_tags('core', 'course', $course->id, context_course::instance($course->id), ['tag1', 'tag2']);

// Call the method
$result = course_data_builder::build_course_metadata($course);

// Assertions
$this->assertIsArray($result);
$this->assertSame('M' . $course->id, $result['_id']);
$this->assertSame($course->id, $result['course_id']);
$this->assertSame(date('Y-m-d', $course->startdate), $result['authored_date']);
$this->assertContains(fullname($teacher), $result['authors']);
$this->assertEquals([$course->category], $result['catalogue_ids']);
$this->assertSame(format_text($course->summary, FORMAT_HTML), $result['description']);
$this->assertEquals(['tag1', 'tag2'], $result['keywords']);
$this->assertIsArray($result['location_paths']);
$this->assertSame(date('Y-m-d', $course->startdate), $result['publication_date']);
$this->assertSame(0, $result['rating']);
$this->assertSame(0, $result['resource_reference_id']);
$this->assertSame('Course', $result['resource_type']);
$this->assertSame($course->fullname, $result['title']);
}
}
2 changes: 1 addition & 1 deletion local/telconfig/tests/helper_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ public function test_send_findwise_api_makes_api_call() {
->willReturn('{"status":"ok"}');

// Call the method with the mock client.
helper::send_findwise_api(['courseid' => 123], $mock);
helper::send_findwise_api(['courseid' => 123], 'POST', $mock);
}
}
Loading