public function test_chapter_viewed() { // There is no proper API to call to trigger this event, so what we are // doing here is simply making sure that the events returns the right information. $course = $this->getDataGenerator()->create_course(); $book = $this->getDataGenerator()->create_module('book', array('course' => $course->id)); $bookgenerator = $this->getDataGenerator()->get_plugin_generator('mod_book'); $context = context_module::instance($book->cmid); $chapter = $bookgenerator->create_chapter(array('bookid' => $book->id)); $event = \mod_book\event\chapter_viewed::create_from_chapter($book, $context, $chapter); // Triggering and capturing the event. $sink = $this->redirectEvents(); $event->trigger(); $events = $sink->get_events(); $this->assertCount(1, $events); $event = reset($events); // Checking that the event contains the expected values. $this->assertInstanceOf('\\mod_book\\event\\chapter_viewed', $event); $this->assertEquals(context_module::instance($book->cmid), $event->get_context()); $this->assertEquals($chapter->id, $event->objectid); $expected = array($course->id, 'book', 'view chapter', 'view.php?id=' . $book->cmid . '&chapterid=' . $chapter->id, $chapter->id, $book->cmid); $this->assertEventLegacyLogData($expected, $event); $this->assertEventContextNotUsed($event); }
/** * Mark the activity completed (if required) and trigger the course_module_viewed event. * * @param stdClass $book book object * @param stdClass $chapter chapter object * @param bool $islaschapter is the las chapter of the book? * @param stdClass $course course object * @param stdClass $cm course module object * @param stdClass $context context object * @since Moodle 3.0 */ function book_view($book, $chapter, $islastchapter, $course, $cm, $context) { // First case, we are just opening the book. if (empty($chapter)) { \mod_book\event\course_module_viewed::create_from_book($book, $context)->trigger(); } else { \mod_book\event\chapter_viewed::create_from_chapter($book, $context, $chapter)->trigger(); if ($islastchapter) { // We cheat a bit here in assuming that viewing the last page means the user viewed the whole book. $completion = new completion_info($course); $completion->set_module_viewed($cm); } } }
// No content in the book. if (!$chapterid) { $PAGE->set_url('/mod/book/view.php', array('id' => $id)); notice(get_string('nocontent', 'mod_book'), $courseurl->out(false)); } // Chapter doesnt exist or it is hidden for students if (!($chapter = $DB->get_record('book_chapters', array('id' => $chapterid, 'bookid' => $book->id))) or $chapter->hidden and !$viewhidden) { print_error('errorchapter', 'mod_book', $courseurl); } $PAGE->set_url('/mod/book/view.php', array('id' => $id, 'chapterid' => $chapterid)); // Unset all page parameters. unset($id); unset($bid); unset($chapterid); // Security checks END. \mod_book\event\chapter_viewed::create_from_chapter($book, $context, $chapter)->trigger(); // Read standard strings. $strbooks = get_string('modulenameplural', 'mod_book'); $strbook = get_string('modulename', 'mod_book'); $strtoc = get_string('toc', 'mod_book'); // prepare header $pagetitle = $book->name . ": " . $chapter->title; $PAGE->set_title($pagetitle); $PAGE->set_heading($course->fullname); book_add_fake_block($chapters, $chapter, $book, $cm, $edit); // prepare chapter navigation icons $previd = null; $prevtitle = null; $nextid = null; $nexttitle = null; $last = null;
/** * Tests the cleaning up of events. */ public function test_clean_events() { global $DB; // Create the necessary items for testing. $user = $this->getDataGenerator()->create_user(); $course = $this->getDataGenerator()->create_course(); $bookgenerator = $this->getDataGenerator()->get_plugin_generator('mod_book'); $book = $this->getDataGenerator()->create_module('book', array('course' => $course->id)); $bookcontext = context_module::instance($book->cmid); $bookchapter = $bookgenerator->create_chapter(array('bookid' => $book->id)); $course2 = $this->getDataGenerator()->create_course(); $book2 = $this->getDataGenerator()->create_module('book', array('course' => $course2->id)); $book2context = context_module::instance($book2->cmid); $book2chapter = $bookgenerator->create_chapter(array('bookid' => $book2->id)); $monitorgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor'); // Let's set some data for the rules we need before we can generate them. $rule = new stdClass(); $rule->userid = $user->id; $rule->courseid = $course->id; $rule->plugin = 'mod_book'; $rule->eventname = '\\mod_book\\event\\course_module_viewed'; $rule->timewindow = 500; // Let's add a few rules we want to monitor. $rule1 = $monitorgenerator->create_rule($rule); $rule->eventname = '\\mod_book\\event\\course_module_instance_list_viewed'; $rule2 = $monitorgenerator->create_rule($rule); // Add the same rules for the same course, but this time with a lower timewindow (used to test that we do not // remove an event for a course if there is still a rule where the maximum timewindow has not been reached). $rule->eventname = '\\mod_book\\event\\course_module_viewed'; $rule->timewindow = 200; $rule3 = $monitorgenerator->create_rule($rule); $rule->eventname = '\\mod_book\\event\\course_module_instance_list_viewed'; $rule4 = $monitorgenerator->create_rule($rule); // Add another rule in a different course. $rule->courseid = $course2->id; $rule->eventname = '\\mod_book\\event\\chapter_viewed'; $rule->timewindow = 200; $rule5 = $monitorgenerator->create_rule($rule); // Add a site wide rule. $rule->courseid = 0; $rule->eventname = '\\mod_book\\event\\chapter_viewed'; $rule->timewindow = 500; $rule6 = $monitorgenerator->create_rule($rule); // Now let's populate the tool_monitor table with the events associated with those rules. \mod_book\event\course_module_viewed::create_from_book($book, $bookcontext)->trigger(); \mod_book\event\course_module_instance_list_viewed::create_from_course($course)->trigger(); \mod_book\event\chapter_viewed::create_from_chapter($book, $bookcontext, $bookchapter)->trigger(); // Let's trigger the viewed events again, but in another course. The rules created for these events are // associated with another course, so these events should get deleted when we trigger the cleanup task. \mod_book\event\course_module_viewed::create_from_book($book2, $book2context)->trigger(); \mod_book\event\course_module_instance_list_viewed::create_from_course($course2)->trigger(); // Trigger a chapter_viewed event in this course - this should not get deleted as the rule is site wide. \mod_book\event\chapter_viewed::create_from_chapter($book2, $book2context, $book2chapter)->trigger(); // Trigger a bunch of other events. $eventparams = array('context' => context_course::instance($course->id)); for ($i = 0; $i < 5; $i++) { \mod_quiz\event\course_module_instance_list_viewed::create($eventparams)->trigger(); \mod_scorm\event\course_module_instance_list_viewed::create($eventparams)->trigger(); } // Check that the events exist - there will be additional events for creating courses, modules and rules. $this->assertEquals(26, $DB->count_records('tool_monitor_events')); // Run the task and check that all the quiz, scorm and rule events are removed as well as the course_module_* // viewed events in the second course. $task = new \tool_monitor\task\clean_events(); $task->execute(); $events = $DB->get_records('tool_monitor_events'); $this->assertEquals(4, count($events)); $event1 = array_shift($events); $event2 = array_shift($events); $event3 = array_shift($events); $event4 = array_shift($events); $this->assertEquals('\\mod_book\\event\\course_module_viewed', $event1->eventname); $this->assertEquals($course->id, $event1->courseid); $this->assertEquals('\\mod_book\\event\\course_module_instance_list_viewed', $event2->eventname); $this->assertEquals($course->id, $event2->courseid); $this->assertEquals('\\mod_book\\event\\chapter_viewed', $event3->eventname); $this->assertEquals($course->id, $event3->courseid); $this->assertEquals('\\mod_book\\event\\chapter_viewed', $event4->eventname); $this->assertEquals($course2->id, $event4->courseid); // Update the timewindow for two of the rules. $updaterule = new stdClass(); $updaterule->id = $rule1->id; $updaterule->timewindow = 0; \tool_monitor\rule_manager::update_rule($updaterule); $updaterule->id = $rule2->id; \tool_monitor\rule_manager::update_rule($updaterule); // Run the task and check that the events remain as we still have not reached the maximum timewindow. $task = new \tool_monitor\task\clean_events(); $task->execute(); $this->assertEquals(4, $DB->count_records('tool_monitor_events')); // Now, remove the rules associated with course_module_* events so they get deleted. \tool_monitor\rule_manager::delete_rule($rule1->id); \tool_monitor\rule_manager::delete_rule($rule2->id); \tool_monitor\rule_manager::delete_rule($rule3->id); \tool_monitor\rule_manager::delete_rule($rule4->id); // Run the task and check all the course_module_* events are gone. $task = new \tool_monitor\task\clean_events(); $task->execute(); // We now should only have the chapter_viewed events. $events = $DB->get_records('tool_monitor_events'); $this->assertEquals(2, count($events)); $event1 = array_shift($events); $event2 = array_shift($events); $this->assertEquals('\\mod_book\\event\\chapter_viewed', $event1->eventname); $this->assertEquals($course->id, $event1->courseid); $this->assertEquals('\\mod_book\\event\\chapter_viewed', $event2->eventname); $this->assertEquals($course2->id, $event2->courseid); // Set the timewindow of the rule for the event chapter_viewed in the second course to 0. $updaterule->id = $rule5->id; \tool_monitor\rule_manager::update_rule($updaterule); // Run the task. $task = new \tool_monitor\task\clean_events(); $task->execute(); // Check that nothing was deleted as we still have a site wide rule for the chapter_viewed event. $this->assertEquals(2, $DB->count_records('tool_monitor_events')); // Set the timewindow back to 500. $updaterule->id = $rule5->id; $updaterule->timewindow = 500; \tool_monitor\rule_manager::update_rule($updaterule); // Set the site rule timewindow to 0. $updaterule->id = $rule6->id; $updaterule->timewindow = 0; \tool_monitor\rule_manager::update_rule($updaterule); // Run the task. $task = new \tool_monitor\task\clean_events(); $task->execute(); // We now should only have one chapter_viewed event for the second course. $events = $DB->get_records('tool_monitor_events'); $this->assertEquals(1, count($events)); $event1 = array_shift($events); $this->assertEquals('\\mod_book\\event\\chapter_viewed', $event1->eventname); $this->assertEquals($course2->id, $event1->courseid); // Remove the site rule. \tool_monitor\rule_manager::delete_rule($rule6->id); // Remove the last remaining rule. \tool_monitor\rule_manager::delete_rule($rule5->id); // Run the task. $task = new \tool_monitor\task\clean_events(); $task->execute(); // There should be no events left. $this->assertEquals(0, $DB->count_records('tool_monitor_events')); }
/** * Test the subscription criteria met event. */ public function test_subscription_criteria_met() { // Create the items we need to test this. $user = $this->getDataGenerator()->create_user(); $course = $this->getDataGenerator()->create_course(); $book = $this->getDataGenerator()->create_module('book', array('course' => $course->id)); $bookgenerator = $this->getDataGenerator()->get_plugin_generator('mod_book'); $chapter = $bookgenerator->create_chapter(array('bookid' => $book->id)); $monitorgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor'); // Create a rule we want to subscribe to. $rule = new stdClass(); $rule->userid = $user->id; $rule->courseid = $course->id; $rule->plugin = 'mod_book'; $rule->eventname = '\\mod_book\\event\\chapter_viewed'; $rule->frequency = 1; $rule->timewindow = 60; $rule = $monitorgenerator->create_rule($rule); // Create the subscription. $sub = new stdClass(); $sub->courseid = $course->id; $sub->userid = $user->id; $sub->ruleid = $rule->id; $monitorgenerator->create_subscription($sub); // Now create the \mod_book\event\chapter_viewed event we are listening for. $context = context_module::instance($book->cmid); $event = \mod_book\event\chapter_viewed::create_from_chapter($book, $context, $chapter); // Trigger and capture the event. $sink = $this->redirectEvents(); \tool_monitor\eventobservers::process_event($event); $events = $sink->get_events(); $this->assertCount(1, $events); $event = reset($events); // Confirm that the event contains the expected values. $this->assertInstanceOf('\\tool_monitor\\event\\subscription_criteria_met', $event); $this->assertEquals(context_course::instance($course->id), $event->get_context()); $this->assertEventContextNotUsed($event); }