diff --git a/mod/quiz/classes/event/attempt_regraded.php b/mod/quiz/classes/event/attempt_regraded.php new file mode 100644 index 00000000000..dbbfd5fcad5 --- /dev/null +++ b/mod/quiz/classes/event/attempt_regraded.php @@ -0,0 +1,122 @@ +. + +/** + * The mod_quiz attempt regraded event. + * + * @package mod_quiz + * @copyright 2020 Russell Boyatt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace mod_quiz\event; + +defined('MOODLE_INTERNAL') || die(); + +/** + * The mod_quiz attempt regraded event class. + * + * @property-read array $other { + * Extra information about event. + * + * - int quizid: the id of the quiz. + * } + * + * @package mod_quiz + * @copyright 2020 Russell Boyatt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class attempt_regraded extends \core\event\base { + + /** + * Init method. + */ + protected function init() { + $this->data['objecttable'] = 'quiz_attempts'; + $this->data['crud'] = 'u'; + $this->data['edulevel'] = self::LEVEL_TEACHING; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventquizattemptregraded', 'mod_quiz'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return "The user with id '$this->userid' regraded quiz attempt with id '$this->objectid' by user " . + "with id '$this->relateduserid' for the quiz with course module id '$this->contextinstanceid'."; + } + + /** + * Returns relevant URL. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/quiz/review.php', array('attempt' => $this->objectid)); + } + + /** + * Custom validation. + * + * @throws \coding_exception + * @return void + */ + protected function validate_data() { + parent::validate_data(); + + if (!isset($this->relateduserid)) { + throw new \coding_exception('The \'relateduserid\' must be set.'); + } + + if (!isset($this->userid)) { + throw new \coding_exception('The \'userid\' must be set.'); + } + + if (!isset($this->other['quizid'])) { + throw new \coding_exception('The \'quizid\' value must be set in other.'); + } + } + + /** + * Get mapping to objects + * + * @return array Array of mappings + */ + public static function get_objectid_mapping() { + return array('db' => 'quiz_attempts', 'restore' => 'quiz_attempt'); + } + + /** + * Retrieve other mapping detail for the event. + * + * @return array Array of array mappings + */ + public static function get_other_mapping() { + $othermapped = array(); + $othermapped['quizid'] = array('db' => 'quiz', 'restore' => 'quiz'); + + return $othermapped; + } +} diff --git a/mod/quiz/lang/en/quiz.php b/mod/quiz/lang/en/quiz.php index 187e1896002..5ac9d24a663 100644 --- a/mod/quiz/lang/en/quiz.php +++ b/mod/quiz/lang/en/quiz.php @@ -342,6 +342,7 @@ $string['eventoverrideupdated'] = 'Quiz override updated'; $string['eventquestionmanuallygraded'] = 'Question manually graded'; $string['eventquizattemptabandoned'] = 'Quiz attempt abandoned'; $string['eventquizattempttimelimitexceeded'] = 'Quiz attempt time limit exceeded'; +$string['eventquizattemptregraded'] = 'Quiz attempt regraded'; $string['eventquizattemptstarted'] = 'Quiz attempt started'; $string['eventquizattemptsubmitted'] = 'Quiz attempt submitted'; $string['eventreportviewed'] = 'Quiz report viewed'; diff --git a/mod/quiz/report/overview/report.php b/mod/quiz/report/overview/report.php index 50e752b87df..0c97eca6d9d 100644 --- a/mod/quiz/report/overview/report.php +++ b/mod/quiz/report/overview/report.php @@ -357,6 +357,17 @@ class quiz_overview_report extends quiz_attempts_report { if (!$dryrun) { question_engine::save_questions_usage_by_activity($quba); + + $params = array( + 'objectid' => $attempt->id, + 'relateduserid' => $attempt->userid, + 'context' => $this->context, + 'other' => array( + 'quizid' => $attempt->quiz + ) + ); + $event = \mod_quiz\event\attempt_regraded::create($params); + $event->trigger(); } $transaction->allow_commit(); diff --git a/mod/quiz/tests/events_test.php b/mod/quiz/tests/events_test.php index 1771846bb79..74946552bf0 100644 --- a/mod/quiz/tests/events_test.php +++ b/mod/quiz/tests/events_test.php @@ -749,4 +749,40 @@ class mod_quiz_events_testcase extends advanced_testcase { $this->assertEventLegacyLogData($expected, $event); $this->assertEventContextNotUsed($event); } + + /** + * Test the attempt regraded event. + * + * There is no external API for regrading attempts, so the unit test will simply + * create and trigger the event and ensure the event data is returned as expected. + */ + public function test_attempt_regraded() { + $this->resetAfterTest(); + + $this->setAdminUser(); + $course = $this->getDataGenerator()->create_course(); + $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id)); + + $params = array( + 'objectid' => 1, + 'relateduserid' => 2, + 'courseid' => $course->id, + 'context' => context_module::instance($quiz->cmid), + 'other' => array( + 'quizid' => $quiz->id + ) + ); + $event = \mod_quiz\event\attempt_regraded::create($params); + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + $event->trigger(); + $events = $sink->get_events(); + $event = reset($events); + + // Check that the event data is valid. + $this->assertInstanceOf('\mod_quiz\event\attempt_regraded', $event); + $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context()); + $this->assertEventContextNotUsed($event); + } }