diff --git a/lang/en/question.php b/lang/en/question.php index b1f6385930c..63ef294cb82 100644 --- a/lang/en/question.php +++ b/lang/en/question.php @@ -137,6 +137,7 @@ $string['errorprocess'] = 'Error occurred during processing!'; $string['errorprocessingresponses'] = 'An error occurred while processing your responses ({$a}). Click continue to return to the page you were on and try again.'; $string['errorsavingcomment'] = 'Error saving the comment for question {$a->name} in the database.'; $string['errorupdatingattempt'] = 'Error updating attempt {$a->id} in the database.'; +$string['eventquestioncategorycreated'] = 'Question category created'; $string['exportcategory'] = 'Export category'; $string['exportcategory_help'] = 'This setting determines the category from which the exported questions will be taken. diff --git a/lib/classes/event/question_category_created.php b/lib/classes/event/question_category_created.php new file mode 100644 index 00000000000..a620065544c --- /dev/null +++ b/lib/classes/event/question_category_created.php @@ -0,0 +1,80 @@ +. + +/** + * Question category created event class. + * + * @package core + * @since Moodle 2.7 + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace core\event; + +defined('MOODLE_INTERNAL') || die(); + +class question_category_created extends base { + + /** + * Init method. + */ + protected function init() { + $this->data['objecttable'] = 'question_categories'; + $this->data['crud'] = 'c'; + $this->data['edulevel'] = self::LEVEL_TEACHING; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventquestioncategorycreated', 'question'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return 'A question category with the id of ' . $this->objectid . ' was created by a user with the id ' . $this->userid; + } + + /** + * Returns relevant URL. + * + * @return \moodle_url + */ + public function get_url() { + if ($this->contextlevel == CONTEXT_MODULE) { + return new \moodle_url('/question/category.php', array('cmid' => $this->contextinstanceid)); + } else { + return new \moodle_url('/question/category.php', array('courseid' => $this->courseid)); + } + } + + /** + * Return the legacy event log data. + * + * @return array + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'quiz', 'addcategory', 'view.php?id=' . $this->contextinstanceid, + $this->objectid, $this->contextinstanceid); + } +} diff --git a/mod/quiz/addrandom.php b/mod/quiz/addrandom.php index 96469587f44..4b12d214593 100644 --- a/mod/quiz/addrandom.php +++ b/mod/quiz/addrandom.php @@ -89,10 +89,8 @@ if ($data = $mform->get_data()) { list($parentid, $contextid) = explode(',', $data->parent); $categoryid = $qcobject->add_category($data->parent, $data->name, '', true); $includesubcategories = 0; - add_to_log($quiz->course, 'quiz', 'addcategory', - 'view.php?id=' . $cm->id, $categoryid, $cm->id); - $returnurl->param('cat', $categoryid . ',' . $contextid); + $returnurl->param('cat', $categoryid . ',' . $contextid); } else { throw new coding_exception( 'It seems a form was submitted without any button being pressed???'); diff --git a/mod/quiz/attempt.php b/mod/quiz/attempt.php index d7a5b1be91d..181c9bc80c4 100644 --- a/mod/quiz/attempt.php +++ b/mod/quiz/attempt.php @@ -95,9 +95,18 @@ if ($autosaveperiod) { } // Log this page view. -add_to_log($attemptobj->get_courseid(), 'quiz', 'continue attempt', - 'review.php?attempt=' . $attemptobj->get_attemptid(), - $attemptobj->get_quizid(), $attemptobj->get_cmid()); +$params = array( + 'objectid' => $attemptid, + 'relateduserid' => $attemptobj->get_userid(), + 'courseid' => $attemptobj->get_courseid(), + 'context' => context_module::instance($attemptobj->get_cmid()), + 'other' => array( + 'quizid' => $attemptobj->get_quizid() + ) +); +$event = \mod_quiz\event\attempt_viewed::create($params); +$event->add_record_snapshot('quiz_attempts', $attemptobj->get_attempt()); +$event->trigger(); // Get the list of questions needed by this page. $slots = $attemptobj->get_slots($page); diff --git a/mod/quiz/classes/event/attempt_deleted.php b/mod/quiz/classes/event/attempt_deleted.php new file mode 100644 index 00000000000..7b4f9d30819 --- /dev/null +++ b/mod/quiz/classes/event/attempt_deleted.php @@ -0,0 +1,95 @@ +. + +/** + * Attempt deleted event class. + * + * @package mod_quiz + * @since Moodle 2.7 + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace mod_quiz\event; + +defined('MOODLE_INTERNAL') || die(); + +class attempt_deleted extends \core\event\base { + + /** + * Init method. + */ + protected function init() { + $this->data['objecttable'] = 'quiz_attempts'; + $this->data['crud'] = 'd'; + $this->data['edulevel'] = self::LEVEL_TEACHING; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventattemptdeleted', 'mod_quiz'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return 'A quiz attempt with the id of ' . $this->objectid . ' belonging to the quiz with the id ' . $this->other['quizid'] . + ' for the user with the id ' . $this->relateduserid . ' was deleted by a user with the id ' . $this->userid; + } + + /** + * Returns relevant URL. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/quiz/report.php', array('id' => $this->contextinstanceid)); + } + + /** + * Return the legacy event log data. + * + * @return array + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'quiz', 'delete attempt', 'report.php?id=' . $this->contextinstanceid, + $this->objectid, $this->contextinstanceid); + } + + /** + * 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->other['quizid'])) { + throw new \coding_exception('The \'quizid\' must be set in other.'); + } + } +} diff --git a/mod/quiz/classes/event/attempt_preview_started.php b/mod/quiz/classes/event/attempt_preview_started.php new file mode 100644 index 00000000000..fc352a2f61f --- /dev/null +++ b/mod/quiz/classes/event/attempt_preview_started.php @@ -0,0 +1,101 @@ +. + +/** + * Attempt preview started event class. + * + * @property-read array $other { + * Extra information about event. + * + * - int quizid: the id of the quiz. + * } + * + * @package mod_quiz + * @since Moodle 2.7 + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace mod_quiz\event; + +defined('MOODLE_INTERNAL') || die(); + +class attempt_preview_started extends \core\event\base { + + /** + * Init method. + */ + protected function init() { + $this->data['objecttable'] = 'quiz_attempts'; + $this->data['crud'] = 'r'; + $this->data['edulevel'] = self::LEVEL_TEACHING; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventattemptpreviewstarted', 'mod_quiz'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return 'A quiz attempt with the id of ' . $this->objectid . ' belonging to the quiz with the id ' . $this->other['quizid'] . + ' was previewed by the user with the id ' . $this->relateduserid; + } + + /** + * Returns relevant URL. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/quiz/view.php', array('id' => $this->contextinstanceid)); + } + + /** + * Return the legacy event log data. + * + * @return array + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'quiz', 'preview', 'view.php?id=' . $this->contextinstanceid, + $this->other['quizid'], $this->contextinstanceid); + } + + /** + * 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->other['quizid'])) { + throw new \coding_exception('The \'quizid\' must be set in other.'); + } + } +} diff --git a/mod/quiz/classes/event/attempt_reviewed.php b/mod/quiz/classes/event/attempt_reviewed.php new file mode 100644 index 00000000000..dd46467ef9b --- /dev/null +++ b/mod/quiz/classes/event/attempt_reviewed.php @@ -0,0 +1,101 @@ +. + +/** + * Attempt reviewed event class. + * + * @property-read array $other { + * Extra information about event. + * + * - int quizid: the id of the quiz. + * } + * + * @package mod_quiz + * @since Moodle 2.7 + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace mod_quiz\event; + +defined('MOODLE_INTERNAL') || die(); + +class attempt_reviewed extends \core\event\base { + + /** + * Init method. + */ + protected function init() { + $this->data['objecttable'] = 'quiz_attempts'; + $this->data['crud'] = 'r'; + $this->data['edulevel'] = self::LEVEL_TEACHING; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventattemptreviewed', 'mod_quiz'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return 'A quiz attempt with the id of ' . $this->objectid . ' for the quiz with the id ' . $this->other['quizid'] . + ' belonging to a user with the id ' . $this->relateduserid . ' was reviewed by a user with the id ' . $this->userid; + } + + /** + * Returns relevant URL. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/quiz/review.php', array('attempt' => $this->objectid)); + } + + /** + * Return the legacy event log data. + * + * @return array + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'quiz', 'review', 'review.php?attempt=' . $this->objectid, + $this->other['quizid'], $this->contextinstanceid); + } + + /** + * 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->other['quizid'])) { + throw new \coding_exception('The \'quizid\' must be set in other.'); + } + } +} diff --git a/mod/quiz/classes/event/attempt_started.php b/mod/quiz/classes/event/attempt_started.php index 69ba87d1668..fa641c9ea90 100644 --- a/mod/quiz/classes/event/attempt_started.php +++ b/mod/quiz/classes/event/attempt_started.php @@ -100,6 +100,18 @@ class attempt_started extends \core\event\base { return $legacyeventdata; } + /** + * Return the legacy event log data. + * + * @return array + */ + protected function get_legacy_logdata() { + $attempt = $this->get_record_snapshot('quiz_attempts', $this->objectid); + + return array($this->courseid, 'quiz', 'attempt', 'review.php?attempt=' . $this->objectid, + $attempt->quiz, $this->contextinstanceid); + } + /** * Custom validation. * diff --git a/mod/quiz/classes/event/attempt_summary_viewed.php b/mod/quiz/classes/event/attempt_summary_viewed.php new file mode 100644 index 00000000000..2b110ad5fb3 --- /dev/null +++ b/mod/quiz/classes/event/attempt_summary_viewed.php @@ -0,0 +1,104 @@ +. + +/** + * Attempt summary viewed event. + * + * @property-read array $other { + * Extra information about event. + * + * - int quizid: the id of the quiz. + * } + * + * @package mod_quiz + * @since Moodle 2.7 + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_quiz\event; + +defined('MOODLE_INTERNAL') || die(); + +class attempt_summary_viewed extends \core\event\base { + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['objecttable'] = 'quiz_attempts'; + $this->data['crud'] = 'r'; + $this->data['edulevel'] = self::LEVEL_TEACHING; + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventattemptsummaryviewed', 'mod_quiz'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return 'The summary for the quiz attempt with the id of ' . $this->objectid . ' belonging to a user with the id ' . + $this->relateduserid . ' was viewed by a user with the id ' . $this->userid; + } + + /** + * Get URL related to the action. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/quiz/summary.php', array('attempt' => $this->objectid)); + } + + /** + * Return the legacy event log data. + * + * @return array + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'quiz', 'view summary', 'summary.php?attempt=' . $this->objectid, + $this->other['quizid'], $this->contextinstanceid); + } + + /** + * 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->other['quizid'])) { + throw new \coding_exception('The \'quizid\' must be set in other.'); + } + } +} diff --git a/mod/quiz/classes/event/attempt_viewed.php b/mod/quiz/classes/event/attempt_viewed.php new file mode 100644 index 00000000000..a9620ffbe78 --- /dev/null +++ b/mod/quiz/classes/event/attempt_viewed.php @@ -0,0 +1,101 @@ +. + +/** + * Attempt viewed event class. + * + * @property-read array $other { + * Extra information about event. + * + * - int quizid: the id of the quiz. + * } + * + * @package mod_quiz + * @since Moodle 2.7 + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace mod_quiz\event; + +defined('MOODLE_INTERNAL') || die(); + +class attempt_viewed extends \core\event\base { + + /** + * Init method. + */ + protected function init() { + $this->data['objecttable'] = 'quiz_attempts'; + $this->data['crud'] = 'r'; + $this->data['edulevel'] = self::LEVEL_PARTICIPATING; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventattemptviewed', 'mod_quiz'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return 'A quiz attempt with the id of ' . $this->objectid . ' belonging to the quiz with the id ' . $this->other['quizid'] . + ' was viewed by the user with the id ' . $this->relateduserid; + } + + /** + * Returns relevant URL. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/quiz/review.php', array('attempt' => $this->objectid)); + } + + /** + * Return the legacy event log data. + * + * @return array + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'quiz', 'continue attempt', 'review.php?attempt=' . $this->objectid, + $this->other['quizid'], $this->contextinstanceid); + } + + /** + * 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->other['quizid'])) { + throw new \coding_exception('The \'quizid\' must be set in other.'); + } + } +} diff --git a/mod/quiz/classes/event/course_module_instance_list_viewed.php b/mod/quiz/classes/event/course_module_instance_list_viewed.php new file mode 100644 index 00000000000..1218cff9b23 --- /dev/null +++ b/mod/quiz/classes/event/course_module_instance_list_viewed.php @@ -0,0 +1,32 @@ +. + +/** + * The instance list viewed event. + * + * @package mod_quiz + * @since Moodle 2.7 + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_quiz\event; + +defined('MOODLE_INTERNAL') || die(); + +class course_module_instance_list_viewed extends \core\event\course_module_instance_list_viewed { + // No code required here as the parent class handles it all. +} diff --git a/mod/quiz/classes/event/course_module_viewed.php b/mod/quiz/classes/event/course_module_viewed.php new file mode 100644 index 00000000000..4a1c3bbbaa7 --- /dev/null +++ b/mod/quiz/classes/event/course_module_viewed.php @@ -0,0 +1,42 @@ +. + +/** + * Course module viewed event. + * + * @package mod_quiz + * @since Moodle 2.7 + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_quiz\event; + +defined('MOODLE_INTERNAL') || die(); + +class course_module_viewed extends \core\event\course_module_viewed { + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['crud'] = 'r'; + $this->data['edulevel'] = self::LEVEL_PARTICIPATING; + $this->data['objecttable'] = 'quiz'; + } +} diff --git a/mod/quiz/classes/event/edit_page_viewed.php b/mod/quiz/classes/event/edit_page_viewed.php new file mode 100644 index 00000000000..45a9501c63d --- /dev/null +++ b/mod/quiz/classes/event/edit_page_viewed.php @@ -0,0 +1,96 @@ +. + +/** + * Edit page viewed event class. + * + * @property-read array $other { + * Extra information about event. + * + * - int quizid: the id of the quiz. + * } + * + * @package mod_quiz + * @since Moodle 2.7 + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace mod_quiz\event; + +defined('MOODLE_INTERNAL') || die(); + +class edit_page_viewed extends \core\event\base { + + /** + * Init method. + */ + protected function init() { + $this->data['crud'] = 'r'; + $this->data['edulevel'] = self::LEVEL_TEACHING; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventeditpageviewed', 'mod_quiz'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return 'The edit quiz page belonging to the quiz with the id ' . $this->other['quizid'] . ' was viewed by the user + with the id ' . $this->userid; + } + + /** + * Returns relevant URL. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/quiz/edit.php', array('cmid' => $this->contextinstanceid)); + } + + /** + * Return the legacy event log data. + * + * @return array + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'quiz', 'editquestions', 'view.php?id=' . $this->contextinstanceid, + $this->other['quizid'], $this->contextinstanceid); + } + + /** + * Custom validation. + * + * @throws \coding_exception + * @return void + */ + protected function validate_data() { + parent::validate_data(); + + if (!isset($this->other['quizid'])) { + throw new \coding_exception('The \'quizid\' must be set in other.'); + } + } +} diff --git a/mod/quiz/classes/event/group_override_created.php b/mod/quiz/classes/event/group_override_created.php new file mode 100644 index 00000000000..cac8c89e50c --- /dev/null +++ b/mod/quiz/classes/event/group_override_created.php @@ -0,0 +1,92 @@ +. + +/** + * Group override created event class. + * + * @property-read array $other { + * Extra information about event. + * + * - int quizid: the id of the quiz. + * - int groupid: the id of the group. + * } + * + * @package mod_quiz + * @since Moodle 2.7 + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace mod_quiz\event; + +defined('MOODLE_INTERNAL') || die(); + +class group_override_created extends \core\event\base { + + /** + * Init method. + */ + protected function init() { + $this->data['objecttable'] = 'quiz_overrides'; + $this->data['crud'] = 'c'; + $this->data['edulevel'] = self::LEVEL_TEACHING; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventoverridecreated', 'mod_quiz'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return 'An override with the id ' . $this->objectid . ' for the quiz with the id of ' . $this->other['quizid'] . + ' was created by the user with the id ' . $this->userid . ' for the group with the id ' . $this->other['groupid']; + } + + /** + * Returns relevant URL. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/quiz/overrideedit.php', array('id' => $this->objectid)); + } + + /** + * Custom validation. + * + * @throws \coding_exception + * @return void + */ + protected function validate_data() { + parent::validate_data(); + + if (!isset($this->other['quizid'])) { + throw new \coding_exception('The \'quizid\' must be set in other.'); + } + + if (!isset($this->other['groupid'])) { + throw new \coding_exception('The \'groupid\' must be set in other.'); + } + } +} diff --git a/mod/quiz/classes/event/group_override_deleted.php b/mod/quiz/classes/event/group_override_deleted.php new file mode 100644 index 00000000000..f1304bb6c64 --- /dev/null +++ b/mod/quiz/classes/event/group_override_deleted.php @@ -0,0 +1,102 @@ +. + +/** + * Group override deleted event class. + * + * @property-read array $other { + * Extra information about event. + * + * - int quizid: the id of the quiz. + * - int groupid: the id of the group. + * } + * + * @package mod_quiz + * @since Moodle 2.7 + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace mod_quiz\event; + +defined('MOODLE_INTERNAL') || die(); + +class group_override_deleted extends \core\event\base { + + /** + * Init method. + */ + protected function init() { + $this->data['objecttable'] = 'quiz_overrides'; + $this->data['crud'] = 'd'; + $this->data['edulevel'] = self::LEVEL_TEACHING; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventoverridedeleted', 'mod_quiz'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return 'An override with the id ' . $this->objectid . ' for the quiz with the id of ' . $this->other['quizid'] . + ' was deleted by the user with the id ' . $this->userid . ' for the group with the id ' . $this->other['groupid']; + } + + /** + * Returns relevant URL. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/quiz/overrides.php', array('cmid' => $this->contextinstanceid)); + } + + /** + * Return the legacy event log data. + * + * @return array + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'quiz', 'delete override', 'overrides.php?cmid=' . $this->contextinstanceid, + $this->other['quizid'], $this->contextinstanceid); + } + + /** + * Custom validation. + * + * @throws \coding_exception + * @return void + */ + protected function validate_data() { + parent::validate_data(); + + if (!isset($this->other['quizid'])) { + throw new \coding_exception('The \'quizid\' must be set in other.'); + } + + if (!isset($this->other['groupid'])) { + throw new \coding_exception('The \'groupid\' must be set in other.'); + } + } +} diff --git a/mod/quiz/classes/event/group_override_updated.php b/mod/quiz/classes/event/group_override_updated.php new file mode 100644 index 00000000000..24942c407e9 --- /dev/null +++ b/mod/quiz/classes/event/group_override_updated.php @@ -0,0 +1,102 @@ +. + +/** + * Group override updated event class. + * + * @property-read array $other { + * Extra information about event. + * + * - int quizid: the id of the quiz. + * - int groupid: the id of the group. + * } + * + * @package mod_quiz + * @since Moodle 2.7 + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace mod_quiz\event; + +defined('MOODLE_INTERNAL') || die(); + +class group_override_updated extends \core\event\base { + + /** + * Init method. + */ + protected function init() { + $this->data['objecttable'] = 'quiz_overrides'; + $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('eventoverrideupdated', 'mod_quiz'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return 'An override with the id ' . $this->objectid . ' for the quiz with the id of ' . $this->other['quizid'] . + ' was updated by the user with the id ' . $this->userid . ' for the group with the id ' . $this->other['groupid']; + } + + /** + * Returns relevant URL. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/quiz/overrideedit.php', array('id' => $this->objectid)); + } + + /** + * Return the legacy event log data. + * + * @return array + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'quiz', 'edit override', 'overrideedit.php?id=' . $this->objectid, $this->other['quizid'], + $this->contextinstanceid); + } + + /** + * Custom validation. + * + * @throws \coding_exception + * @return void + */ + protected function validate_data() { + parent::validate_data(); + + if (!isset($this->other['quizid'])) { + throw new \coding_exception('The \'quizid\' must be set in other.'); + } + + if (!isset($this->other['groupid'])) { + throw new \coding_exception('The \'groupid\' must be set in other.'); + } + } +} diff --git a/mod/quiz/classes/event/question_manually_graded.php b/mod/quiz/classes/event/question_manually_graded.php new file mode 100644 index 00000000000..d6444dc922d --- /dev/null +++ b/mod/quiz/classes/event/question_manually_graded.php @@ -0,0 +1,109 @@ +. + +/** + * Question manually graded event class. + * + * @property-read array $other { + * Extra information about event. + * + * - int quizid: the id of the quiz. + * - int attemptid: the id of the attempt. + * - int slot: the question number in the attempt. + * } + * + * @package core + * @since Moodle 2.7 + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace mod_quiz\event; + +defined('MOODLE_INTERNAL') || die(); + +class question_manually_graded extends \core\event\base { + + /** + * Init method. + */ + protected function init() { + $this->data['objecttable'] = 'question'; + $this->data['crud'] = 'c'; + $this->data['edulevel'] = self::LEVEL_TEACHING; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventquestionmanuallygraded', 'mod_quiz'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return 'A question with the id of ' . $this->objectid . ' was manually graded by a user with the id ' . $this->userid . + ' for the attempt with the id ' . $this->other['attemptid']; + } + + /** + * Returns relevant URL. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/quiz/comment.php', array('attempt' => $this->other['attemptid'], + 'slot' => $this->other['slot'])); + } + + /** + * Return the legacy event log data. + * + * @return array + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'quiz', 'manualgrade', 'comment.php?attempt=' . $this->other['attemptid'] . + '&slot=' . $this->other['slot'], $this->other['quizid'], $this->contextinstanceid); + } + + /** + * Custom validation. + * + * @throws \coding_exception + * @return void + */ + protected function validate_data() { + parent::validate_data(); + + if (!isset($this->other['quizid'])) { + throw new \coding_exception('The \'quizid\' must be set in other.'); + } + + if (!isset($this->other['attemptid'])) { + throw new \coding_exception('The \'attemptid\' must be set in other.'); + } + + if (!isset($this->other['slot'])) { + throw new \coding_exception('The \'slot\' must be set in other.'); + } + + } +} diff --git a/mod/quiz/classes/event/report_viewed.php b/mod/quiz/classes/event/report_viewed.php new file mode 100644 index 00000000000..da2d3012fa0 --- /dev/null +++ b/mod/quiz/classes/event/report_viewed.php @@ -0,0 +1,105 @@ +. + +/** + * Report viewed event. + * + * @property-read array $other { + * Extra information about event. + * + * - int quizid: the id of the quiz. + * - string reportname: the name of the report. + * } + * + * @package mod_quiz + * @since Moodle 2.7 + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_quiz\event; + +defined('MOODLE_INTERNAL') || die(); + +class report_viewed extends \core\event\base { + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['crud'] = 'r'; + $this->data['edulevel'] = self::LEVEL_TEACHING; + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventreportviewed', 'mod_quiz'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return 'User with id ' . $this->userid . ' viewed the report \'' . s($this->other['reportname']) . '\' for the quiz + with the id ' . $this->other['quizid']; + } + + /** + * Get URL related to the action. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/quiz/report.php', array('id' => $this->contextinstanceid, + 'mode' => $this->other['reportname'])); + } + + /** + * Return the legacy event log data. + * + * @return array + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'quiz', 'report', 'report.php?id=' . $this->contextinstanceid . '&mode=' . + $this->other['reportname'], $this->other['quizid'], $this->contextinstanceid); + } + + /** + * Custom validation. + * + * @throws \coding_exception + * @return void + */ + protected function validate_data() { + parent::validate_data(); + + if (!isset($this->other['quizid'])) { + throw new \coding_exception('The \'quizid\' must be set in other.'); + } + + if (!isset($this->other['reportname'])) { + throw new \coding_exception('The \'reportname\' must be set in other.'); + } + } +} diff --git a/mod/quiz/classes/event/user_override_created.php b/mod/quiz/classes/event/user_override_created.php new file mode 100644 index 00000000000..3a1eafb0431 --- /dev/null +++ b/mod/quiz/classes/event/user_override_created.php @@ -0,0 +1,91 @@ +. + +/** + * User override created event class. + * + * @property-read array $other { + * Extra information about event. + * + * - int quizid: the id of the quiz. + * } + * + * @package mod_quiz + * @since Moodle 2.7 + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace mod_quiz\event; + +defined('MOODLE_INTERNAL') || die(); + +class user_override_created extends \core\event\base { + + /** + * Init method. + */ + protected function init() { + $this->data['objecttable'] = 'quiz_overrides'; + $this->data['crud'] = 'c'; + $this->data['edulevel'] = self::LEVEL_TEACHING; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventoverridecreated', 'mod_quiz'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return 'An override with the id ' . $this->objectid . ' for the quiz with the id of ' . $this->other['quizid'] . + ' was created by the user with the id ' . $this->userid . ' for the user with the id ' . $this->relateduserid; + } + + /** + * Returns relevant URL. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/quiz/overrideedit.php', array('id' => $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->other['quizid'])) { + throw new \coding_exception('The \'quizid\' must be set in other.'); + } + } +} diff --git a/mod/quiz/classes/event/user_override_deleted.php b/mod/quiz/classes/event/user_override_deleted.php new file mode 100644 index 00000000000..b441593014a --- /dev/null +++ b/mod/quiz/classes/event/user_override_deleted.php @@ -0,0 +1,101 @@ +. + +/** + * User override deleted event class. + * + * @property-read array $other { + * Extra information about event. + * + * - int quizid: the id of the quiz. + * } + * + * @package mod_quiz + * @since Moodle 2.7 + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace mod_quiz\event; + +defined('MOODLE_INTERNAL') || die(); + +class user_override_deleted extends \core\event\base { + + /** + * Init method. + */ + protected function init() { + $this->data['objecttable'] = 'quiz_overrides'; + $this->data['crud'] = 'd'; + $this->data['edulevel'] = self::LEVEL_TEACHING; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventoverridedeleted', 'mod_quiz'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return 'An override with the id ' . $this->objectid . ' for the quiz with the id of ' . $this->other['quizid'] . + ' was deleted by the user with the id ' . $this->userid . ' for the user with the id ' . $this->relateduserid; + } + + /** + * Returns relevant URL. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/quiz/overrides.php', array('cmid' => $this->contextinstanceid)); + } + + /** + * Return the legacy event log data. + * + * @return array + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'quiz', 'delete override', 'overrides.php?cmid=' . $this->contextinstanceid, + $this->other['quizid'], $this->contextinstanceid); + } + + /** + * 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->other['quizid'])) { + throw new \coding_exception('The \'quizid\' must be set in other.'); + } + } +} diff --git a/mod/quiz/classes/event/user_override_updated.php b/mod/quiz/classes/event/user_override_updated.php new file mode 100644 index 00000000000..3c61d90d2a8 --- /dev/null +++ b/mod/quiz/classes/event/user_override_updated.php @@ -0,0 +1,101 @@ +. + +/** + * User override updated event class. + * + * @property-read array $other { + * Extra information about event. + * + * - int quizid: the id of the quiz. + * } + * + * @package mod_quiz + * @since Moodle 2.7 + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace mod_quiz\event; + +defined('MOODLE_INTERNAL') || die(); + +class user_override_updated extends \core\event\base { + + /** + * Init method. + */ + protected function init() { + $this->data['objecttable'] = 'quiz_overrides'; + $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('eventoverrideupdated', 'mod_quiz'); + } + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return 'An override with the id ' . $this->objectid . ' for the quiz with the id of ' . $this->other['quizid'] . + ' was updated by the user with the id ' . $this->userid . ' for the user with the id ' . $this->relateduserid; + } + + /** + * Returns relevant URL. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/quiz/overrideedit.php', array('id' => $this->objectid)); + } + + /** + * Return the legacy event log data. + * + * @return array + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'quiz', 'edit override', 'overrideedit.php?id=' . $this->objectid, $this->other['quizid'], + $this->contextinstanceid); + } + + /** + * 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->other['quizid'])) { + throw new \coding_exception('The \'quizid\' must be set in other.'); + } + } +} diff --git a/mod/quiz/comment.php b/mod/quiz/comment.php index 754b88dcee9..c1961ab2a8d 100644 --- a/mod/quiz/comment.php +++ b/mod/quiz/comment.php @@ -42,11 +42,6 @@ if (!$attemptobj->is_finished()) { require_login($attemptobj->get_course(), false, $attemptobj->get_cm()); $attemptobj->require_capability('mod/quiz:grade'); -// Log this action. -add_to_log($attemptobj->get_courseid(), 'quiz', 'manualgrade', 'comment.php?attempt=' . - $attemptobj->get_attemptid() . '&slot=' . $slot, - $attemptobj->get_quizid(), $attemptobj->get_cmid()); - // Print the page header. $PAGE->set_pagelayout('popup'); $PAGE->set_heading($attemptobj->get_course()->fullname); @@ -74,6 +69,21 @@ if (data_submitted() && confirm_sesskey()) { $transaction = $DB->start_delegated_transaction(); $attemptobj->process_submitted_actions(time()); $transaction->allow_commit(); + + // Log this action. + $params = array( + 'objectid' => $attemptobj->get_question_attempt($slot)->get_question()->id, + 'courseid' => $attemptobj->get_courseid(), + 'context' => context_module::instance($attemptobj->get_cmid()), + 'other' => array( + 'quizid' => $attemptobj->get_quizid(), + 'attemptid' => $attemptobj->get_attemptid(), + 'slot' => $slot + ) + ); + $event = \mod_quiz\event\question_manually_graded::create($params); + $event->trigger(); + echo $output->notification(get_string('changessaved'), 'notifysuccess'); close_window(2, true); die; diff --git a/mod/quiz/edit.php b/mod/quiz/edit.php index 82af005738f..9cbf9c97523 100644 --- a/mod/quiz/edit.php +++ b/mod/quiz/edit.php @@ -152,13 +152,20 @@ if (!$course) { $questionbank = new quiz_question_bank_view($contexts, $thispageurl, $course, $cm, $quiz); $questionbank->set_quiz_has_attempts($quizhasattempts); -// Log this visit. -add_to_log($cm->course, 'quiz', 'editquestions', - "view.php?id=$cm->id", "$quiz->id", $cm->id); - // You need mod/quiz:manage in addition to question capabilities to access this page. require_capability('mod/quiz:manage', $contexts->lowest()); +// Log this visit. +$params = array( + 'courseid' => $course->id, + 'context' => $contexts->lowest(), + 'other' => array( + 'quizid' => $quiz->id + ) +); +$event = \mod_quiz\event\edit_page_viewed::create($params); +$event->trigger(); + // Process commands ============================================================ // Get the list of question ids had their check-boxes ticked. diff --git a/mod/quiz/index.php b/mod/quiz/index.php index 5dd8d8e855f..f119782d81f 100644 --- a/mod/quiz/index.php +++ b/mod/quiz/index.php @@ -35,7 +35,11 @@ $coursecontext = context_course::instance($id); require_login($course); $PAGE->set_pagelayout('incourse'); -add_to_log($course->id, "quiz", "view all", "index.php?id=$course->id", ""); +$params = array( + 'context' => $coursecontext +); +$event = \mod_quiz\event\course_module_instance_list_viewed::create($params); +$event->trigger(); // Print the header. $strquizzes = get_string("modulenameplural", "quiz"); diff --git a/mod/quiz/lang/en/quiz.php b/mod/quiz/lang/en/quiz.php index 4b2c936ebb9..18cc1e6b96f 100644 --- a/mod/quiz/lang/en/quiz.php +++ b/mod/quiz/lang/en/quiz.php @@ -305,10 +305,21 @@ $string['errornotnumbers'] = 'Error - answers must be numeric'; $string['errorunexpectedevent'] = 'Unexpected event code {$a->event} found for question {$a->questionid} in attempt {$a->attemptid}.'; $string['essay'] = 'Essay'; $string['essayquestions'] = 'Questions'; +$string['eventattemptdeleted'] = 'Quiz attempt deleted'; +$string['eventattemptpreviewstarted'] = 'Quiz attempt preview started'; +$string['eventattemptreviewed'] = 'Quiz attempt reviewed'; +$string['eventattemptsummaryviewed'] = 'Quiz attempt summary viewed'; +$string['eventattemptviewed'] = 'Quiz attempt viewed'; +$string['eventeditpageviewed'] = 'Quiz edit page viewed'; +$string['eventoverridecreated'] = 'Quiz override created'; +$string['eventoverridedeleted'] = 'Quiz override deleted'; +$string['eventoverrideupdated'] = 'Quiz override updated'; +$string['eventquestionmanuallygraded'] = 'Question manually graded'; $string['eventquizattemptabandoned'] = 'Quiz attempt abandoned'; $string['eventquizattempttimelimitexceeded'] = 'Quiz attempt time limit exceeded'; $string['eventquizattemptstarted'] = 'Quiz attempt started'; $string['eventquizattemptsubmitted'] = 'Quiz attempt submitted'; +$string['eventreportviewed'] = 'Quiz report viewed'; $string['everynquestions'] = 'Every {$a} questions'; $string['everyquestion'] = 'Every question'; $string['everythingon'] = 'Everything on'; diff --git a/mod/quiz/lib.php b/mod/quiz/lib.php index f6090c0c28b..4e4276ceb5d 100644 --- a/mod/quiz/lib.php +++ b/mod/quiz/lib.php @@ -203,6 +203,28 @@ function quiz_delete_override($quiz, $overrideid) { } $DB->delete_records('quiz_overrides', array('id' => $overrideid)); + + // Set the common parameters for one of the events we will be triggering. + $params = array( + 'objectid' => $override->id, + 'context' => context_module::instance($quiz->cmid), + 'other' => array( + 'quizid' => $override->quiz + ) + ); + // Determine which override deleted event to fire. + if (!empty($override->userid)) { + $params['relateduserid'] = $override->userid; + $event = \mod_quiz\event\user_override_deleted::create($params); + } else { + $params['other']['groupid'] = $override->groupid; + $event = \mod_quiz\event\group_override_deleted::create($params); + } + + // Trigger the override deleted event. + $event->add_record_snapshot('quiz_overrides', $override); + $event->trigger(); + return true; } diff --git a/mod/quiz/locallib.php b/mod/quiz/locallib.php index f24f3fc4ea1..47eb0bc6f4e 100644 --- a/mod/quiz/locallib.php +++ b/mod/quiz/locallib.php @@ -289,14 +289,29 @@ function quiz_attempt_save_started($quizobj, $quba, $attempt) { question_engine::save_questions_usage_by_activity($quba); $attempt->uniqueid = $quba->get_id(); $attempt->id = $DB->insert_record('quiz_attempts', $attempt); - // Log the new attempt. + + // Params used by the events below. + $params = array( + 'objectid' => $attempt->id, + 'relateduserid' => $attempt->userid, + 'courseid' => $quizobj->get_courseid(), + 'context' => $quizobj->get_context() + ); + // Decide which event we are using. if ($attempt->preview) { - add_to_log($quizobj->get_courseid(), 'quiz', 'preview', 'view.php?id='.$quizobj->get_cmid(), - $quizobj->get_quizid(), $quizobj->get_cmid()); + $params['other'] = array( + 'quizid' => $quizobj->get_quizid() + ); + $event = \mod_quiz\event\attempt_preview_started::create($params); } else { - add_to_log($quizobj->get_courseid(), 'quiz', 'attempt', 'review.php?attempt='.$attempt->id, - $quizobj->get_quizid(), $quizobj->get_cmid()); + $event = \mod_quiz\event\attempt_started::create($params); + } + + // Trigger the event. + $event->add_record_snapshot('quiz', $quizobj->get_quiz()); + $event->trigger(); + return $attempt; } @@ -360,6 +375,19 @@ function quiz_delete_attempt($attempt, $quiz) { question_engine::delete_questions_usage_by_activity($attempt->uniqueid); $DB->delete_records('quiz_attempts', array('id' => $attempt->id)); + // Log the deletion of the attempt. + $params = array( + 'objectid' => $attempt->id, + 'relateduserid' => $attempt->userid, + 'context' => context_module::instance($quiz->cmid), + 'other' => array( + 'quizid' => $quiz->id + ) + ); + $event = \mod_quiz\event\attempt_deleted::create($params); + $event->add_record_snapshot('quiz_attempts', $attempt); + $event->trigger(); + // Search quiz_attempts for other instances by this user. // If none, then delete record for this quiz, this user from quiz_grades // else recalculate best grade. diff --git a/mod/quiz/overridedelete.php b/mod/quiz/overridedelete.php index 8d9144fc8ac..ec841aef784 100644 --- a/mod/quiz/overridedelete.php +++ b/mod/quiz/overridedelete.php @@ -63,9 +63,6 @@ if ($confirm) { quiz_delete_override($quiz, $override->id); - add_to_log($cm->course, 'quiz', 'delete override', - "overrides.php?cmid=$cm->id", $quiz->id, $cm->id); - redirect($cancelurl); } diff --git a/mod/quiz/overrideedit.php b/mod/quiz/overrideedit.php index 1648ab93bc2..8dc7fa2ed6b 100644 --- a/mod/quiz/overrideedit.php +++ b/mod/quiz/overrideedit.php @@ -155,25 +155,54 @@ if ($mform->is_cancelled()) { $fromform->{$key} = $oldoverride->{$key}; } } - // Delete the old override. - $DB->delete_records('quiz_overrides', array('id' => $oldoverride->id)); + quiz_delete_override($quiz, $oldoverride->id); } } + // Set the common parameters for one of the events we may be triggering. + $params = array( + 'context' => $context, + 'other' => array( + 'quizid' => $quiz->id + ) + ); if (!empty($override->id)) { $fromform->id = $override->id; $DB->update_record('quiz_overrides', $fromform); + + // Determine which override updated event to fire. + $params['objectid'] = $override->id; + if (!$groupmode) { + $params['relateduserid'] = $fromform->userid; + $event = \mod_quiz\event\user_override_updated::create($params); + } else { + $params['other']['groupid'] = $fromform->groupid; + $event = \mod_quiz\event\group_override_updated::create($params); + } + + // Trigger the override updated event. + $event->trigger(); } else { unset($fromform->id); $fromform->id = $DB->insert_record('quiz_overrides', $fromform); + + // Determine which override created event to fire. + $params['objectid'] = $fromform->id; + if (!$groupmode) { + $params['relateduserid'] = $fromform->userid; + $event = \mod_quiz\event\user_override_created::create($params); + } else { + $params['other']['groupid'] = $fromform->groupid; + $event = \mod_quiz\event\group_override_created::create($params); + } + + // Trigger the override created event. + $event->trigger(); } quiz_update_open_attempts(array('quizid'=>$quiz->id)); quiz_update_events($quiz, $fromform); - add_to_log($cm->course, 'quiz', 'edit override', - "overrideedit.php?id=$fromform->id", $quiz->id, $cm->id); - if (!empty($fromform->submitbutton)) { redirect($overridelisturl); } diff --git a/mod/quiz/processattempt.php b/mod/quiz/processattempt.php index ccefbab7fd5..edf6d8c617c 100644 --- a/mod/quiz/processattempt.php +++ b/mod/quiz/processattempt.php @@ -157,13 +157,6 @@ if (!$finishattempt) { } } -// Otherwise, we have been asked to finish attempt, so do that. - -// Log the end of this attempt. -add_to_log($attemptobj->get_courseid(), 'quiz', 'close attempt', - 'review.php?attempt=' . $attemptobj->get_attemptid(), - $attemptobj->get_quizid(), $attemptobj->get_cmid()); - // Update the quiz attempt record. try { if ($becomingabandoned) { diff --git a/mod/quiz/report.php b/mod/quiz/report.php index ddc8c52b30a..2be5173f549 100644 --- a/mod/quiz/report.php +++ b/mod/quiz/report.php @@ -82,9 +82,6 @@ if (!is_readable("report/$mode/report.php")) { print_error('reportnotfound', 'quiz', '', $mode); } -add_to_log($course->id, 'quiz', 'report', 'report.php?id=' . $cm->id . '&mode=' . $mode, - $quiz->id, $cm->id); - // Open the selected quiz report and display it. $file = $CFG->dirroot . '/mod/quiz/report/' . $mode . '/report.php'; if (is_readable($file)) { @@ -100,3 +97,16 @@ $report->display($quiz, $cm, $course); // Print footer. echo $OUTPUT->footer(); + +// Log that this report was viewed. +$params = array( + 'context' => $context, + 'other' => array( + 'quizid' => $quiz->id, + 'reportname' => $mode + ) +); +$event = \mod_quiz\event\report_viewed::create($params); +$event->add_record_snapshot('course', $course); +$event->add_record_snapshot('quiz', $quiz); +$event->trigger(); diff --git a/mod/quiz/report/attemptsreport.php b/mod/quiz/report/attemptsreport.php index 4ea24a9926c..2342d8507f2 100644 --- a/mod/quiz/report/attemptsreport.php +++ b/mod/quiz/report/attemptsreport.php @@ -317,8 +317,7 @@ abstract class quiz_attempts_report extends quiz_default_report { // Ensure the attempt belongs to a student included in the report. If not skip. continue; } - add_to_log($quiz->course, 'quiz', 'delete attempt', 'report.php?id=' . $cm->id, - $attemptid, $cm->id); + quiz_delete_attempt($attempt, $quiz); } } diff --git a/mod/quiz/review.php b/mod/quiz/review.php index 3af0bda7ae8..4c2deb7fc1f 100644 --- a/mod/quiz/review.php +++ b/mod/quiz/review.php @@ -85,10 +85,6 @@ if ($options->flags == question_display_options::EDITABLE && optional_param('sav redirect($attemptobj->review_url(null, $page, $showall)); } -// Log this review. -add_to_log($attemptobj->get_courseid(), 'quiz', 'review', 'review.php?attempt=' . - $attemptobj->get_attemptid(), $attemptobj->get_quizid(), $attemptobj->get_cmid()); - // Work out appropriate title and whether blocks should be shown. if ($attemptobj->is_preview_user() && $attemptobj->is_own_attempt()) { $strreviewtitle = get_string('reviewofpreview', 'quiz'); @@ -255,3 +251,17 @@ $regions = $PAGE->blocks->get_regions(); $PAGE->blocks->add_fake_block($navbc, reset($regions)); echo $output->review_page($attemptobj, $slots, $page, $showall, $lastpage, $options, $summarydata); + +// Trigger an event for this review. +$params = array( + 'objectid' => $attemptobj->get_attemptid(), + 'relateduserid' => $attemptobj->get_userid(), + 'courseid' => $attemptobj->get_courseid(), + 'context' => context_module::instance($attemptobj->get_cmid()), + 'other' => array( + 'quizid' => $attemptobj->get_quizid() + ) +); +$event = \mod_quiz\event\attempt_reviewed::create($params); +$event->add_record_snapshot('quiz_attempts', $attemptobj->get_attempt()); +$event->trigger(); diff --git a/mod/quiz/summary.php b/mod/quiz/summary.php index 106890a8411..b1ac720ff57 100644 --- a/mod/quiz/summary.php +++ b/mod/quiz/summary.php @@ -76,11 +76,6 @@ if ($attemptobj->is_finished()) { redirect($attemptobj->review_url()); } -// Log this page view. -add_to_log($attemptobj->get_courseid(), 'quiz', 'view summary', - 'summary.php?attempt=' . $attemptobj->get_attemptid(), - $attemptobj->get_quizid(), $attemptobj->get_cmid()); - // Arrange for the navigation to be displayed. if (empty($attemptobj->get_quiz()->showblocks)) { $PAGE->blocks->show_only_fake_blocks(); @@ -96,3 +91,17 @@ $PAGE->set_heading($attemptobj->get_course()->fullname); // Display the page. echo $output->summary_page($attemptobj, $displayoptions); + +// Log this page view. +$params = array( + 'objectid' => $attemptobj->get_attemptid(), + 'relateduserid' => $attemptobj->get_userid(), + 'courseid' => $attemptobj->get_courseid(), + 'context' => context_module::instance($attemptobj->get_cmid()), + 'other' => array( + 'quizid' => $attemptobj->get_quizid() + ) +); +$event = \mod_quiz\event\attempt_summary_viewed::create($params); +$event->add_record_snapshot('quiz_attempts', $attemptobj->get_attempt()); +$event->trigger(); diff --git a/mod/quiz/tests/events_test.php b/mod/quiz/tests/events_test.php index d7d34b3ac41..bad32a0205c 100644 --- a/mod/quiz/tests/events_test.php +++ b/mod/quiz/tests/events_test.php @@ -222,5 +222,498 @@ class mod_quiz_events_testcase extends advanced_testcase { $this->assertEquals('quiz_attempt_started', $event->get_legacy_eventname()); $this->assertEventLegacyData($legacydata, $event); $this->assertEventContextNotUsed($event); + + // Create another attempt. + $attempt = quiz_create_attempt($quizobj, 1, false, time(), false, 2); + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + quiz_attempt_save_started($quizobj, $quba, $attempt); + $events = $sink->get_events(); + $event = reset($events); + + // Check that the event data is valid. + $this->assertInstanceOf('\mod_quiz\event\attempt_started', $event); + $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context()); + $expected = array($quizobj->get_courseid(), 'quiz', 'attempt', 'review.php?attempt=' . $attempt->id, + $quizobj->get_quizid(), $quizobj->get_cmid()); + $this->assertEventLegacyLogData($expected, $event); + } + + /** + * Test the edit page viewed event. + * + * There is no external API for updating a quiz, so the unit test will simply + * create and trigger the event and ensure the event data is returned as expected. + */ + public function test_edit_page_viewed() { + $this->resetAfterTest(); + + $this->setAdminUser(); + $course = $this->getDataGenerator()->create_course(); + $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id)); + + $params = array( + 'courseid' => $course->id, + 'context' => context_module::instance($quiz->cmid), + 'other' => array( + 'quizid' => $quiz->id + ) + ); + $event = \mod_quiz\event\edit_page_viewed::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\edit_page_viewed', $event); + $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context()); + $expected = array($course->id, 'quiz', 'editquestions', 'view.php?id=' . $quiz->cmid, $quiz->id, $quiz->cmid); + $this->assertEventLegacyLogData($expected, $event); + $this->assertEventContextNotUsed($event); + } + + /** + * Test the attempt deleted event. + */ + public function test_attempt_deleted() { + list($quizobj, $quba, $attempt) = $this->prepare_quiz_data(); + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + quiz_delete_attempt($attempt, $quizobj->get_quiz()); + $events = $sink->get_events(); + $event = reset($events); + + // Check that the event data is valid. + $this->assertInstanceOf('\mod_quiz\event\attempt_deleted', $event); + $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context()); + $expected = array($quizobj->get_courseid(), 'quiz', 'delete attempt', 'report.php?id=' . $quizobj->get_cmid(), + $attempt->id, $quizobj->get_cmid()); + $this->assertEventLegacyLogData($expected, $event); + $this->assertEventContextNotUsed($event); + } + + /** + * Test the report viewed event. + * + * There is no external API for viewing reports, so the unit test will simply + * create and trigger the event and ensure the event data is returned as expected. + */ + public function test_report_viewed() { + $this->resetAfterTest(); + + $this->setAdminUser(); + $course = $this->getDataGenerator()->create_course(); + $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id)); + + $params = array( + 'context' => $context = context_module::instance($quiz->cmid), + 'other' => array( + 'quizid' => $quiz->id, + 'reportname' => 'overview' + ) + ); + $event = \mod_quiz\event\report_viewed::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\report_viewed', $event); + $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context()); + $expected = array($course->id, 'quiz', 'report', 'report.php?id=' . $quiz->cmid . '&mode=overview', + $quiz->id, $quiz->cmid); + $this->assertEventLegacyLogData($expected, $event); + $this->assertEventContextNotUsed($event); + } + + /** + * Test the attempt reviewed event. + * + * There is no external API for reviewing 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_reviewed() { + $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_reviewed::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_reviewed', $event); + $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context()); + $expected = array($course->id, 'quiz', 'review', 'review.php?attempt=1', $quiz->id, $quiz->cmid); + $this->assertEventLegacyLogData($expected, $event); + $this->assertEventContextNotUsed($event); + } + + /** + * Test the attempt summary viewed event. + * + * There is no external API for viewing the attempt summary, so the unit test will simply + * create and trigger the event and ensure the event data is returned as expected. + */ + public function test_attempt_summary_viewed() { + $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_summary_viewed::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_summary_viewed', $event); + $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context()); + $expected = array($course->id, 'quiz', 'view summary', 'summary.php?attempt=1', $quiz->id, $quiz->cmid); + $this->assertEventLegacyLogData($expected, $event); + $this->assertEventContextNotUsed($event); + } + + /** + * Test the user override created event. + * + * There is no external API for creating a user override, so the unit test will simply + * create and trigger the event and ensure the event data is returned as expected. + */ + public function test_user_override_created() { + $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, + 'context' => context_module::instance($quiz->cmid), + 'other' => array( + 'quizid' => $quiz->id + ) + ); + $event = \mod_quiz\event\user_override_created::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\user_override_created', $event); + $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context()); + $this->assertEventContextNotUsed($event); + } + + /** + * Test the group override created event. + * + * There is no external API for creating a group override, so the unit test will simply + * create and trigger the event and ensure the event data is returned as expected. + */ + public function test_group_override_created() { + $this->resetAfterTest(); + + $this->setAdminUser(); + $course = $this->getDataGenerator()->create_course(); + $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id)); + + $params = array( + 'objectid' => 1, + 'context' => context_module::instance($quiz->cmid), + 'other' => array( + 'quizid' => $quiz->id, + 'groupid' => 2 + ) + ); + $event = \mod_quiz\event\group_override_created::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\group_override_created', $event); + $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context()); + $this->assertEventContextNotUsed($event); + } + + /** + * Test the user override updated event. + * + * There is no external API for updating a user override, so the unit test will simply + * create and trigger the event and ensure the event data is returned as expected. + */ + public function test_user_override_updated() { + $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, + 'context' => context_module::instance($quiz->cmid), + 'other' => array( + 'quizid' => $quiz->id + ) + ); + $event = \mod_quiz\event\user_override_updated::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\user_override_updated', $event); + $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context()); + $expected = array($course->id, 'quiz', 'edit override', 'overrideedit.php?id=1', $quiz->id, $quiz->cmid); + $this->assertEventLegacyLogData($expected, $event); + $this->assertEventContextNotUsed($event); + } + + /** + * Test the group override updated event. + * + * There is no external API for updating a group override, so the unit test will simply + * create and trigger the event and ensure the event data is returned as expected. + */ + public function test_group_override_updated() { + $this->resetAfterTest(); + + $this->setAdminUser(); + $course = $this->getDataGenerator()->create_course(); + $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id)); + + $params = array( + 'objectid' => 1, + 'context' => context_module::instance($quiz->cmid), + 'other' => array( + 'quizid' => $quiz->id, + 'groupid' => 2 + ) + ); + $event = \mod_quiz\event\group_override_updated::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\group_override_updated', $event); + $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context()); + $expected = array($course->id, 'quiz', 'edit override', 'overrideedit.php?id=1', $quiz->id, $quiz->cmid); + $this->assertEventLegacyLogData($expected, $event); + $this->assertEventContextNotUsed($event); + } + + /** + * Test the user override deleted event. + */ + public function test_user_override_deleted() { + global $DB; + + $this->resetAfterTest(); + + $this->setAdminUser(); + $course = $this->getDataGenerator()->create_course(); + $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id)); + + // Create an override. + $override = new stdClass(); + $override->quiz = $quiz->id; + $override->userid = 2; + $override->id = $DB->insert_record('quiz_overrides', $override); + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + quiz_delete_override($quiz, $override->id); + $events = $sink->get_events(); + $event = reset($events); + + // Check that the event data is valid. + $this->assertInstanceOf('\mod_quiz\event\user_override_deleted', $event); + $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context()); + $expected = array($course->id, 'quiz', 'delete override', 'overrides.php?cmid=' . $quiz->cmid, $quiz->id, $quiz->cmid); + $this->assertEventLegacyLogData($expected, $event); + $this->assertEventContextNotUsed($event); + } + + /** + * Test the group override deleted event. + */ + public function test_group_override_deleted() { + global $DB; + + $this->resetAfterTest(); + + $this->setAdminUser(); + $course = $this->getDataGenerator()->create_course(); + $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id)); + + // Create an override. + $override = new stdClass(); + $override->quiz = $quiz->id; + $override->groupid = 2; + $override->id = $DB->insert_record('quiz_overrides', $override); + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + quiz_delete_override($quiz, $override->id); + $events = $sink->get_events(); + $event = reset($events); + + // Check that the event data is valid. + $this->assertInstanceOf('\mod_quiz\event\group_override_deleted', $event); + $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context()); + $expected = array($course->id, 'quiz', 'delete override', 'overrides.php?cmid=' . $quiz->cmid, $quiz->id, $quiz->cmid); + $this->assertEventLegacyLogData($expected, $event); + $this->assertEventContextNotUsed($event); + } + + /** + * Test the attempt viewed event. + * + * There is no external API for continuing an attempt, so the unit test will simply + * create and trigger the event and ensure the event data is returned as expected. + */ + public function test_attempt_viewed() { + $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_viewed::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_viewed', $event); + $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context()); + $expected = array($course->id, 'quiz', 'continue attempt', 'review.php?attempt=1', $quiz->id, $quiz->cmid); + $this->assertEventLegacyLogData($expected, $event); + $this->assertEventContextNotUsed($event); + } + + /** + * Test the attempt previewed event. + */ + public function test_attempt_preview_started() { + list($quizobj, $quba, $attempt) = $this->prepare_quiz_data(); + + // We want to preview this attempt. + $attempt = quiz_create_attempt($quizobj, 1, false, time(), false, 2); + $attempt->preview = 1; + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + quiz_attempt_save_started($quizobj, $quba, $attempt); + $events = $sink->get_events(); + $event = reset($events); + + // Check that the event data is valid. + $this->assertInstanceOf('\mod_quiz\event\attempt_preview_started', $event); + $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context()); + $expected = array($quizobj->get_courseid(), 'quiz', 'preview', 'view.php?id=' . $quizobj->get_cmid(), + $quizobj->get_quizid(), $quizobj->get_cmid()); + $this->assertEventLegacyLogData($expected, $event); + $this->assertEventContextNotUsed($event); + } + + /** + * Test the question manually graded event. + * + * There is no external API for manually grading a question, so the unit test will simply + * create and trigger the event and ensure the event data is returned as expected. + */ + public function test_question_manually_graded() { + list($quizobj, $quba, $attempt) = $this->prepare_quiz_data(); + + $params = array( + 'objectid' => 1, + 'courseid' => $quizobj->get_courseid(), + 'context' => context_module::instance($quizobj->get_cmid()), + 'other' => array( + 'quizid' => $quizobj->get_quizid(), + 'attemptid' => 2, + 'slot' => 3 + ) + ); + $event = \mod_quiz\event\question_manually_graded::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\question_manually_graded', $event); + $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context()); + $expected = array($quizobj->get_courseid(), 'quiz', 'manualgrade', 'comment.php?attempt=2&slot=3', + $quizobj->get_quizid(), $quizobj->get_cmid()); + $this->assertEventLegacyLogData($expected, $event); + $this->assertEventContextNotUsed($event); } } diff --git a/mod/quiz/view.php b/mod/quiz/view.php index fbdb24a4824..a99f8254eff 100644 --- a/mod/quiz/view.php +++ b/mod/quiz/view.php @@ -70,7 +70,13 @@ $accessmanager = new quiz_access_manager($quizobj, $timenow, $quiz = $quizobj->get_quiz(); // Log this request. -add_to_log($course->id, 'quiz', 'view', 'view.php?id=' . $cm->id, $quiz->id, $cm->id); +$params = array( + 'objectid' => $quiz->id, + 'context' => $context +); +$event = \mod_quiz\event\course_module_viewed::create($params); +$event->add_record_snapshot('quiz', $quiz); +$event->trigger(); $completion = new completion_info($course); $completion->set_module_viewed($cm); diff --git a/question/category_class.php b/question/category_class.php index 39740fde6e7..cd331b828c0 100644 --- a/question/category_class.php +++ b/question/category_class.php @@ -404,6 +404,15 @@ class question_category_object { $cat->sortorder = 999; $cat->stamp = make_unique_id_code(); $categoryid = $DB->insert_record("question_categories", $cat); + + // Log the creation of this category. + $params = array( + 'objectid' => $categoryid, + 'contextid' => $contextid + ); + $event = \core\event\question_category_created::create($params); + $event->trigger(); + if ($return) { return $categoryid; } else { diff --git a/question/tests/events_test.php b/question/tests/events_test.php new file mode 100644 index 00000000000..357422e4e15 --- /dev/null +++ b/question/tests/events_test.php @@ -0,0 +1,76 @@ +. + +/** + * Events tests. + * + * @package core_question + * @copyright 2014 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; + +require_once($CFG->dirroot . '/question/editlib.php'); +require_once($CFG->dirroot . '/question/category_class.php'); + +class core_question_events_testcase extends advanced_testcase { + + /** + * Tests set up. + */ + public function setUp() { + $this->resetAfterTest(); + } + + /** + * Test the question category created event. + */ + public function test_question_category_created() { + $this->setAdminUser(); + $course = $this->getDataGenerator()->create_course(); + $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id)); + + $contexts = new question_edit_contexts(context_module::instance($quiz->cmid)); + + $defaultcategoryobj = question_make_default_categories(array($contexts->lowest())); + $defaultcategory = $defaultcategoryobj->id . ',' . $defaultcategoryobj->contextid; + + $qcobject = new question_category_object( + 1, + new moodle_url('/mod/quiz/edit.php', array('cmid' => $quiz->cmid)), + $contexts->having_one_edit_tab_cap('categories'), + $defaultcategoryobj->id, + $defaultcategory, + null, + $contexts->having_cap('moodle/question:add')); + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + $categoryid = $qcobject->add_category($defaultcategory, 'newcategory', '', true); + $events = $sink->get_events(); + $event = reset($events); + + // Check that the event data is valid. + $this->assertInstanceOf('\core\event\question_category_created', $event); + $this->assertEquals(context_module::instance($quiz->cmid), $event->get_context()); + $expected = array($course->id, 'quiz', 'addcategory', 'view.php?id=' . $quiz->cmid , $categoryid, $quiz->cmid); + $this->assertEventLegacyLogData($expected, $event); + $this->assertEventContextNotUsed($event); + } +}