From 86bf9fd531980f46027787f51bed6300cfe5034d Mon Sep 17 00:00:00 2001 From: tobias Date: Tue, 1 Aug 2023 14:29:44 +0200 Subject: [PATCH 01/23] Create new class playload that holds payload for grade sync requests --- classes/grades/synchronization/context.php | 8 +++++ classes/grades/synchronization/payload.php | 39 ++++++++++++++++++++++ gradesync.php | 9 +++-- 3 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 classes/grades/synchronization/context.php create mode 100644 classes/grades/synchronization/payload.php diff --git a/classes/grades/synchronization/context.php b/classes/grades/synchronization/context.php new file mode 100644 index 0000000..2f0913e --- /dev/null +++ b/classes/grades/synchronization/context.php @@ -0,0 +1,8 @@ +users = $users; + $this->course = $course; + $this->objectIds = $objectIds; + $this->lastSync = $lastSync; + $this->includeAll = $includeAll; + } + + public function with_context($context): payload { + $this->context = $context; + return $this; + } + + public function get_encoded(): string { + return json_encode($this); + } + +} \ No newline at end of file diff --git a/gradesync.php b/gradesync.php index 84f00b0..3d9613d 100644 --- a/gradesync.php +++ b/gradesync.php @@ -24,6 +24,8 @@ */ namespace mod_mumie; +use mod_mumie\synchronization\payload; + defined('MOODLE_INTERNAL') || die(); require_once($CFG->dirroot . '/mod/mumie/lib.php'); @@ -220,11 +222,12 @@ private static function is_latest_grade($grades, $potentialgrade) { * @return stdClass all requested grades for the given MUMIE task */ public static function get_xapi_grades($mumie, $syncids, $mumieids) { + global $CFG; + require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/payload.php"); $mumieserver = new \auth_mumie\mumie_server(); $mumieserver->set_urlprefix($mumie->server); - $payload = json_encode(array("users" => $syncids, "course" => $mumie->mumie_coursefile, - "objectIds" => $mumieids, "lastSync" => $mumie->lastsync, "includeAll" => true)); - $ch = self::create_post_curl_request($mumieserver->get_grade_sync_url(), $payload); + $payload = new payload($syncids, $mumie->mumie_coursefile, $mumieids, $mumie->lastsync, true); + $ch = self::create_post_curl_request($mumieserver->get_grade_sync_url(), $payload->get_encoded()); $result = curl_exec($ch); curl_close($ch); From 75c0bd271e793536bb6b6d52b5e2f037dcf34131 Mon Sep 17 00:00:00 2001 From: tobias Date: Tue, 1 Aug 2023 15:11:47 +0200 Subject: [PATCH 02/23] Defined context classes to include information about deadlines in grade sync requests --- classes/grades/synchronization/context.php | 8 ------- .../synchronization/context/context.php | 22 +++++++++++++++++++ .../context/object_context.php | 22 +++++++++++++++++++ .../synchronization/context/user_context.php | 21 ++++++++++++++++++ classes/grades/synchronization/payload.php | 22 ++++++++++--------- gradesync.php | 2 +- 6 files changed, 78 insertions(+), 19 deletions(-) delete mode 100644 classes/grades/synchronization/context.php create mode 100644 classes/grades/synchronization/context/context.php create mode 100644 classes/grades/synchronization/context/object_context.php create mode 100644 classes/grades/synchronization/context/user_context.php diff --git a/classes/grades/synchronization/context.php b/classes/grades/synchronization/context.php deleted file mode 100644 index 2f0913e..0000000 --- a/classes/grades/synchronization/context.php +++ /dev/null @@ -1,8 +0,0 @@ -objectcontexts = array(); + } + + public function add_object_context(string $objectid, object_context $objectcontext): void { + $this->objectcontexts[$objectid] = $objectcontext; + } + + public function jsonSerialize() : array + { + return $this->objectcontexts; + } +} \ No newline at end of file diff --git a/classes/grades/synchronization/context/object_context.php b/classes/grades/synchronization/context/object_context.php new file mode 100644 index 0000000..aaba6a8 --- /dev/null +++ b/classes/grades/synchronization/context/object_context.php @@ -0,0 +1,22 @@ +usercontexts = array(); + } + + public function add_user_context(string $userId, user_context $usercontext): void { + $this->usercontexts[$userId] = $usercontext; + } + + public function jsonSerialize() + { + return $this->usercontexts; + } +} \ No newline at end of file diff --git a/classes/grades/synchronization/context/user_context.php b/classes/grades/synchronization/context/user_context.php new file mode 100644 index 0000000..f867cd4 --- /dev/null +++ b/classes/grades/synchronization/context/user_context.php @@ -0,0 +1,21 @@ +deadline = $deadline; + } + + public function jsonSerialize() + { + return get_object_vars($this); + } +} \ No newline at end of file diff --git a/classes/grades/synchronization/payload.php b/classes/grades/synchronization/payload.php index 9a01a96..18c7700 100644 --- a/classes/grades/synchronization/payload.php +++ b/classes/grades/synchronization/payload.php @@ -2,14 +2,16 @@ namespace mod_mumie\synchronization; -class payload +use mod_mumie\synchronization\context\context; + +class payload implements \JsonSerializable { - public array $users; - public string $course; - public array $objectIds; - public int $lastSync; - public bool $includeAll; - public context $context; + private array $users; + private string $course; + private array $objectIds; + private int $lastSync; + private bool $includeAll; + private context $context; /** * @param array $users @@ -32,8 +34,8 @@ public function with_context($context): payload { return $this; } - public function get_encoded(): string { - return json_encode($this); + public function jsonSerialize(): array + { + return get_object_vars($this); } - } \ No newline at end of file diff --git a/gradesync.php b/gradesync.php index 3d9613d..de6ec32 100644 --- a/gradesync.php +++ b/gradesync.php @@ -227,7 +227,7 @@ public static function get_xapi_grades($mumie, $syncids, $mumieids) { $mumieserver = new \auth_mumie\mumie_server(); $mumieserver->set_urlprefix($mumie->server); $payload = new payload($syncids, $mumie->mumie_coursefile, $mumieids, $mumie->lastsync, true); - $ch = self::create_post_curl_request($mumieserver->get_grade_sync_url(), $payload->get_encoded()); + $ch = self::create_post_curl_request($mumieserver->get_grade_sync_url(), json_encode($payload)); $result = curl_exec($ch); curl_close($ch); From ce035fb4df8b62e0f78ac62e06d9665b66f61f58 Mon Sep 17 00:00:00 2001 From: tobias Date: Wed, 2 Aug 2023 10:22:39 +0200 Subject: [PATCH 03/23] extracted logic to create/send xapi requests into new xapi_request class to clean up gradesync.php --- .../grades/synchronization/xapi_request.php | 48 +++++++++++++++++++ gradesync.php | 35 ++------------ 2 files changed, 52 insertions(+), 31 deletions(-) create mode 100644 classes/grades/synchronization/xapi_request.php diff --git a/classes/grades/synchronization/xapi_request.php b/classes/grades/synchronization/xapi_request.php new file mode 100644 index 0000000..2391919 --- /dev/null +++ b/classes/grades/synchronization/xapi_request.php @@ -0,0 +1,48 @@ +server = $server; + $this->payload = $payload; + } + + public function send() { + $ch = $this->create_post_curl_request(); + $result = curl_exec($ch); + + curl_close($ch); + return json_decode($result); + } + + /** + * Creates a curl post request for a given url and json payload + * + * @return CurlHandle curl handle for json payload + */ + public function create_post_curl_request(): CurlHandle { + $ch = curl_init($this->server->get_grade_sync_url()); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); + curl_setopt($ch, CURLOPT_USERAGENT, "My User Agent Name"); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($this->payload)); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt( + $ch, + CURLOPT_HTTPHEADER, + array( + 'Content-Type: application/json', + 'Content-Length: ' . strlen(json_encode($this->payload)), + "X-API-Key: " . get_config('auth_mumie', 'mumie_api_key'), + ) + ); + return $ch; + } +} diff --git a/gradesync.php b/gradesync.php index de6ec32..4079b86 100644 --- a/gradesync.php +++ b/gradesync.php @@ -25,6 +25,7 @@ namespace mod_mumie; use mod_mumie\synchronization\payload; +use mod_mumie\synchronization\xapi_request; defined('MOODLE_INTERNAL') || die(); @@ -224,14 +225,12 @@ private static function is_latest_grade($grades, $potentialgrade) { public static function get_xapi_grades($mumie, $syncids, $mumieids) { global $CFG; require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/payload.php"); + require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/xapi_request.php"); $mumieserver = new \auth_mumie\mumie_server(); $mumieserver->set_urlprefix($mumie->server); $payload = new payload($syncids, $mumie->mumie_coursefile, $mumieids, $mumie->lastsync, true); - $ch = self::create_post_curl_request($mumieserver->get_grade_sync_url(), json_encode($payload)); - $result = curl_exec($ch); - - curl_close($ch); - return json_decode($result); + $request = new xapi_request($mumieserver, $payload); + return $request->send(); } /** @@ -288,30 +287,4 @@ public static function get_mumie_id($mumietask) { $id = substr($id, 0, strpos($id, '?lang=')); return $id; } - - /** - * Creates a curl post request for a given url and json payload - * - * @param string $url - * @param string $payload as json - * @return cURL curl handle for json payload - */ - public static function create_post_curl_request($url, $payload) { - $ch = curl_init($url); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); - curl_setopt($ch, CURLOPT_USERAGENT, "My User Agent Name"); - curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt( - $ch, - CURLOPT_HTTPHEADER, - array( - 'Content-Type: application/json', - 'Content-Length: ' . strlen($payload), - "X-API-Key: " . get_config('auth_mumie', 'mumie_api_key'), - ) - ); - - return $ch; - } } From a153b308f0903665d8239a2f4f055cd6eec77ecb Mon Sep 17 00:00:00 2001 From: tobias Date: Wed, 2 Aug 2023 13:37:53 +0200 Subject: [PATCH 04/23] WIP Add context to grade sync request --- .../context/context_provider.php | 61 +++++++++++++++++++ gradesync.php | 9 +++ 2 files changed, 70 insertions(+) create mode 100644 classes/grades/synchronization/context/context_provider.php diff --git a/classes/grades/synchronization/context/context_provider.php b/classes/grades/synchronization/context/context_provider.php new file mode 100644 index 0000000..eabf8de --- /dev/null +++ b/classes/grades/synchronization/context/context_provider.php @@ -0,0 +1,61 @@ +add_object_context( + self::get_mumie_id($mumie), + self::get_object_context($mumie, $users) + ); + } + } + return $context; + } + + + //TODO: This is copied from gradesync.php + //Refactor so that we don't have duplicate code + /** + * Get the unique identifier for a MUMIE task + * + * @param stdClass $mumietask + * @return string id for MUMIE task on MUMIE/LEMON server + */ + private static function get_mumie_id($mumietask): string { + $id = $mumietask->taskurl; + $prefix = "link/"; + if (strpos($id, $prefix) !== false) { + $id = substr($mumietask->taskurl, strlen($prefix)); + } + $id = substr($id, 0, strpos($id, '?lang=')); + return $id; + } + + public static function has_context($mumie): bool { + return false; + } + + private static function get_object_context($mumie, array $users): object_context { + global $CFG; + require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/context/object_context.php"); + $context = new object_context(); + foreach ($users as $user) { + $context->add_user_context($user->get_sync_id(), self::get_user_context($mumie, $user)); + } + return $context; + } + + private static function get_user_context($mumie, mumie_user $user): user_context { + global $CFG; + require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/context/user_context.php"); + return new user_context(locallib::get_effective_duedate($user->get_moodle_id(), $mumie)); + } +} \ No newline at end of file diff --git a/gradesync.php b/gradesync.php index 4079b86..ad28d98 100644 --- a/gradesync.php +++ b/gradesync.php @@ -26,6 +26,8 @@ use mod_mumie\synchronization\payload; use mod_mumie\synchronization\xapi_request; +use mod_mumie\synchronization\context\context_provider; +use auth_mumie\user\mumie_user; defined('MOODLE_INTERNAL') || die(); @@ -226,9 +228,16 @@ public static function get_xapi_grades($mumie, $syncids, $mumieids) { global $CFG; require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/payload.php"); require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/xapi_request.php"); + require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/context/context_provider.php"); + require_once($CFG->dirroot . "/auth/mumie/classes/sso/user/mumie_user.php"); $mumieserver = new \auth_mumie\mumie_server(); $mumieserver->set_urlprefix($mumie->server); $payload = new payload($syncids, $mumie->mumie_coursefile, $mumieids, $mumie->lastsync, true); + if(context_provider::has_context($mumie)) { + $context = context_provider::get_context(array($mumie), array(new mumie_user("2", "2"))); + $payload->with_context($context); + } + debugging(json_encode($payload)); $request = new xapi_request($mumieserver, $payload); return $request->send(); } From 4e948cfce6fd3554ffb7b88ac33acc90d5a790d3 Mon Sep 17 00:00:00 2001 From: tobias Date: Wed, 2 Aug 2023 14:06:21 +0200 Subject: [PATCH 05/23] WIP Add context to grade sync request --- .../context/context_provider.php | 4 +- gradesync.php | 49 ++++++------------- 2 files changed, 17 insertions(+), 36 deletions(-) diff --git a/classes/grades/synchronization/context/context_provider.php b/classes/grades/synchronization/context/context_provider.php index eabf8de..c7f3569 100644 --- a/classes/grades/synchronization/context/context_provider.php +++ b/classes/grades/synchronization/context/context_provider.php @@ -8,6 +8,8 @@ class context_provider { public static function get_context(array $mumies, array $users): context { + global $CFG; + require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/context/context.php"); $context = new context(); foreach ($mumies as $mumie) { if(self::has_context($mumie)) { @@ -40,7 +42,7 @@ private static function get_mumie_id($mumietask): string { } public static function has_context($mumie): bool { - return false; + return true; } private static function get_object_context($mumie, array $users): object_context { diff --git a/gradesync.php b/gradesync.php index ad28d98..bdd9cc1 100644 --- a/gradesync.php +++ b/gradesync.php @@ -28,6 +28,7 @@ use mod_mumie\synchronization\xapi_request; use mod_mumie\synchronization\context\context_provider; use auth_mumie\user\mumie_user; +use auth_mumie\user\mumie_user_service; defined('MOODLE_INTERNAL') || die(); @@ -35,6 +36,7 @@ require_once($CFG->dirroot . '/auth/mumie/lib.php'); require_once($CFG->dirroot . '/auth/mumie/classes/mumie_server.php'); require_once($CFG->dirroot . '/mod/mumie/classes/mumie_duedate_extension.php'); +require_once($CFG->dirroot . '/auth/mumie/classes/sso/user/mumie_user_service.php'); /** * This file defines the class gradesync @@ -110,20 +112,20 @@ public static function get_all_mumie_tasks_for_user($userid) { * @return array grades for the given MUMIE task */ public static function get_mumie_grades($mumie, $userid) { - global $COURSE, $DB; - $syncids = array(); + global $COURSE; + $mumieusers = array(); if ($userid == 0) { foreach (get_enrolled_users(\context_course::instance($COURSE->id)) as $user) { - array_push($syncids, self::get_sync_id($user->id, $mumie)); + array_push($mumieusers, mumie_user_service::get_user($user->id, $mumie)); } } else { - $syncids = array(self::get_sync_id($userid, $mumie)); + $mumieusers = array(mumie_user_service::get_user($userid, $mumie)); } $mumieids = array(self::get_mumie_id($mumie)); $grades = array(); - $xapigrades = self::get_xapi_grades($mumie, $syncids, $mumieids); + $xapigrades = self::get_xapi_grades($mumie, $mumieusers, $mumieids); if (is_null($xapigrades)) { return null; @@ -146,14 +148,13 @@ public static function get_mumie_grades($mumie, $userid) { * @return array */ public static function get_all_grades_for_user($mumie, $userid) { - global $COURSE, $DB; - $syncids = array(); + $mumieusers = array(); - array_push($syncids, self::get_sync_id($userid, $mumie)); + array_push($mumieusers, mumie_user_service::get_user($userid, $mumie)); $mumieids = array(self::get_mumie_id($mumie)); $grades = array(); - $xapigrades = self::get_xapi_grades($mumie, $syncids, $mumieids); + $xapigrades = self::get_xapi_grades($mumie, $mumieusers, $mumieids); if (is_null($xapigrades)) { return null; @@ -220,11 +221,11 @@ private static function is_latest_grade($grades, $potentialgrade) { * Get xapi grades for a MUMIE task instance * * @param stdClass $mumie instance of MUMIE task we want to get grades for - * @param array $syncids all users we want grades for + * @param array $mumieusers all users we want grades for * @param array $mumieids mumieid of mumie instance as an array * @return stdClass all requested grades for the given MUMIE task */ - public static function get_xapi_grades($mumie, $syncids, $mumieids) { + public static function get_xapi_grades($mumie, $mumieusers, $mumieids) { global $CFG; require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/payload.php"); require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/xapi_request.php"); @@ -232,9 +233,10 @@ public static function get_xapi_grades($mumie, $syncids, $mumieids) { require_once($CFG->dirroot . "/auth/mumie/classes/sso/user/mumie_user.php"); $mumieserver = new \auth_mumie\mumie_server(); $mumieserver->set_urlprefix($mumie->server); + $syncids = array_map(function ($user) {return $user->get_sync_id();}, $mumieusers); $payload = new payload($syncids, $mumie->mumie_coursefile, $mumieids, $mumie->lastsync, true); if(context_provider::has_context($mumie)) { - $context = context_provider::get_context(array($mumie), array(new mumie_user("2", "2"))); + $context = context_provider::get_context(array($mumie), $mumieusers); $payload->with_context($context); } debugging(json_encode($payload)); @@ -242,29 +244,6 @@ public static function get_xapi_grades($mumie, $syncids, $mumieids) { return $request->send(); } - /** - * Get a unique syncid from a userid that can be used on the MUMIE server as username - * @param int $userid - * @param int $mumie - * @return string unique username for MUMIE servers derived from the moodle userid - */ - public static function get_sync_id($userid, $mumie) { - global $DB; - $org = get_config('auth_mumie', 'mumie_org'); - if ($mumie->use_hashed_id == 1) { - $hashidtable = 'auth_mumie_id_hashes'; - $hash = auth_mumie_get_hashed_id($userid); - if ($mumie->privategradepool) { - $hash .= '@gradepool' . $mumie->course . '@'; - } - if (!$DB->get_record($hashidtable, array("the_user" => $userid, 'hash' => $hash))) { - $DB->insert_record($hashidtable, array("the_user" => $userid, "hash" => $hash)); - } - $userid = $hash; - } - return "GSSO_" . $org . "_" . $userid; - } - /** * Get moodleUserID from syncid * @param string $syncid From 38ae3d7d0d1a0b757a50fad3ffea0386afa4f1f8 Mon Sep 17 00:00:00 2001 From: tobias Date: Wed, 2 Aug 2023 14:25:10 +0200 Subject: [PATCH 06/23] Implemented logic for context_provider::has_context --- classes/grades/synchronization/context/context_provider.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/classes/grades/synchronization/context/context_provider.php b/classes/grades/synchronization/context/context_provider.php index c7f3569..154e712 100644 --- a/classes/grades/synchronization/context/context_provider.php +++ b/classes/grades/synchronization/context/context_provider.php @@ -42,7 +42,8 @@ private static function get_mumie_id($mumietask): string { } public static function has_context($mumie): bool { - return true; + return str_starts_with($mumie->taskurl, "worksheet_") + && $mumie->duedate > 0; } private static function get_object_context($mumie, array $users): object_context { From 0f4c488ae427ecc5adc1db2a7d1a44c425ef4808 Mon Sep 17 00:00:00 2001 From: tobias Date: Wed, 2 Aug 2023 14:50:19 +0200 Subject: [PATCH 07/23] Added/fixed typing --- gradesync.php | 56 +++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/gradesync.php b/gradesync.php index bdd9cc1..d7231d0 100644 --- a/gradesync.php +++ b/gradesync.php @@ -24,11 +24,15 @@ */ namespace mod_mumie; +global $CFG; + use mod_mumie\synchronization\payload; use mod_mumie\synchronization\xapi_request; use mod_mumie\synchronization\context\context_provider; -use auth_mumie\user\mumie_user; use auth_mumie\user\mumie_user_service; +use stdClass; +use context_course; +use auth_mumie\mumie_server; defined('MOODLE_INTERNAL') || die(); @@ -59,7 +63,7 @@ public static function update() { if ($isreportpage) { $userid = $USER->id; - if (has_capability("mod/mumie:viewgrades", \context_course::instance($COURSE->id), $USER)) { + if (has_capability("mod/mumie:viewgrades", context_course::instance($COURSE->id), $USER)) { // User id = 0 => update grades for all users! $userid = 0; } @@ -81,7 +85,7 @@ public static function update() { * @param int $courseid * @return array All MUMIE tasks that are used in the given course */ - public static function get_mumie_tasks_from_course($courseid) { + public static function get_mumie_tasks_from_course($courseid) : array { global $DB; return $DB->get_records(MUMIE_TASK_TABLE, array("course" => $courseid, "isgraded" => 1)); } @@ -92,7 +96,7 @@ public static function get_mumie_tasks_from_course($courseid) { * @param int $userid * @return array All MUMIE tasks that are in courses, the user is enrolled in */ - public static function get_all_mumie_tasks_for_user($userid) { + public static function get_all_mumie_tasks_for_user($userid) : array { $allmumietasks = array(); foreach (enrol_get_all_users_courses($userid) as $course) { $mumietasks = self::get_mumie_tasks_from_course($course->id); @@ -111,12 +115,13 @@ public static function get_all_mumie_tasks_for_user($userid) { * @param int $userid If userid = 0, update all users * @return array grades for the given MUMIE task */ - public static function get_mumie_grades($mumie, $userid) { + public static function get_mumie_grades(stdClass $mumie, int $userid) : ?array { global $COURSE; $mumieusers = array(); + //TODO: extract this into new function if ($userid == 0) { - foreach (get_enrolled_users(\context_course::instance($COURSE->id)) as $user) { + foreach (get_enrolled_users(context_course::instance($COURSE->id)) as $user) { array_push($mumieusers, mumie_user_service::get_user($user->id, $mumie)); } } else { @@ -143,15 +148,13 @@ public static function get_mumie_grades($mumie, $userid) { /** * Get all grades a user has archived for a given MUMIE Task * - * @param \stdClass $mumie + * @param stdClass $mumie * @param int $userid * @return array */ - public static function get_all_grades_for_user($mumie, $userid) { - $mumieusers = array(); - - array_push($mumieusers, mumie_user_service::get_user($userid, $mumie)); + public static function get_all_grades_for_user(stdClass $mumie, int $userid) : ?array { + $mumieusers = [mumie_user_service::get_user($userid, $mumie)]; $mumieids = array(self::get_mumie_id($mumie)); $grades = array(); $xapigrades = self::get_xapi_grades($mumie, $mumieusers, $mumieids); @@ -162,7 +165,7 @@ public static function get_all_grades_for_user($mumie, $userid) { foreach ($xapigrades as $xapigrade) { $grade = self::xapi_to_moodle_grade($xapigrade, $mumie); - array_push($grades, $grade); + $grades[] = $grade; } return $grades; } @@ -170,12 +173,12 @@ public static function get_all_grades_for_user($mumie, $userid) { /** * Transform Xapi grade to moodle grade objects. * - * @param \stdClass $xapigrade - * @param \stdClass $mumie - * @return \stdClass + * @param stdClass $xapigrade + * @param stdClass $mumie + * @return stdClass */ - private static function xapi_to_moodle_grade($xapigrade, $mumie) { - $grade = new \stdClass(); + private static function xapi_to_moodle_grade($xapigrade, stdClass $mumie) : stdClass { + $grade = new stdClass(); $grade->userid = self::get_moodle_user_id($xapigrade->actor->account->name, $mumie->use_hashed_id); $grade->rawgrade = 100 * $xapigrade->result->score->raw; $grade->timecreated = strtotime($xapigrade->timestamp); @@ -190,7 +193,7 @@ private static function xapi_to_moodle_grade($xapigrade, $mumie) { * @param stdClass $potentialgrade the grade in question * @return boolean Whether the grade should be added to $grades */ - public static function include_grade($mumie, $grades, $potentialgrade) { + public static function include_grade(stdClass $mumie, array $grades, stdClass $potentialgrade) : bool { global $CFG; require_once($CFG->dirroot . "/mod/mumie/locallib.php"); $duedate = locallib::get_effective_duedate($potentialgrade->userid, $mumie); @@ -209,10 +212,10 @@ public static function include_grade($mumie, $grades, $potentialgrade) { * True, if the given grade is currently the latest available one. * * @param array $grades List of the latest grades so far by user. - * @param \stdClass $potentialgrade The grade we are testing + * @param stdClass $potentialgrade The grade we are testing * @return boolean */ - private static function is_latest_grade($grades, $potentialgrade) { + private static function is_latest_grade(array $grades, stdClass $potentialgrade) : bool { return !isset($grades[$potentialgrade->userid]) || $grades[$potentialgrade->userid]->timecreated < $potentialgrade->timecreated; } @@ -225,13 +228,13 @@ private static function is_latest_grade($grades, $potentialgrade) { * @param array $mumieids mumieid of mumie instance as an array * @return stdClass all requested grades for the given MUMIE task */ - public static function get_xapi_grades($mumie, $mumieusers, $mumieids) { + public static function get_xapi_grades(stdClass $mumie, array $mumieusers, array $mumieids) { global $CFG; require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/payload.php"); require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/xapi_request.php"); require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/context/context_provider.php"); require_once($CFG->dirroot . "/auth/mumie/classes/sso/user/mumie_user.php"); - $mumieserver = new \auth_mumie\mumie_server(); + $mumieserver = new mumie_server(); $mumieserver->set_urlprefix($mumie->server); $syncids = array_map(function ($user) {return $user->get_sync_id();}, $mumieusers); $payload = new payload($syncids, $mumie->mumie_coursefile, $mumieids, $mumie->lastsync, true); @@ -244,13 +247,15 @@ public static function get_xapi_grades($mumie, $mumieusers, $mumieids) { return $request->send(); } + + //TODO: replace this with a call to mumie_user_server::get_user /** * Get moodleUserID from syncid * @param string $syncid * @param int $hashid indicates whether the id was hashed * @return string of moodle user */ - public static function get_moodle_user_id($syncid, $hashid) { + public static function get_moodle_user_id($syncid, $hashid) : ?string { $userid = substr(strrchr($syncid, "_"), 1); $hashidtable = 'auth_mumie_id_hashes'; if ($hashid == 1) { @@ -266,13 +271,12 @@ public static function get_moodle_user_id($syncid, $hashid) { * @param stdClass $mumietask * @return string id for MUMIE task on MUMIE/LEMON server */ - public static function get_mumie_id($mumietask) { + public static function get_mumie_id(stdClass $mumietask) : string { $id = $mumietask->taskurl; $prefix = "link/"; if (strpos($id, $prefix) !== false) { $id = substr($mumietask->taskurl, strlen($prefix)); } - $id = substr($id, 0, strpos($id, '?lang=')); - return $id; + return substr($id, 0, strpos($id, '?lang=')); } } From 15b4a6789c1c7d71281fbd4b42d2d9564344b78c Mon Sep 17 00:00:00 2001 From: tobias Date: Wed, 2 Aug 2023 14:58:29 +0200 Subject: [PATCH 08/23] Fixed some whitespace formatting --- classes/grades/synchronization/context/context.php | 11 ++++------- .../synchronization/context/context_provider.php | 5 ++--- .../grades/synchronization/context/object_context.php | 11 ++++------- .../grades/synchronization/context/user_context.php | 11 ++++------- classes/grades/synchronization/payload.php | 2 +- 5 files changed, 15 insertions(+), 25 deletions(-) diff --git a/classes/grades/synchronization/context/context.php b/classes/grades/synchronization/context/context.php index 4dac15b..783a173 100644 --- a/classes/grades/synchronization/context/context.php +++ b/classes/grades/synchronization/context/context.php @@ -2,12 +2,10 @@ namespace mod_mumie\synchronization\context; -class context implements \JsonSerializable -{ +class context implements \JsonSerializable { private array $objectcontexts; - public function __construct() - { + public function __construct() { $this->objectcontexts = array(); } @@ -15,8 +13,7 @@ public function add_object_context(string $objectid, object_context $objectconte $this->objectcontexts[$objectid] = $objectcontext; } - public function jsonSerialize() : array - { + public function jsonSerialize() : array { return $this->objectcontexts; } -} \ No newline at end of file +} diff --git a/classes/grades/synchronization/context/context_provider.php b/classes/grades/synchronization/context/context_provider.php index 154e712..8294d14 100644 --- a/classes/grades/synchronization/context/context_provider.php +++ b/classes/grades/synchronization/context/context_provider.php @@ -5,8 +5,7 @@ use mod_mumie\locallib; use auth_mumie\user\mumie_user; -class context_provider -{ +class context_provider { public static function get_context(array $mumies, array $users): context { global $CFG; require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/context/context.php"); @@ -61,4 +60,4 @@ private static function get_user_context($mumie, mumie_user $user): user_context require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/context/user_context.php"); return new user_context(locallib::get_effective_duedate($user->get_moodle_id(), $mumie)); } -} \ No newline at end of file +} diff --git a/classes/grades/synchronization/context/object_context.php b/classes/grades/synchronization/context/object_context.php index aaba6a8..5118859 100644 --- a/classes/grades/synchronization/context/object_context.php +++ b/classes/grades/synchronization/context/object_context.php @@ -2,12 +2,10 @@ namespace mod_mumie\synchronization\context; -class object_context implements \JsonSerializable -{ +class object_context implements \JsonSerializable { private array $usercontexts; - public function __construct() - { + public function __construct() { $this->usercontexts = array(); } @@ -15,8 +13,7 @@ public function add_user_context(string $userId, user_context $usercontext): vo $this->usercontexts[$userId] = $usercontext; } - public function jsonSerialize() - { + public function jsonSerialize() { return $this->usercontexts; } -} \ No newline at end of file +} diff --git a/classes/grades/synchronization/context/user_context.php b/classes/grades/synchronization/context/user_context.php index f867cd4..2b1e073 100644 --- a/classes/grades/synchronization/context/user_context.php +++ b/classes/grades/synchronization/context/user_context.php @@ -2,20 +2,17 @@ namespace mod_mumie\synchronization\context; -class user_context implements \JsonSerializable -{ +class user_context implements \JsonSerializable { private int $deadline; /** * @param int $deadline */ - public function __construct(int $deadline) - { + public function __construct(int $deadline) { $this->deadline = $deadline; } - public function jsonSerialize() - { + public function jsonSerialize() { return get_object_vars($this); } -} \ No newline at end of file +} diff --git a/classes/grades/synchronization/payload.php b/classes/grades/synchronization/payload.php index 18c7700..bc3da1a 100644 --- a/classes/grades/synchronization/payload.php +++ b/classes/grades/synchronization/payload.php @@ -38,4 +38,4 @@ public function jsonSerialize(): array { return get_object_vars($this); } -} \ No newline at end of file +} From a6e00c8176076f09a790b918bc609d3b802557f6 Mon Sep 17 00:00:00 2001 From: tobias Date: Wed, 2 Aug 2023 16:11:29 +0200 Subject: [PATCH 09/23] Added moodle boiler plate --- .../synchronization/context/context.php | 14 ++++++++++++++ .../context/context_provider.php | 14 ++++++++++++++ .../context/object_context.php | 14 ++++++++++++++ .../synchronization/context/user_context.php | 14 ++++++++++++++ classes/grades/synchronization/payload.php | 14 ++++++++++++++ .../grades/synchronization/xapi_request.php | 19 ++++++++++++++++--- 6 files changed, 86 insertions(+), 3 deletions(-) diff --git a/classes/grades/synchronization/context/context.php b/classes/grades/synchronization/context/context.php index 783a173..7c9459b 100644 --- a/classes/grades/synchronization/context/context.php +++ b/classes/grades/synchronization/context/context.php @@ -1,4 +1,18 @@ . namespace mod_mumie\synchronization\context; diff --git a/classes/grades/synchronization/context/context_provider.php b/classes/grades/synchronization/context/context_provider.php index 8294d14..dbf7ab3 100644 --- a/classes/grades/synchronization/context/context_provider.php +++ b/classes/grades/synchronization/context/context_provider.php @@ -1,4 +1,18 @@ . namespace mod_mumie\synchronization\context; diff --git a/classes/grades/synchronization/context/object_context.php b/classes/grades/synchronization/context/object_context.php index 5118859..616dff5 100644 --- a/classes/grades/synchronization/context/object_context.php +++ b/classes/grades/synchronization/context/object_context.php @@ -1,4 +1,18 @@ . namespace mod_mumie\synchronization\context; diff --git a/classes/grades/synchronization/context/user_context.php b/classes/grades/synchronization/context/user_context.php index 2b1e073..5c27098 100644 --- a/classes/grades/synchronization/context/user_context.php +++ b/classes/grades/synchronization/context/user_context.php @@ -1,4 +1,18 @@ . namespace mod_mumie\synchronization\context; diff --git a/classes/grades/synchronization/payload.php b/classes/grades/synchronization/payload.php index bc3da1a..d0a128f 100644 --- a/classes/grades/synchronization/payload.php +++ b/classes/grades/synchronization/payload.php @@ -1,4 +1,18 @@ . namespace mod_mumie\synchronization; diff --git a/classes/grades/synchronization/xapi_request.php b/classes/grades/synchronization/xapi_request.php index 2391919..8a8b8c7 100644 --- a/classes/grades/synchronization/xapi_request.php +++ b/classes/grades/synchronization/xapi_request.php @@ -1,8 +1,21 @@ . namespace mod_mumie\synchronization; -use CurlHandle; use auth_mumie\mumie_server; class xapi_request { @@ -26,9 +39,9 @@ public function send() { /** * Creates a curl post request for a given url and json payload * - * @return CurlHandle curl handle for json payload + * @return mixed curl handle for json payload */ - public function create_post_curl_request(): CurlHandle { + public function create_post_curl_request() { $ch = curl_init($this->server->get_grade_sync_url()); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_USERAGENT, "My User Agent Name"); From 0b81c60277cf8ae1e9e40c78da8415d2fa476aff Mon Sep 17 00:00:00 2001 From: tobias Date: Wed, 2 Aug 2023 16:12:23 +0200 Subject: [PATCH 10/23] fixed illegal use of camel case --- .../context/object_context.php | 4 ++-- classes/grades/synchronization/payload.php | 23 +++++++++---------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/classes/grades/synchronization/context/object_context.php b/classes/grades/synchronization/context/object_context.php index 616dff5..88f064a 100644 --- a/classes/grades/synchronization/context/object_context.php +++ b/classes/grades/synchronization/context/object_context.php @@ -23,8 +23,8 @@ public function __construct() { $this->usercontexts = array(); } - public function add_user_context(string $userId, user_context $usercontext): void { - $this->usercontexts[$userId] = $usercontext; + public function add_user_context(string $userid, user_context $usercontext): void { + $this->usercontexts[$userid] = $usercontext; } public function jsonSerialize() { diff --git a/classes/grades/synchronization/payload.php b/classes/grades/synchronization/payload.php index d0a128f..e3ad242 100644 --- a/classes/grades/synchronization/payload.php +++ b/classes/grades/synchronization/payload.php @@ -18,29 +18,28 @@ use mod_mumie\synchronization\context\context; -class payload implements \JsonSerializable -{ +class payload implements \JsonSerializable { private array $users; private string $course; - private array $objectIds; - private int $lastSync; - private bool $includeAll; + private array $objectids; + private int $lastsync; + private bool $includeall; private context $context; /** * @param array $users * @param string $course - * @param array $objectIds - * @param int $lastSync - * @param bool $includeAll + * @param array $objectids + * @param int $lastsync + * @param bool $includeall */ - public function __construct(array $users, string $course, array $objectIds, int $lastSync, bool $includeAll) + public function __construct(array $users, string $course, array $objectids, int $lastsync, bool $includeall) { $this->users = $users; $this->course = $course; - $this->objectIds = $objectIds; - $this->lastSync = $lastSync; - $this->includeAll = $includeAll; + $this->objectids = $objectids; + $this->lastsync = $lastsync; + $this->includeall = $includeall; } public function with_context($context): payload { From febb2abd7c664fd5d2707bd11295f72bc614b5a5 Mon Sep 17 00:00:00 2001 From: tobias Date: Wed, 2 Aug 2023 16:16:56 +0200 Subject: [PATCH 11/23] fixed some whitespace issues --- .../context/context_provider.php | 6 +++--- classes/grades/synchronization/payload.php | 6 ++---- .../grades/synchronization/xapi_request.php | 3 +-- gradesync.php | 18 ++++++++++++------ 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/classes/grades/synchronization/context/context_provider.php b/classes/grades/synchronization/context/context_provider.php index dbf7ab3..ec65eeb 100644 --- a/classes/grades/synchronization/context/context_provider.php +++ b/classes/grades/synchronization/context/context_provider.php @@ -25,7 +25,7 @@ public static function get_context(array $mumies, array $users): context { require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/context/context.php"); $context = new context(); foreach ($mumies as $mumie) { - if(self::has_context($mumie)) { + if (self::has_context($mumie)) { $context->add_object_context( self::get_mumie_id($mumie), self::get_object_context($mumie, $users) @@ -36,8 +36,8 @@ public static function get_context(array $mumies, array $users): context { } - //TODO: This is copied from gradesync.php - //Refactor so that we don't have duplicate code + // TODO: This is copied from gradesync.php + // Refactor so that we don't have duplicate code /** * Get the unique identifier for a MUMIE task * diff --git a/classes/grades/synchronization/payload.php b/classes/grades/synchronization/payload.php index e3ad242..b835499 100644 --- a/classes/grades/synchronization/payload.php +++ b/classes/grades/synchronization/payload.php @@ -33,8 +33,7 @@ class payload implements \JsonSerializable { * @param int $lastsync * @param bool $includeall */ - public function __construct(array $users, string $course, array $objectids, int $lastsync, bool $includeall) - { + public function __construct(array $users, string $course, array $objectids, int $lastsync, bool $includeall) { $this->users = $users; $this->course = $course; $this->objectids = $objectids; @@ -47,8 +46,7 @@ public function with_context($context): payload { return $this; } - public function jsonSerialize(): array - { + public function jsonSerialize(): array { return get_object_vars($this); } } diff --git a/classes/grades/synchronization/xapi_request.php b/classes/grades/synchronization/xapi_request.php index 8a8b8c7..c52f267 100644 --- a/classes/grades/synchronization/xapi_request.php +++ b/classes/grades/synchronization/xapi_request.php @@ -22,8 +22,7 @@ class xapi_request { private mumie_server $server; private payload $payload; - public function __construct(mumie_server $server, payload $payload) - { + public function __construct(mumie_server $server, payload $payload) { $this->server = $server; $this->payload = $payload; } diff --git a/gradesync.php b/gradesync.php index d7231d0..bba0578 100644 --- a/gradesync.php +++ b/gradesync.php @@ -24,7 +24,6 @@ */ namespace mod_mumie; -global $CFG; use mod_mumie\synchronization\payload; use mod_mumie\synchronization\xapi_request; @@ -36,6 +35,8 @@ defined('MOODLE_INTERNAL') || die(); +global $CFG; + require_once($CFG->dirroot . '/mod/mumie/lib.php'); require_once($CFG->dirroot . '/auth/mumie/lib.php'); require_once($CFG->dirroot . '/auth/mumie/classes/mumie_server.php'); @@ -119,7 +120,7 @@ public static function get_mumie_grades(stdClass $mumie, int $userid) : ?array { global $COURSE; $mumieusers = array(); - //TODO: extract this into new function + // TODO: extract this into new function if ($userid == 0) { foreach (get_enrolled_users(context_course::instance($COURSE->id)) as $user) { array_push($mumieusers, mumie_user_service::get_user($user->id, $mumie)); @@ -236,9 +237,14 @@ public static function get_xapi_grades(stdClass $mumie, array $mumieusers, array require_once($CFG->dirroot . "/auth/mumie/classes/sso/user/mumie_user.php"); $mumieserver = new mumie_server(); $mumieserver->set_urlprefix($mumie->server); - $syncids = array_map(function ($user) {return $user->get_sync_id();}, $mumieusers); + $syncids = array_map( + function ($user) { + return $user->get_sync_id(); + }, + $mumieusers + ); $payload = new payload($syncids, $mumie->mumie_coursefile, $mumieids, $mumie->lastsync, true); - if(context_provider::has_context($mumie)) { + if (context_provider::has_context($mumie)) { $context = context_provider::get_context(array($mumie), $mumieusers); $payload->with_context($context); } @@ -248,14 +254,14 @@ public static function get_xapi_grades(stdClass $mumie, array $mumieusers, array } - //TODO: replace this with a call to mumie_user_server::get_user + // TODO: replace this with a call to mumie_user_server::get_user. /** * Get moodleUserID from syncid * @param string $syncid * @param int $hashid indicates whether the id was hashed * @return string of moodle user */ - public static function get_moodle_user_id($syncid, $hashid) : ?string { + public static function get_moodle_user_id($syncid, $hashid) : ?string { $userid = substr(strrchr($syncid, "_"), 1); $hashidtable = 'auth_mumie_id_hashes'; if ($hashid == 1) { From 91684aa3d60727fe86cdc011c66ea743b1997e13 Mon Sep 17 00:00:00 2001 From: tobias Date: Wed, 2 Aug 2023 16:33:59 +0200 Subject: [PATCH 12/23] Extracted logic to get mumie_users in gradesync::get_mumie_grades into new method --- gradesync.php | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/gradesync.php b/gradesync.php index bba0578..98fce6b 100644 --- a/gradesync.php +++ b/gradesync.php @@ -117,26 +117,15 @@ public static function get_all_mumie_tasks_for_user($userid) : array { * @return array grades for the given MUMIE task */ public static function get_mumie_grades(stdClass $mumie, int $userid) : ?array { - global $COURSE; - $mumieusers = array(); - - // TODO: extract this into new function - if ($userid == 0) { - foreach (get_enrolled_users(context_course::instance($COURSE->id)) as $user) { - array_push($mumieusers, mumie_user_service::get_user($user->id, $mumie)); - } - } else { - $mumieusers = array(mumie_user_service::get_user($userid, $mumie)); - } - + $mumieusers = self::get_mumie_users($mumie, $userid); $mumieids = array(self::get_mumie_id($mumie)); - $grades = array(); $xapigrades = self::get_xapi_grades($mumie, $mumieusers, $mumieids); if (is_null($xapigrades)) { return null; } + $grades = array(); foreach ($xapigrades as $xapigrade) { $grade = self::xapi_to_moodle_grade($xapigrade, $mumie); if (self::include_grade($mumie, $grades, $grade)) { @@ -146,6 +135,19 @@ public static function get_mumie_grades(stdClass $mumie, int $userid) : ?array { return $grades; } + private static function get_mumie_users(stdClass $mumie, int $userid): array { + global $COURSE; + if ($userid == 0) { + $mumieusers = array(); + foreach (get_enrolled_users(context_course::instance($COURSE->id)) as $user) { + $mumieusers[] = mumie_user_service::get_user($user->id, $mumie); + } + return $mumieusers; + } else { + return array(mumie_user_service::get_user($userid, $mumie)); + } + } + /** * Get all grades a user has archived for a given MUMIE Task * From 469e16f82c902d0261fdf442182f7ce2f538b10c Mon Sep 17 00:00:00 2001 From: tobias Date: Wed, 2 Aug 2023 17:16:49 +0200 Subject: [PATCH 13/23] Removed some code duplicates --- gradesync.php | 47 +++++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/gradesync.php b/gradesync.php index 98fce6b..0a7ed46 100644 --- a/gradesync.php +++ b/gradesync.php @@ -32,6 +32,7 @@ use stdClass; use context_course; use auth_mumie\mumie_server; +use auth_mumie\user\mumie_user; defined('MOODLE_INTERNAL') || die(); @@ -78,7 +79,6 @@ public static function update() { } } } - return; } /** @@ -86,7 +86,7 @@ public static function update() { * @param int $courseid * @return array All MUMIE tasks that are used in the given course */ - public static function get_mumie_tasks_from_course($courseid) : array { + public static function get_mumie_tasks_from_course(int $courseid) : array { global $DB; return $DB->get_records(MUMIE_TASK_TABLE, array("course" => $courseid, "isgraded" => 1)); } @@ -97,7 +97,7 @@ public static function get_mumie_tasks_from_course($courseid) : array { * @param int $userid * @return array All MUMIE tasks that are in courses, the user is enrolled in */ - public static function get_all_mumie_tasks_for_user($userid) : array { + public static function get_all_mumie_tasks_for_user(int $userid) : array { $allmumietasks = array(); foreach (enrol_get_all_users_courses($userid) as $course) { $mumietasks = self::get_mumie_tasks_from_course($course->id); @@ -127,7 +127,7 @@ public static function get_mumie_grades(stdClass $mumie, int $userid) : ?array { $grades = array(); foreach ($xapigrades as $xapigrade) { - $grade = self::xapi_to_moodle_grade($xapigrade, $mumie); + $grade = self::xapi_to_moodle_grade($xapigrade); if (self::include_grade($mumie, $grades, $grade)) { $grades[$grade->userid] = $grade; } @@ -167,7 +167,7 @@ public static function get_all_grades_for_user(stdClass $mumie, int $userid) : ? } foreach ($xapigrades as $xapigrade) { - $grade = self::xapi_to_moodle_grade($xapigrade, $mumie); + $grade = self::xapi_to_moodle_grade($xapigrade); $grades[] = $grade; } return $grades; @@ -177,17 +177,22 @@ public static function get_all_grades_for_user(stdClass $mumie, int $userid) : ? * Transform Xapi grade to moodle grade objects. * * @param stdClass $xapigrade - * @param stdClass $mumie * @return stdClass */ - private static function xapi_to_moodle_grade($xapigrade, stdClass $mumie) : stdClass { + private static function xapi_to_moodle_grade($xapigrade) : stdClass { $grade = new stdClass(); - $grade->userid = self::get_moodle_user_id($xapigrade->actor->account->name, $mumie->use_hashed_id); + $grade->userid = self::get_user_from_sync_id($xapigrade->actor->account->name)->get_moodle_id(); $grade->rawgrade = 100 * $xapigrade->result->score->raw; $grade->timecreated = strtotime($xapigrade->timestamp); return $grade; } + + private static function get_user_from_sync_id(string $syncid): ?mumie_user { + $mumieid = substr(strrchr($syncid, "_"), 1); + return mumie_user_service::get_user_from_mumie_id($mumieid); + } + /** * Indicate whether a grade was archived before the task was due and is the latest one currently available * @@ -229,9 +234,9 @@ private static function is_latest_grade(array $grades, stdClass $potentialgrade) * @param stdClass $mumie instance of MUMIE task we want to get grades for * @param array $mumieusers all users we want grades for * @param array $mumieids mumieid of mumie instance as an array - * @return stdClass all requested grades for the given MUMIE task + * @return stdClass | null all requested grades for the given MUMIE task or null */ - public static function get_xapi_grades(stdClass $mumie, array $mumieusers, array $mumieids) { + public static function get_xapi_grades(stdClass $mumie, array $mumieusers, array $mumieids) : ?stdClass { global $CFG; require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/payload.php"); require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/xapi_request.php"); @@ -252,25 +257,11 @@ function ($user) { } debugging(json_encode($payload)); $request = new xapi_request($mumieserver, $payload); - return $request->send(); - } - - - // TODO: replace this with a call to mumie_user_server::get_user. - /** - * Get moodleUserID from syncid - * @param string $syncid - * @param int $hashid indicates whether the id was hashed - * @return string of moodle user - */ - public static function get_moodle_user_id($syncid, $hashid) : ?string { - $userid = substr(strrchr($syncid, "_"), 1); - $hashidtable = 'auth_mumie_id_hashes'; - if ($hashid == 1) { - global $DB; - $userid = $DB->get_record($hashidtable, array("hash" => $userid))->the_user; + $result = $request->send(); + if ($result->status == 200) { + return $result; } - return $userid; + return null; } /** From d977cb6948b93e63fec8f1de79091dd0ff374b82 Mon Sep 17 00:00:00 2001 From: tobias Date: Wed, 2 Aug 2023 17:31:49 +0200 Subject: [PATCH 14/23] fixed missing camel case in xapi_request --- classes/grades/synchronization/payload.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/classes/grades/synchronization/payload.php b/classes/grades/synchronization/payload.php index b835499..66ec390 100644 --- a/classes/grades/synchronization/payload.php +++ b/classes/grades/synchronization/payload.php @@ -47,6 +47,16 @@ public function with_context($context): payload { } public function jsonSerialize(): array { - return get_object_vars($this); + $json = array( + "users" => $this->users, + "course" => $this->course, + "objectIds" => $this->objectids, + "lastSync" => $this->lastsync, + "includeAll" => $this->includeall + ); + if (isset($this->context)) { + $json["context"] = $this->context; + } + return $json; } } From e8767d583ebfc131f678eac6842d5951718e794a Mon Sep 17 00:00:00 2001 From: tobias Date: Thu, 3 Aug 2023 12:14:17 +0200 Subject: [PATCH 15/23] WIP fixing issue where --- classes/grades/synchronization/xapi_request.php | 14 ++++++++++---- gradesync.php | 13 ++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/classes/grades/synchronization/xapi_request.php b/classes/grades/synchronization/xapi_request.php index c52f267..6f74aa0 100644 --- a/classes/grades/synchronization/xapi_request.php +++ b/classes/grades/synchronization/xapi_request.php @@ -27,12 +27,18 @@ public function __construct(mumie_server $server, payload $payload) { $this->payload = $payload; } - public function send() { + public function send(): array { $ch = $this->create_post_curl_request(); - $result = curl_exec($ch); - + $result = (array) json_decode(curl_exec($ch)); curl_close($ch); - return json_decode($result); + if ($this->has_error($result)) { + return array(); + } + return $result; + } + + private function has_error($response): bool { + return array_key_exists("status", $response) && $response["status"] !== 200; } /** diff --git a/gradesync.php b/gradesync.php index 0a7ed46..37cd3e9 100644 --- a/gradesync.php +++ b/gradesync.php @@ -121,7 +121,7 @@ public static function get_mumie_grades(stdClass $mumie, int $userid) : ?array { $mumieids = array(self::get_mumie_id($mumie)); $xapigrades = self::get_xapi_grades($mumie, $mumieusers, $mumieids); - if (is_null($xapigrades)) { + if (empty($xapigrades)) { return null; } @@ -234,9 +234,9 @@ private static function is_latest_grade(array $grades, stdClass $potentialgrade) * @param stdClass $mumie instance of MUMIE task we want to get grades for * @param array $mumieusers all users we want grades for * @param array $mumieids mumieid of mumie instance as an array - * @return stdClass | null all requested grades for the given MUMIE task or null + * @return array all requested grades for the given MUMIE task */ - public static function get_xapi_grades(stdClass $mumie, array $mumieusers, array $mumieids) : ?stdClass { + public static function get_xapi_grades(stdClass $mumie, array $mumieusers, array $mumieids) : array { global $CFG; require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/payload.php"); require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/xapi_request.php"); @@ -255,13 +255,8 @@ function ($user) { $context = context_provider::get_context(array($mumie), $mumieusers); $payload->with_context($context); } - debugging(json_encode($payload)); $request = new xapi_request($mumieserver, $payload); - $result = $request->send(); - if ($result->status == 200) { - return $result; - } - return null; + return $request->send(); } /** From 7155330dbc3445cf0f38ba49557474d0a81dfb64 Mon Sep 17 00:00:00 2001 From: tobias Date: Thu, 3 Aug 2023 12:33:30 +0200 Subject: [PATCH 16/23] moved get_mumie_id to locallib so that it can be used by multiple classes --- .../context/context_provider.php | 21 +-------------- gradesync.php | 24 +++-------------- locallib.php | 26 ++++++++++++++++--- 3 files changed, 27 insertions(+), 44 deletions(-) diff --git a/classes/grades/synchronization/context/context_provider.php b/classes/grades/synchronization/context/context_provider.php index ec65eeb..9cb6b2f 100644 --- a/classes/grades/synchronization/context/context_provider.php +++ b/classes/grades/synchronization/context/context_provider.php @@ -27,7 +27,7 @@ public static function get_context(array $mumies, array $users): context { foreach ($mumies as $mumie) { if (self::has_context($mumie)) { $context->add_object_context( - self::get_mumie_id($mumie), + locallib::get_mumie_id($mumie), self::get_object_context($mumie, $users) ); } @@ -35,25 +35,6 @@ public static function get_context(array $mumies, array $users): context { return $context; } - - // TODO: This is copied from gradesync.php - // Refactor so that we don't have duplicate code - /** - * Get the unique identifier for a MUMIE task - * - * @param stdClass $mumietask - * @return string id for MUMIE task on MUMIE/LEMON server - */ - private static function get_mumie_id($mumietask): string { - $id = $mumietask->taskurl; - $prefix = "link/"; - if (strpos($id, $prefix) !== false) { - $id = substr($mumietask->taskurl, strlen($prefix)); - } - $id = substr($id, 0, strpos($id, '?lang=')); - return $id; - } - public static function has_context($mumie): bool { return str_starts_with($mumie->taskurl, "worksheet_") && $mumie->duedate > 0; diff --git a/gradesync.php b/gradesync.php index 37cd3e9..03baeb3 100644 --- a/gradesync.php +++ b/gradesync.php @@ -39,6 +39,7 @@ global $CFG; require_once($CFG->dirroot . '/mod/mumie/lib.php'); +require_once($CFG->dirroot . "/mod/mumie/locallib.php"); require_once($CFG->dirroot . '/auth/mumie/lib.php'); require_once($CFG->dirroot . '/auth/mumie/classes/mumie_server.php'); require_once($CFG->dirroot . '/mod/mumie/classes/mumie_duedate_extension.php'); @@ -118,7 +119,7 @@ public static function get_all_mumie_tasks_for_user(int $userid) : array { */ public static function get_mumie_grades(stdClass $mumie, int $userid) : ?array { $mumieusers = self::get_mumie_users($mumie, $userid); - $mumieids = array(self::get_mumie_id($mumie)); + $mumieids = array(locallib::get_mumie_id($mumie)); $xapigrades = self::get_xapi_grades($mumie, $mumieusers, $mumieids); if (empty($xapigrades)) { @@ -158,11 +159,11 @@ private static function get_mumie_users(stdClass $mumie, int $userid): array { public static function get_all_grades_for_user(stdClass $mumie, int $userid) : ?array { $mumieusers = [mumie_user_service::get_user($userid, $mumie)]; - $mumieids = array(self::get_mumie_id($mumie)); + $mumieids = array(locallib::get_mumie_id($mumie)); $grades = array(); $xapigrades = self::get_xapi_grades($mumie, $mumieusers, $mumieids); - if (is_null($xapigrades)) { + if (empty($xapigrades)) { return null; } @@ -202,8 +203,6 @@ private static function get_user_from_sync_id(string $syncid): ?mumie_user { * @return boolean Whether the grade should be added to $grades */ public static function include_grade(stdClass $mumie, array $grades, stdClass $potentialgrade) : bool { - global $CFG; - require_once($CFG->dirroot . "/mod/mumie/locallib.php"); $duedate = locallib::get_effective_duedate($potentialgrade->userid, $mumie); if (!isset($duedate) || $duedate == 0) { return true; @@ -258,19 +257,4 @@ function ($user) { $request = new xapi_request($mumieserver, $payload); return $request->send(); } - - /** - * Get the unique identifier for a MUMIE task - * - * @param stdClass $mumietask - * @return string id for MUMIE task on MUMIE/LEMON server - */ - public static function get_mumie_id(stdClass $mumietask) : string { - $id = $mumietask->taskurl; - $prefix = "link/"; - if (strpos($id, $prefix) !== false) { - $id = substr($mumietask->taskurl, strlen($prefix)); - } - return substr($id, 0, strpos($id, '?lang=')); - } } diff --git a/locallib.php b/locallib.php index c6912f3..a891295 100644 --- a/locallib.php +++ b/locallib.php @@ -26,10 +26,12 @@ defined('MOODLE_INTERNAL') || die; -require_once($CFG->dirroot . '/mod/mumie/lib.php'); - global $CFG; -global $DB; + +use stdClass; + + +require_once($CFG->dirroot . '/mod/mumie/lib.php'); define("MUMIE_LAUNCH_CONTAINER_WINDOW", 0); define("MUMIE_LAUNCH_CONTAINER_EMBEDDED", 1); @@ -78,7 +80,7 @@ public static function get_mumie_tasks_by_course($courseid) { /** * The function is called whenever a MUMIE task is updated or created. * If a pending decision regarding gradepools was made, we need to update all other MUMIE Tasks in this course as well. - * @param stcClass $mumietask The update we are processing + * @param stdClass $mumietask The update we are processing */ public static function update_pending_gradepool($mumietask) { global $DB; @@ -219,4 +221,20 @@ public static function get_effective_duedate($userid, $mumie) { } return $mumie->duedate; } + + /** + * Get the unique identifier for a MUMIE task + * + * @param stdClass $mumietask + * @return string id for MUMIE task on MUMIE/LEMON server + */ + public static function get_mumie_id($mumietask): string { + $id = $mumietask->taskurl; + $prefix = "link/"; + if (strpos($id, $prefix) !== false) { + $id = substr($mumietask->taskurl, strlen($prefix)); + } + $id = substr($id, 0, strpos($id, '?lang=')); + return $id; + } } From 45738d0152c5a223c7c709289b28a9c390eec598 Mon Sep 17 00:00:00 2001 From: tobias Date: Thu, 3 Aug 2023 14:29:44 +0200 Subject: [PATCH 17/23] Added missing php docs --- .../synchronization/context/context.php | 24 ++++++++++ .../context/context_provider.php | 46 ++++++++++++++++--- .../context/object_context.php | 24 ++++++++++ .../synchronization/context/user_context.php | 16 +++++++ classes/grades/synchronization/payload.php | 38 ++++++++++++++- .../grades/synchronization/xapi_request.php | 30 +++++++++++- gradesync.php | 17 ++++++- 7 files changed, 185 insertions(+), 10 deletions(-) diff --git a/classes/grades/synchronization/context/context.php b/classes/grades/synchronization/context/context.php index 7c9459b..650b98d 100644 --- a/classes/grades/synchronization/context/context.php +++ b/classes/grades/synchronization/context/context.php @@ -16,17 +16,41 @@ namespace mod_mumie\synchronization\context; +/** + * This class holds context for multiple MUMIE Tasks required for some XAPI requests. + * + * @package mod_mumie + * @copyright 2017-2023 integral-learning GmbH (https://www.integral-learning.de/) + * @author Tobias Goltz (tobias.goltz@integral-learning.de) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ class context implements \JsonSerializable { + /** + * @var array + */ private array $objectcontexts; + /** + * Create a new instance. + */ public function __construct() { $this->objectcontexts = array(); } + /** + * Add a new ObjectContext to this context. + * @param string $objectid + * @param object_context $objectcontext + * @return void + */ public function add_object_context(string $objectid, object_context $objectcontext): void { $this->objectcontexts[$objectid] = $objectcontext; } + /** + * Custom json serialization. + * @return array + */ public function jsonSerialize() : array { return $this->objectcontexts; } diff --git a/classes/grades/synchronization/context/context_provider.php b/classes/grades/synchronization/context/context_provider.php index 9cb6b2f..d5257c8 100644 --- a/classes/grades/synchronization/context/context_provider.php +++ b/classes/grades/synchronization/context/context_provider.php @@ -18,39 +18,73 @@ use mod_mumie\locallib; use auth_mumie\user\mumie_user; +use stdClass; +/** + * This service is used to create the context that is required for some XAPI requests. + * + * @package mod_mumie + * @copyright 2017-2023 integral-learning GmbH (https://www.integral-learning.de/) + * @author Tobias Goltz (tobias.goltz@integral-learning.de) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ class context_provider { + /** + * Get context for a given list of mumie tasks and users. + * + * @param array $mumies + * @param array $users + * @return context + */ public static function get_context(array $mumies, array $users): context { global $CFG; require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/context/context.php"); $context = new context(); foreach ($mumies as $mumie) { - if (self::has_context($mumie)) { + if (self::requires_context($mumie)) { $context->add_object_context( locallib::get_mumie_id($mumie), - self::get_object_context($mumie, $users) + self::create_object_context($mumie, $users) ); } } return $context; } - public static function has_context($mumie): bool { + /** + * Check whether a MUMIE Task requires context for XAPI requests. + * @param stdClass $mumie + * @return bool + */ + public static function requires_context(stdClass $mumie): bool { return str_starts_with($mumie->taskurl, "worksheet_") && $mumie->duedate > 0; } - private static function get_object_context($mumie, array $users): object_context { + /** + * Create a new object_context instance for a given list of users. + * + * @param stdClass $mumie + * @param array $users + * @return object_context + */ + private static function create_object_context(stdClass $mumie, array $users): object_context { global $CFG; require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/context/object_context.php"); $context = new object_context(); foreach ($users as $user) { - $context->add_user_context($user->get_sync_id(), self::get_user_context($mumie, $user)); + $context->add_user_context($user->get_sync_id(), self::create_user_context($mumie, $user)); } return $context; } - private static function get_user_context($mumie, mumie_user $user): user_context { + /** + * Create a new user_context instance for a given user and MUMIE Task + * @param stdClass $mumie + * @param mumie_user $user + * @return user_context + */ + private static function create_user_context(stdClass $mumie, mumie_user $user): user_context { global $CFG; require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/context/user_context.php"); return new user_context(locallib::get_effective_duedate($user->get_moodle_id(), $mumie)); diff --git a/classes/grades/synchronization/context/object_context.php b/classes/grades/synchronization/context/object_context.php index 88f064a..2cb23c4 100644 --- a/classes/grades/synchronization/context/object_context.php +++ b/classes/grades/synchronization/context/object_context.php @@ -16,17 +16,41 @@ namespace mod_mumie\synchronization\context; +/** + * This class represents a single MUMIE Tasks context required for some XAPI requests. + * + * @package mod_mumie + * @copyright 2017-2023 integral-learning GmbH (https://www.integral-learning.de/) + * @author Tobias Goltz (tobias.goltz@integral-learning.de) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ class object_context implements \JsonSerializable { + /** + * @var array + */ private array $usercontexts; + /** + * Create a new instance. + */ public function __construct() { $this->usercontexts = array(); } + /** + * Add a new context for a given user. + * @param string $userid + * @param user_context $usercontext + * @return void + */ public function add_user_context(string $userid, user_context $usercontext): void { $this->usercontexts[$userid] = $usercontext; } + /** + * Custom JSON serializer. + * @return array + */ public function jsonSerialize() { return $this->usercontexts; } diff --git a/classes/grades/synchronization/context/user_context.php b/classes/grades/synchronization/context/user_context.php index 5c27098..332fac9 100644 --- a/classes/grades/synchronization/context/user_context.php +++ b/classes/grades/synchronization/context/user_context.php @@ -16,16 +16,32 @@ namespace mod_mumie\synchronization\context; +/** + * This class represents the context in which a user is working on a MUMIE Task. + * + * @package mod_mumie + * @copyright 2017-2023 integral-learning GmbH (https://www.integral-learning.de/) + * @author Tobias Goltz (tobias.goltz@integral-learning.de) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ class user_context implements \JsonSerializable { + /** + * @var int + */ private int $deadline; /** + * Create new instance. * @param int $deadline */ public function __construct(int $deadline) { $this->deadline = $deadline; } + /** + * Custom JSON serializer. + * @return array|mixed + */ public function jsonSerialize() { return get_object_vars($this); } diff --git a/classes/grades/synchronization/payload.php b/classes/grades/synchronization/payload.php index 66ec390..733924a 100644 --- a/classes/grades/synchronization/payload.php +++ b/classes/grades/synchronization/payload.php @@ -18,15 +18,42 @@ use mod_mumie\synchronization\context\context; +/** + * This class represents the payload used in XAPI requests for MUMIE Task grade synchronization + * + * @package mod_mumie + * @copyright 2017-2023 integral-learning GmbH (https://www.integral-learning.de/) + * @author Tobias Goltz (tobias.goltz@integral-learning.de) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ class payload implements \JsonSerializable { + /** + * @var array + */ private array $users; + /** + * @var string + */ private string $course; + /** + * @var array + */ private array $objectids; + /** + * @var int + */ private int $lastsync; + /** + * @var bool + */ private bool $includeall; + /** + * @var context + */ private context $context; /** + * Create a new instance. * @param array $users * @param string $course * @param array $objectids @@ -41,11 +68,20 @@ public function __construct(array $users, string $course, array $objectids, int $this->includeall = $includeall; } - public function with_context($context): payload { + /** + * Add context to the payload. + * @param context $context + * @return $this + */ + public function with_context(context $context): payload { $this->context = $context; return $this; } + /** + * Custom JSON serializer. + * @return array + */ public function jsonSerialize(): array { $json = array( "users" => $this->users, diff --git a/classes/grades/synchronization/xapi_request.php b/classes/grades/synchronization/xapi_request.php index 6f74aa0..1edd66d 100644 --- a/classes/grades/synchronization/xapi_request.php +++ b/classes/grades/synchronization/xapi_request.php @@ -18,15 +18,38 @@ use auth_mumie\mumie_server; +/** + * This class represents an xapi request used to retrieve grades for MUMIE Tasks, + * + * @package mod_mumie + * @copyright 2017-2023 integral-learning GmbH (https://www.integral-learning.de/) + * @author Tobias Goltz (tobias.goltz@integral-learning.de) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ class xapi_request { + /** + * @var mumie_server + */ private mumie_server $server; + /** + * @var payload + */ private payload $payload; + /** + * Create a new instance. + * @param mumie_server $server + * @param payload $payload + */ public function __construct(mumie_server $server, payload $payload) { $this->server = $server; $this->payload = $payload; } + /** + * Send the request. + * @return array + */ public function send(): array { $ch = $this->create_post_curl_request(); $result = (array) json_decode(curl_exec($ch)); @@ -37,7 +60,12 @@ public function send(): array { return $result; } - private function has_error($response): bool { + /** + * Check if the request failed. + * @param array $response + * @return bool + */ + private function has_error(array $response): bool { return array_key_exists("status", $response) && $response["status"] !== 200; } diff --git a/gradesync.php b/gradesync.php index 03baeb3..e4ad006 100644 --- a/gradesync.php +++ b/gradesync.php @@ -136,6 +136,14 @@ public static function get_mumie_grades(stdClass $mumie, int $userid) : ?array { return $grades; } + /** + * Get an array of MUMIE users that have can submit answers to a given MUMIE Task. + * + * If $userid is 0, all possible students are returned. Otherwise, the array will only contain the user with the given $userid. + * @param stdClass $mumie + * @param int $userid + * @return array + */ private static function get_mumie_users(stdClass $mumie, int $userid): array { global $COURSE; if ($userid == 0) { @@ -188,7 +196,12 @@ private static function xapi_to_moodle_grade($xapigrade) : stdClass { return $grade; } - + /** + * Get a mumie_user from a syncid. + * @param string $syncid + * @return mumie_user|null + * @throws \dml_exception + */ private static function get_user_from_sync_id(string $syncid): ?mumie_user { $mumieid = substr(strrchr($syncid, "_"), 1); return mumie_user_service::get_user_from_mumie_id($mumieid); @@ -250,7 +263,7 @@ function ($user) { $mumieusers ); $payload = new payload($syncids, $mumie->mumie_coursefile, $mumieids, $mumie->lastsync, true); - if (context_provider::has_context($mumie)) { + if (context_provider::requires_context($mumie)) { $context = context_provider::get_context(array($mumie), $mumieusers); $payload->with_context($context); } From 91416ada4c70ab9917212663862e6250a9635dbc Mon Sep 17 00:00:00 2001 From: tobias Date: Thu, 3 Aug 2023 14:38:47 +0200 Subject: [PATCH 18/23] Removed unnecessary local variable --- gradesync.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gradesync.php b/gradesync.php index e4ad006..1b56572 100644 --- a/gradesync.php +++ b/gradesync.php @@ -176,8 +176,7 @@ public static function get_all_grades_for_user(stdClass $mumie, int $userid) : ? } foreach ($xapigrades as $xapigrade) { - $grade = self::xapi_to_moodle_grade($xapigrade); - $grades[] = $grade; + $grades[] = self::xapi_to_moodle_grade($xapigrade); } return $grades; } From f238cf7b83ab855859f3ae9b2b4755b32e2f165f Mon Sep 17 00:00:00 2001 From: tobias Date: Thu, 3 Aug 2023 14:40:06 +0200 Subject: [PATCH 19/23] Renamed method to clearly indicate the return type. --- gradesync.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradesync.php b/gradesync.php index 1b56572..9d87725 100644 --- a/gradesync.php +++ b/gradesync.php @@ -189,7 +189,7 @@ public static function get_all_grades_for_user(stdClass $mumie, int $userid) : ? */ private static function xapi_to_moodle_grade($xapigrade) : stdClass { $grade = new stdClass(); - $grade->userid = self::get_user_from_sync_id($xapigrade->actor->account->name)->get_moodle_id(); + $grade->userid = self::get_mumie_user_from_sync_id($xapigrade->actor->account->name)->get_moodle_id(); $grade->rawgrade = 100 * $xapigrade->result->score->raw; $grade->timecreated = strtotime($xapigrade->timestamp); return $grade; @@ -201,7 +201,7 @@ private static function xapi_to_moodle_grade($xapigrade) : stdClass { * @return mumie_user|null * @throws \dml_exception */ - private static function get_user_from_sync_id(string $syncid): ?mumie_user { + private static function get_mumie_user_from_sync_id(string $syncid): ?mumie_user { $mumieid = substr(strrchr($syncid, "_"), 1); return mumie_user_service::get_user_from_mumie_id($mumieid); } From fd966758357bb0c125b4748908847abab052ff87 Mon Sep 17 00:00:00 2001 From: tobias Date: Thu, 3 Aug 2023 15:24:13 +0200 Subject: [PATCH 20/23] Added missing php docs --- lib.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib.php b/lib.php index c782a20..0a932be 100644 --- a/lib.php +++ b/lib.php @@ -488,6 +488,15 @@ function mumie_update_multiple_tasks($mumie) { } } -function mumie_get_effective_duedate($userid, $mumie) { +/** + * Get the effective duedate for a student. + * + * Individual due date extensions always overrule general due date settings. + * + * @param int $userid + * @param stdClass $mumie + * @return int + */ +function mumie_get_effective_duedate(int $userid, stdClass $mumie): int { return locallib::get_effective_duedate($userid, $mumie); } From 12bc85cdeceef38b88c36f13e3b35eae1c19d940 Mon Sep 17 00:00:00 2001 From: Filip Sacha Date: Thu, 21 Sep 2023 15:25:15 +0200 Subject: [PATCH 21/23] Provide the deadline in milliseconds for the XAPI request --- .../grades/synchronization/context/context_provider.php | 3 ++- lib.php | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/classes/grades/synchronization/context/context_provider.php b/classes/grades/synchronization/context/context_provider.php index d5257c8..edfdd62 100644 --- a/classes/grades/synchronization/context/context_provider.php +++ b/classes/grades/synchronization/context/context_provider.php @@ -87,6 +87,7 @@ private static function create_object_context(stdClass $mumie, array $users): ob private static function create_user_context(stdClass $mumie, mumie_user $user): user_context { global $CFG; require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/context/user_context.php"); - return new user_context(locallib::get_effective_duedate($user->get_moodle_id(), $mumie)); + require_once($CFG->dirroot . '/mod/mumie/lib.php'); + return new user_context(mumie_get_deadline_in_ms(locallib::get_effective_duedate($user->get_moodle_id(), $mumie))); } } diff --git a/lib.php b/lib.php index 0a932be..a98c0cf 100644 --- a/lib.php +++ b/lib.php @@ -500,3 +500,12 @@ function mumie_update_multiple_tasks($mumie) { function mumie_get_effective_duedate(int $userid, stdClass $mumie): int { return locallib::get_effective_duedate($userid, $mumie); } + +/** + * Transforms the deadline(Unix Timestamp) from seconds to milliseconds. + * @param int $deadline timestamp in s + * @return int timestamp in ms + */ +function mumie_get_deadline_in_ms($deadline) { + return $deadline * 1000; +} From ad8eddebd529a98f9bd839e80ba8962a589219cb Mon Sep 17 00:00:00 2001 From: Filip Date: Mon, 16 Oct 2023 17:29:49 +0200 Subject: [PATCH 22/23] Resolve threads --- .../synchronization/context/context_provider.php | 16 ++++++++-------- classes/grades/synchronization/xapi_request.php | 4 ++-- gradesync.php | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/classes/grades/synchronization/context/context_provider.php b/classes/grades/synchronization/context/context_provider.php index edfdd62..82a610c 100644 --- a/classes/grades/synchronization/context/context_provider.php +++ b/classes/grades/synchronization/context/context_provider.php @@ -21,7 +21,7 @@ use stdClass; /** - * This service is used to create the context that is required for some XAPI requests. + * This class is used to create the context that is required for some XAPI requests. * * @package mod_mumie * @copyright 2017-2023 integral-learning GmbH (https://www.integral-learning.de/) @@ -30,21 +30,21 @@ */ class context_provider { /** - * Get context for a given list of mumie tasks and users. + * Get context for a given list of MUMIE Tasks and users. * - * @param array $mumies + * @param array $mumietasks * @param array $users * @return context */ - public static function get_context(array $mumies, array $users): context { + public static function get_context(array $mumietasks, array $users): context { global $CFG; require_once($CFG->dirroot . "/mod/mumie/classes/grades/synchronization/context/context.php"); $context = new context(); - foreach ($mumies as $mumie) { - if (self::requires_context($mumie)) { + foreach ($mumietasks as $mumietask) { + if (self::requires_context($mumietask)) { $context->add_object_context( - locallib::get_mumie_id($mumie), - self::create_object_context($mumie, $users) + locallib::get_mumie_id($mumietask), + self::create_object_context($mumietask, $users) ); } } diff --git a/classes/grades/synchronization/xapi_request.php b/classes/grades/synchronization/xapi_request.php index 1edd66d..52f99e5 100644 --- a/classes/grades/synchronization/xapi_request.php +++ b/classes/grades/synchronization/xapi_request.php @@ -19,7 +19,7 @@ use auth_mumie\mumie_server; /** - * This class represents an xapi request used to retrieve grades for MUMIE Tasks, + * This class represents an xapi request used to retrieve grades for MUMIE Tasks. * * @package mod_mumie * @copyright 2017-2023 integral-learning GmbH (https://www.integral-learning.de/) @@ -77,7 +77,7 @@ private function has_error(array $response): bool { public function create_post_curl_request() { $ch = curl_init($this->server->get_grade_sync_url()); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); - curl_setopt($ch, CURLOPT_USERAGENT, "My User Agent Name"); + curl_setopt($ch, CURLOPT_USERAGENT, "Default User Name"); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($this->payload)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt( diff --git a/gradesync.php b/gradesync.php index 9d87725..ad03897 100644 --- a/gradesync.php +++ b/gradesync.php @@ -137,7 +137,7 @@ public static function get_mumie_grades(stdClass $mumie, int $userid) : ?array { } /** - * Get an array of MUMIE users that have can submit answers to a given MUMIE Task. + * Get an array of MUMIE users that can submit answers to a given MUMIE Task. * * If $userid is 0, all possible students are returned. Otherwise, the array will only contain the user with the given $userid. * @param stdClass $mumie From 4d0c82d659cd1f1753af6b7747afc3c428365af4 Mon Sep 17 00:00:00 2001 From: Filip Date: Wed, 18 Oct 2023 11:19:12 +0200 Subject: [PATCH 23/23] Remove user agent form xapi request --- classes/grades/synchronization/xapi_request.php | 1 - 1 file changed, 1 deletion(-) diff --git a/classes/grades/synchronization/xapi_request.php b/classes/grades/synchronization/xapi_request.php index 52f99e5..5e0de24 100644 --- a/classes/grades/synchronization/xapi_request.php +++ b/classes/grades/synchronization/xapi_request.php @@ -77,7 +77,6 @@ private function has_error(array $response): bool { public function create_post_curl_request() { $ch = curl_init($this->server->get_grade_sync_url()); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); - curl_setopt($ch, CURLOPT_USERAGENT, "Default User Name"); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($this->payload)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt(