Skip to content

Commit 717e65d

Browse files
authored
feat: bridges to retrieve additional attempt information
1 parent e5de1ce commit 717e65d

File tree

5 files changed

+466
-0
lines changed

5 files changed

+466
-0
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
// This file is part of the QuestionPy Moodle plugin - https://questionpy.org
3+
//
4+
// Moodle is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// Moodle is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16+
17+
namespace qtype_questionpy\local\bridge;
18+
19+
use qtype_questionpy\question_bridge_base;
20+
21+
/**
22+
* Bridge class between QuestionPy and core_question_preview.
23+
*
24+
* This class is used to retrieve data that is not available through the Question API.
25+
*
26+
* @package qtype_questionpy
27+
* @author Martin Gauk
28+
* @copyright 2025 TU Berlin, innoCampus {@link https://www.questionpy.org}
29+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
30+
*/
31+
class core_question_preview extends question_bridge_base {
32+
/** @var \stdClass|null quiz attempt data as stored in database. */
33+
private $quizattempt;
34+
35+
/**
36+
* Get additional LMS attributes.
37+
*
38+
* @param string[] $requestedattributes
39+
* @return string[]
40+
*/
41+
protected function get_additional_lms_attributes(array $requestedattributes): array {
42+
$attributes = [];
43+
44+
if (in_array('attempt_started_at', $requestedattributes)) {
45+
$firststep = $this->attempt->get_step(0);
46+
$attributes['attempt_started_at'] = date('c', $firststep->get_timecreated());
47+
}
48+
49+
if (in_array('lms_moodle_component_name', $requestedattributes)) {
50+
$attributes['lms_moodle_component_name'] = 'core_question_preview';
51+
}
52+
53+
return $attributes;
54+
}
55+
56+
/**
57+
* Get user or group id this attempt belongs to.
58+
*
59+
* @return array<'user'|'group', int>
60+
*/
61+
public function get_user_or_group_id(): array {
62+
if ($this->context instanceof \core\context\user) {
63+
return ['user', $this->context->instanceid];
64+
}
65+
throw new \coding_exception('Expected a user context, got ' . get_class($this->context));
66+
}
67+
}

classes/local/bridge/mod_quiz.php

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
// This file is part of the QuestionPy Moodle plugin - https://questionpy.org
3+
//
4+
// Moodle is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// Moodle is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16+
17+
namespace qtype_questionpy\local\bridge;
18+
19+
use qtype_questionpy\question_bridge_base;
20+
21+
/**
22+
* Bridge class between QuestionPy and mod_quiz.
23+
*
24+
* This class is used to retrieve data that is not available through the Question API.
25+
*
26+
* @package qtype_questionpy
27+
* @author Martin Gauk
28+
* @copyright 2025 TU Berlin, innoCampus {@link https://www.questionpy.org}
29+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
30+
*/
31+
class mod_quiz extends question_bridge_base {
32+
/** @var \stdClass|null quiz attempt data as stored in database. */
33+
private $quizattempt = null;
34+
35+
/**
36+
* Get additional LMS attributes.
37+
*
38+
* @param string[] $requestedattributes
39+
* @return string[]
40+
*/
41+
protected function get_additional_lms_attributes(array $requestedattributes): array {
42+
$attributes = [];
43+
44+
if (in_array('attempt_started_at', $requestedattributes)) {
45+
$attempt = $this->get_quiz_attempt_data();
46+
$attributes['attempt_started_at'] = date('c', $attempt->timestart);
47+
}
48+
49+
if (in_array('submission_at', $requestedattributes)) {
50+
$attempt = $this->get_quiz_attempt_data();
51+
if ($attempt->timefinish) {
52+
$attributes['submission_at'] = date('c', $attempt->timefinish);
53+
}
54+
}
55+
56+
if (in_array('lms_moodle_component_name', $requestedattributes)) {
57+
$attributes['lms_moodle_component_name'] = 'mod_quiz';
58+
}
59+
60+
if (in_array('lms_moodle_module_instance', $requestedattributes)) {
61+
$attempt = $this->get_quiz_attempt_data();
62+
$attributes['lms_moodle_module_instance'] = (int) $attempt->quiz;
63+
}
64+
65+
return $attributes;
66+
}
67+
68+
/**
69+
* Get user or group id this attempt belongs to.
70+
*
71+
* @return array<'user'|'group', int>
72+
*/
73+
public function get_user_or_group_id(): array {
74+
return ['user', $this->get_quiz_attempt_data()->userid];
75+
}
76+
77+
/**
78+
* Getter to lazily load quiz attempt data.
79+
*
80+
* @return \stdClass quiz_attempts db record
81+
*/
82+
private function get_quiz_attempt_data(): \stdClass {
83+
global $DB;
84+
85+
if ($this->quizattempt === null) {
86+
$usageid = $this->attempt->get_usage_id();
87+
$this->quizattempt = $DB->get_record('quiz_attempts', ['uniqueid' => $usageid], '*', MUST_EXIST);
88+
}
89+
return $this->quizattempt;
90+
}
91+
}

0 commit comments

Comments
 (0)