diff --git a/mod/lesson/classes/event/course_module_instance_list_viewed.php b/mod/lesson/classes/event/course_module_instance_list_viewed.php new file mode 100644 index 00000000000..50a89ddb843 --- /dev/null +++ b/mod/lesson/classes/event/course_module_instance_list_viewed.php @@ -0,0 +1,31 @@ +. + +/** + * Event for when all lesson instances for a course are viewed. + * + * @package mod_lesson + * @copyright 2013 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_lesson\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/lesson/classes/event/course_module_viewed.php b/mod/lesson/classes/event/course_module_viewed.php new file mode 100644 index 00000000000..36255331827 --- /dev/null +++ b/mod/lesson/classes/event/course_module_viewed.php @@ -0,0 +1,39 @@ +. + +/** + * Course module viewed event. + * + * @package mod_lesson + * @copyright 2013 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_lesson\event; + +defined('MOODLE_INTERNAL') || die(); + +class course_module_viewed extends \core\event\course_module_viewed { + + /** + * Set basic properties for the event. + */ + protected function init() { + $this->data['objecttable'] = 'lesson'; + $this->data['crud'] = 'r'; + $this->data['level'] = self::LEVEL_PARTICIPATING; + } +} diff --git a/mod/lesson/classes/event/essay_attempt_viewed.php b/mod/lesson/classes/event/essay_attempt_viewed.php new file mode 100644 index 00000000000..7e066c79b5a --- /dev/null +++ b/mod/lesson/classes/event/essay_attempt_viewed.php @@ -0,0 +1,78 @@ +. + +/** + * Event to be triggered when the an essay attempt is viewed + * + * @package mod_lesson + * @copyright 2013 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later. + */ + +namespace mod_lesson\event; + +defined('MOODLE_INTERNAL') || die(); + +class essay_attempt_viewed extends \core\event\base { + + /** + * Set basic properties for the event. + */ + protected function init() { + $this->data['objecttable'] = 'lesson_attempts'; + $this->data['crud'] = 'r'; + $this->data['level'] = self::LEVEL_TEACHING; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventessayattemptviewed', 'mod_lesson'); + } + + /** + * Get URL related to the action. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/lesson/essay.php', array('id' => $this->context->instanceid, + 'mode' => 'grade', 'attemptid' => $this->objectid)); + } + + /** + * Returns non-localised event description with id's for admin use only. + * + * @return string + */ + public function get_description() { + return 'The essay grade for the user with the id ' . $this->relateduserid . ' for the attempt with the id ' . + $this->objectid . ' was viewed by the user with the id ' . $this->userid; + } + + /** + * Replace add_to_log() statement. + * + * @return array of parameters to be passed to legacy add_to_log() function. + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'lesson', 'view grade', 'essay.php?id=' . $this->context->instanceid . '&mode=grade&attemptid=' + . $this->objectid, get_string('manualgrading', 'lesson'), $this->context->instanceid); + } +} diff --git a/mod/lesson/classes/event/highscore_added.php b/mod/lesson/classes/event/highscore_added.php new file mode 100644 index 00000000000..b2204dbe191 --- /dev/null +++ b/mod/lesson/classes/event/highscore_added.php @@ -0,0 +1,81 @@ +. + +/** + * Event to be triggered when a highscore is added. + * + * @package mod_lesson + * @copyright 2013 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later. + */ + +namespace mod_lesson\event; + +defined('MOODLE_INTERNAL') || die(); + +class highscore_added extends \core\event\base { + + /** + * Set basic properties for the event. + */ + protected function init() { + $this->data['objecttable'] = 'lesson_high_scores'; + $this->data['crud'] = 'c'; + $this->data['level'] = self::LEVEL_PARTICIPATING; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventhighscoreadded', 'mod_lesson'); + } + + /** + * Get URL related to the action. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/lesson/highscores.php', array('id' => $this->context->instanceid)); + } + + /** + * Returns non-localised event description with id's for admin use only. + * + * @return string + */ + public function get_description() { + $highscore = $this->get_record_snapshot('lesson_high_scores', $this->objectid); + + return 'A new highscore was added to the lesson with the id ' . $highscore->lessonid . + ' for user with the id ' . $this->userid; + } + + /** + * Replace add_to_log() statement. + * + * @return array of parameters to be passed to legacy add_to_log() function. + */ + protected function get_legacy_logdata() { + $highscore = $this->get_record_snapshot('lesson_high_scores', $this->objectid); + + return array($this->courseid, 'lesson', 'update highscores', 'highscores.php?id=' . $this->context->instanceid, + $highscore->nickname, $this->context->instanceid); + } +} diff --git a/mod/lesson/classes/event/highscores_viewed.php b/mod/lesson/classes/event/highscores_viewed.php new file mode 100644 index 00000000000..549e451d361 --- /dev/null +++ b/mod/lesson/classes/event/highscores_viewed.php @@ -0,0 +1,78 @@ +. + +/** + * Event to be triggered when the highscores are viewed. + * + * @package mod_lesson + * @copyright 2013 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later. + */ + +namespace mod_lesson\event; + +defined('MOODLE_INTERNAL') || die(); + +class highscores_viewed extends \core\event\base { + + /** + * Set basic properties for the event. + */ + protected function init() { + $this->data['objecttable'] = 'lesson'; + $this->data['crud'] = 'r'; + $this->data['level'] = self::LEVEL_PARTICIPATING; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventhighscoresviewed', 'mod_lesson'); + } + + /** + * Get URL related to the action. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/lesson/highscores.php', array('id' => $this->context->instanceid)); + } + + /** + * Returns non-localised event description with id's for admin use only. + * + * @return string + */ + public function get_description() { + return 'The highscores for lesson ' . $this->objectid . ' were viewed by ' . $this->userid; + } + + /** + * Replace add_to_log() statement. + * + * @return array of parameters to be passed to legacy add_to_log() function. + */ + protected function get_legacy_logdata() { + $lesson = $this->get_record_snapshot('lesson', $this->objectid); + + return array($this->courseid, 'lesson', 'view highscores', 'highscores.php?id=' . $this->context->instanceid, + $lesson->name, $this->context->instanceid); + } +} diff --git a/mod/lesson/classes/event/lesson_ended.php b/mod/lesson/classes/event/lesson_ended.php new file mode 100644 index 00000000000..76963d284f9 --- /dev/null +++ b/mod/lesson/classes/event/lesson_ended.php @@ -0,0 +1,76 @@ +. + +/** + * Event to be triggered when a lesson is ended. + * + * @package mod_lesson + * @copyright 2013 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later. + */ + +namespace mod_lesson\event; + +defined('MOODLE_INTERNAL') || die(); + +class lesson_ended extends \core\event\base { + + /** + * Set basic properties for the event. + */ + protected function init() { + $this->data['objecttable'] = 'lesson'; + $this->data['crud'] = 'r'; + $this->data['level'] = self::LEVEL_PARTICIPATING; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventlessonended', 'mod_lesson'); + } + + /** + * Get URL related to the action. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/lesson/view.php', array('id' => $this->context->instanceid)); + } + + /** + * Returns non-localised event description with id's for admin use only. + * + * @return string + */ + public function get_description() { + return 'The lesson ' . $this->objectid . ' was ended by the user ' . $this->userid; + } + + /** + * Replace add_to_log() statement. + * + * @return array of parameters to be passed to legacy add_to_log() function. + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'lesson', 'end', 'view.php?id=' . $this->context->instanceid, $this->objectid, + $this->context->instanceid); + } +} diff --git a/mod/lesson/classes/event/lesson_started.php b/mod/lesson/classes/event/lesson_started.php new file mode 100644 index 00000000000..de377275feb --- /dev/null +++ b/mod/lesson/classes/event/lesson_started.php @@ -0,0 +1,76 @@ +. + +/** + * Event to be triggered when a lesson is started. + * + * @package mod_lesson + * @copyright 2013 Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later. + */ + +namespace mod_lesson\event; + +defined('MOODLE_INTERNAL') || die(); + +class lesson_started extends \core\event\base { + + /** + * Set basic properties for the event. + */ + protected function init() { + $this->data['objecttable'] = 'lesson'; + $this->data['crud'] = 'r'; + $this->data['level'] = self::LEVEL_PARTICIPATING; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('eventlessonstarted', 'mod_lesson'); + } + + /** + * Get URL related to the action. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/lesson/view.php', array('id' => $this->context->instanceid)); + } + + /** + * Returns non-localised event description with id's for admin use only. + * + * @return string + */ + public function get_description() { + return 'The lesson ' . $this->objectid . ' was started by the user ' . $this->userid; + } + + /** + * Replace add_to_log() statement. + * + * @return array of parameters to be passed to legacy add_to_log() function. + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'lesson', 'start', 'view.php?id=' . $this->context->instanceid, + $this->objectid, $this->context->instanceid); + } +} diff --git a/mod/lesson/essay.php b/mod/lesson/essay.php index c824a63ac64..123a166bc34 100644 --- a/mod/lesson/essay.php +++ b/mod/lesson/essay.php @@ -243,8 +243,6 @@ switch ($mode) { $essayinfo->sent = 1; $attempt->useranswer = serialize($essayinfo); $DB->update_record('lesson_attempts', $attempt); - // Log it - add_to_log($course->id, 'lesson', 'update email essay grade', "essay.php?id=$cm->id", format_string($pages[$attempt->pageid]->title,true).': '.fullname($users[$attempt->userid]), $cm->id); } } $lesson->add_message(get_string('emailsuccess', 'lesson'), 'notifysuccess'); @@ -299,8 +297,6 @@ switch ($mode) { } break; } -// Log it -add_to_log($course->id, 'lesson', 'view grade', "essay.php?id=$cm->id", get_string('manualgrading', 'lesson'), $cm->id); $lessonoutput = $PAGE->get_renderer('mod_lesson'); echo $lessonoutput->header($lesson, $cm, 'essay', false, null, get_string('manualgrading', 'lesson')); @@ -384,6 +380,16 @@ switch ($mode) { echo html_writer::table($table); break; case 'grade': + // Trigger the essay grade viewed event. + $event = \mod_lesson\event\essay_attempt_viewed::create(array( + 'objectid' => $attempt->id, + 'relateduserid' => $attempt->userid, + 'context' => $context, + 'courseid' => $course->id, + )); + $event->add_record_snapshot('lesson_attempts', $attempt); + $event->trigger(); + // Grading form // Expects the following to be set: $attemptid, $answer, $user, $page, $attempt $essayinfo = unserialize($attempt->useranswer); diff --git a/mod/lesson/highscores.php b/mod/lesson/highscores.php index c75dbbff47f..0493cd771fc 100644 --- a/mod/lesson/highscores.php +++ b/mod/lesson/highscores.php @@ -143,10 +143,15 @@ switch ($mode) { $newhighscore->gradeid = $newgrade->id; $newhighscore->nickname = $name; - $DB->insert_record('lesson_high_scores', $newhighscore); + $newhighscore->id = $DB->insert_record('lesson_high_scores', $newhighscore); - // Log it - add_to_log($course->id, 'lesson', 'update highscores', "highscores.php?id=$cm->id", $name, $cm->id); + // Trigger highscore updated event. + $event = \mod_lesson\event\highscore_added::create(array( + 'objectid' => $newhighscore->id, + 'context' => $context, + 'courseid' => $course->id, + )); + $event->trigger(); $lesson->add_message(get_string('postsuccess', 'lesson'), 'notifysuccess'); redirect("$CFG->wwwroot/mod/lesson/highscores.php?id=$cm->id&link=1"); @@ -156,8 +161,13 @@ switch ($mode) { break; } -// Log it -add_to_log($course->id, 'lesson', 'view highscores', "highscores.php?id=$cm->id", $lesson->name, $cm->id); +// Trigger highscore viewed event. +$event = \mod_lesson\event\highscores_viewed::create(array( + 'objectid' => $lesson->properties()->id, + 'context' => $context, + 'courseid' => $course->id +)); +$event->trigger(); $lessonoutput = $PAGE->get_renderer('mod_lesson'); echo $lessonoutput->header($lesson, $cm, 'highscores', false, null, get_string('viewhighscores', 'lesson')); diff --git a/mod/lesson/index.php b/mod/lesson/index.php index 1f95c538829..ad13f61bed4 100644 --- a/mod/lesson/index.php +++ b/mod/lesson/index.php @@ -39,8 +39,12 @@ if (!$course = $DB->get_record("course", array("id" => $id))) { require_login($course); $PAGE->set_pagelayout('incourse'); -add_to_log($course->id, "lesson", "view all", "index.php?id=$course->id", ""); - +// Trigger instances list viewed event. +$params = array( + 'context' => context_course::instance($course->id) +); +$event = \mod_lesson\event\course_module_instance_list_viewed::create($params); +$event->trigger(); /// Get all required strings diff --git a/mod/lesson/lang/en/lesson.php b/mod/lesson/lang/en/lesson.php index 6dc34e72a65..a0ff52d0edf 100644 --- a/mod/lesson/lang/en/lesson.php +++ b/mod/lesson/lang/en/lesson.php @@ -169,6 +169,11 @@ $string['essayemailmessage2'] = '

Essay prompt:

{$a->question}properties()->id, $this->properties()->course, + false, MUST_EXIST); + + // Trigger lesson started event. + $event = \mod_lesson\event\lesson_started::create(array( + 'objectid' => $this->properties()->id, + 'context' => context_module::instance($cm->id), + 'courseid' => $this->properties()->course + )); + $event->trigger(); + $USER->startlesson[$this->properties->id] = true; $startlesson = new stdClass; $startlesson->lessonid = $this->properties->id; @@ -1243,6 +1255,18 @@ class lesson extends lesson_base { public function stop_timer() { global $USER, $DB; unset($USER->startlesson[$this->properties->id]); + + $cm = get_coursemodule_from_instance('lesson', $this->properties()->id, $this->properties()->course, + false, MUST_EXIST); + + // Trigger lesson ended event. + $event = \mod_lesson\event\lesson_ended::create(array( + 'objectid' => $this->properties()->id, + 'context' => context_module::instance($cm->id), + 'courseid' => $this->properties()->course + )); + $event->trigger(); + return $this->update_timer(false, false); } diff --git a/mod/lesson/tests/events_test.php b/mod/lesson/tests/events_test.php new file mode 100644 index 00000000000..55ff9217db5 --- /dev/null +++ b/mod/lesson/tests/events_test.php @@ -0,0 +1,197 @@ +. + +/** + * Events tests. + * + * @package mod_lesson + * @category test + * @copyright 2013 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.'/mod/lesson/locallib.php'); + +class mod_lesson_events_testcase extends advanced_testcase { + + /** @var stdClass the course used for testing */ + private $course; + + /** @var lesson the lesson used for testing */ + private $lesson; + + /** + * Test set up. + * + * This is executed before running any test in this file. + */ + public function setUp() { + $this->resetAfterTest(); + + $this->setAdminUser(); + $this->course = $this->getDataGenerator()->create_course(); + $lesson = $this->getDataGenerator()->create_module('lesson', array('course' => $this->course->id)); + + // Convert to a lesson object. + $this->lesson = new lesson($lesson); + } + + /** + * Test the essay attempt viewed event. + * + * There is no external API for viewing an essay attempt, so the unit test will simply + * create and trigger the event and ensure the legacy log data is returned as expected. + */ + public function test_essay_attempt_viewed() { + // Create a essays list viewed event + $event = \mod_lesson\event\essay_attempt_viewed::create(array( + 'objectid' => $this->lesson->id, + 'relateduserid' => 3, + 'context' => context_module::instance($this->lesson->properties()->cmid), + 'courseid' => $this->course->id + )); + + // 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_lesson\event\essay_attempt_viewed', $event); + $this->assertEquals(context_module::instance($this->lesson->properties()->cmid), $event->get_context()); + $expected = array($this->course->id, 'lesson', 'view grade', 'essay.php?id=' . $this->lesson->properties()->cmid . + '&mode=grade&attemptid=1', get_string('manualgrading', 'lesson'), $this->lesson->properties()->cmid); + $this->assertEventLegacyLogData($expected, $event); + } + + /** + * Test the highscore added event. + * + * There is no external API for adding a highscore, so the unit test will simply create + * and trigger the event and ensure the legacy log data is returned as expected. + */ + public function test_highscore_added() { + global $DB; + + // Create a highscore. + $newhighscore = new stdClass; + $newhighscore->lessonid = $this->lesson->id; + $newhighscore->userid = 3; + $newhighscore->gradeid = 70; + $newhighscore->nickname = 'noob'; + + $newhighscore->id = $DB->insert_record('lesson_high_scores', $newhighscore); + + // Create a highscore added event. + $event = \mod_lesson\event\highscore_added::create(array( + 'objectid' => $newhighscore->id, + 'context' => context_module::instance($this->lesson->properties()->cmid), + 'courseid' => $this->course->id + )); + + // 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_lesson\event\highscore_added', $event); + $this->assertEquals(context_module::instance($this->lesson->properties()->cmid), $event->get_context()); + $expected = array($this->course->id, 'lesson', 'update highscores', 'highscores.php?id=' . $this->lesson->properties()->cmid, + 'noob', $this->lesson->properties()->cmid); + $this->assertEventLegacyLogData($expected, $event); + } + + /** + * Test the highscores viewed event. + * + * There is no external API for viewing highscores, so the unit test will simply create + * and trigger the event and ensure the legacy log data is returned as expected. + */ + public function test_highscores_viewed() { + // Create a highscore viewed event. + $event = \mod_lesson\event\highscores_viewed::create(array( + 'objectid' => $this->lesson->id, + 'context' => context_module::instance($this->lesson->properties()->cmid), + 'courseid' => $this->course->id + )); + + // 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_lesson\event\highscores_viewed', $event); + $this->assertEquals(context_module::instance($this->lesson->properties()->cmid), $event->get_context()); + $expected = array($this->course->id, 'lesson', 'view highscores', 'highscores.php?id=' . $this->lesson->properties()->cmid, + $this->lesson->properties()->name, $this->lesson->properties()->cmid); + $this->assertEventLegacyLogData($expected, $event); + } + + /** + * Test the lesson started event. + */ + public function test_lesson_started() { + // Trigger and capture the event. + $sink = $this->redirectEvents(); + $this->lesson->start_timer(); + $events = $sink->get_events(); + $event = reset($events); + + // Check that the event data is valid. + $this->assertInstanceOf('\mod_lesson\event\lesson_started', $event); + $this->assertEquals(context_module::instance($this->lesson->properties()->cmid), $event->get_context()); + $expected = array($this->course->id, 'lesson', 'start', 'view.php?id=' . $this->lesson->properties()->cmid, + $this->lesson->properties()->id, $this->lesson->properties()->cmid); + $this->assertEventLegacyLogData($expected, $event); + } + + /** + * Test the lesson ended event. + */ + public function test_lesson_ended() { + global $DB, $USER; + + // Add a lesson timer so that stop_timer() does not complain. + $lessontimer = new stdClass(); + $lessontimer->lessonid = $this->lesson->properties()->id; + $lessontimer->userid = $USER->id; + $lessontimer->startime = time(); + $lessontimer->lessontime = time(); + $DB->insert_record('lesson_timer', $lessontimer); + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + $this->lesson->stop_timer(); + $events = $sink->get_events(); + $event = reset($events); + + // Check that the event data is valid. + $this->assertInstanceOf('\mod_lesson\event\lesson_ended', $event); + $this->assertEquals(context_module::instance($this->lesson->properties()->cmid), $event->get_context()); + $expected = array($this->course->id, 'lesson', 'end', 'view.php?id=' . $this->lesson->properties()->cmid, + $this->lesson->properties()->id, $this->lesson->properties()->cmid); + $this->assertEventLegacyLogData($expected, $event); + } +} diff --git a/mod/lesson/view.php b/mod/lesson/view.php index e73435fe550..383e9f9cb50 100644 --- a/mod/lesson/view.php +++ b/mod/lesson/view.php @@ -179,8 +179,6 @@ if (empty($pageid)) { } } - add_to_log($course->id, 'lesson', 'start', 'view.php?id='. $cm->id, $lesson->id, $cm->id); - // if no pageid given see if the lesson has been started $retries = $DB->count_records('lesson_grades', array("lessonid" => $lesson->id, "userid" => $USER->id)); if ($retries > 0) { @@ -287,7 +285,13 @@ if ($pageid != LESSON_EOL) { $page = $lesson->load_page($newpageid); } - add_to_log($PAGE->course->id, 'lesson', 'view', 'view.php?id='. $PAGE->cm->id, $page->id, $PAGE->cm->id); + // Trigger module viewed event. + $event = \mod_lesson\event\course_module_viewed::create(array( + 'objectid' => $lesson->id, + 'context' => $context, + 'courseid' => $course->id + )); + $event->trigger(); // This is where several messages (usually warnings) are displayed // all of this is displayed above the actual page @@ -417,9 +421,6 @@ if ($pageid != LESSON_EOL) { // Used to check to see if the student ran out of time $outoftime = optional_param('outoftime', '', PARAM_ALPHA); - // Update the clock / get time information for this user - add_to_log($course->id, "lesson", "end", "view.php?id=".$PAGE->cm->id, "$lesson->id", $PAGE->cm->id); - // We are using level 3 header because the page title is a sub-heading of lesson title (MDL-30911). $lessoncontent .= $OUTPUT->heading(get_string("congratulations", "lesson"), 3); $lessoncontent .= $OUTPUT->box_start('generalbox boxaligncenter'); @@ -428,6 +429,7 @@ if ($pageid != LESSON_EOL) { $ntries--; // need to look at the old attempts :) } if (!$canmanage) { + // Update the clock / get time information for this user. $lesson->stop_timer(); $gradeinfo = lesson_grade($lesson, $ntries);