/** * Returns the string to display for the help icon. * * @param string $type the type we are displaying the help icon for (either rule or subscription). * @param int $id the id of the type. * @param boolean $ajax Whether this help is called from an AJAX script. * This is used to influence text formatting and determines which format to output the doclink in. * @return string|object|array $a An object, string or number that can be used within translation strings */ public static function get_help_string_parameters($type, $id, $ajax = false) { if ($type == 'rule') { $rule = \tool_monitor\rule_manager::get_rule($id); $langstring = new \stdClass(); $langstring->eventname = $rule->get_event_name(); $langstring->eventcomponent = $rule->get_plugin_name(); $langstring->frequency = $rule->frequency; $langstring->minutes = $rule->timewindow / MINSECS; return get_formatted_help_string('rulehelp', 'tool_monitor', $ajax, $langstring); } // Must be a subscription. $sub = \tool_monitor\subscription_manager::get_subscription($id); $langstring = new \stdClass(); $langstring->eventname = $sub->get_event_name(); $langstring->moduleinstance = $sub->get_instance_name(); $langstring->frequency = $sub->frequency; $langstring->minutes = $sub->timewindow / MINSECS; return get_formatted_help_string('subhelp', 'tool_monitor', $ajax, $langstring); }
/** * Query the reader. Store results in the object for use by build_table. * * @param int $pagesize size of page for paginated displayed table. * @param bool $useinitialsbar do you want to use the initials bar. */ public function query_db($pagesize, $useinitialsbar = true) { $total = \tool_monitor\rule_manager::count_rules_by_courseid($this->courseid); $this->pagesize($pagesize, $total); $rules = \tool_monitor\rule_manager::get_rules_by_courseid($this->courseid, $this->get_page_start(), $this->get_page_size()); $this->rawdata = $rules; // Set initial bars. if ($useinitialsbar) { $this->initialbars($total > $pagesize); } }
/** * Test observer for course module delete event. */ public function test_course_module_deleted() { global $DB; $this->setAdminUser(); $this->resetAfterTest(true); $user = $this->getDataGenerator()->create_user(); $course1 = $this->getDataGenerator()->create_course(); $course2 = $this->getDataGenerator()->create_course(); $monitorgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor'); // Now let us create a rule specific to a module instance. $cm = new stdClass(); $cm->course = $course1->id; $book = $this->getDataGenerator()->create_module('book', $cm); $rule = new stdClass(); $rule->userid = $user->id; $rule->courseid = $course1->id; $rule->plugin = 'test'; $sub = new stdClass(); $sub->courseid = $course1->id; $sub->userid = $user->id; $sub->cmid = $book->cmid; // Add 10 rules for this course with subscriptions for this module. for ($i = 0; $i < 10; $i++) { $createdrule = $monitorgenerator->create_rule($rule); $sub->ruleid = $createdrule->id; $monitorgenerator->create_subscription($sub); } // Add 10 random rules for course 2. $rule->courseid = $course2->id; for ($i = 0; $i < 10; $i++) { $createdrule = $monitorgenerator->create_rule($rule); $sub->courseid = $rule->courseid; $sub->ruleid = $createdrule->id; $sub->cmid = 0; $monitorgenerator->create_subscription($sub); } // Verify data before module delete. $totalrules = \tool_monitor\rule_manager::get_rules_by_plugin('test'); $this->assertCount(20, $totalrules); $totalsubs = $DB->get_records('tool_monitor_subscriptions'); $this->assertCount(20, $totalsubs); // Let us delete the user now. course_delete_module($book->cmid); // Verify data after course delete. $totalrules = \tool_monitor\rule_manager::get_rules_by_plugin('test'); $this->assertCount(20, $totalrules); $totalsubs = $DB->get_records('tool_monitor_subscriptions'); $this->assertCount(10, $totalsubs); // Make sure only relevant subscriptions are deleted. }
/** * Test get_rules_by_event method. */ public function test_get_rules_by_event() { $this->setAdminUser(); $this->resetAfterTest(true); $monitorgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor'); $rule = $monitorgenerator->create_rule(); $record = new stdClass(); $record->eventname = '\\core\\event\\calendar_event_created'; $record2 = new stdClass(); $record2->eventname = '\\core\\event\\calendar_event_updated'; $ruleids = array(); for ($i = 0; $i < 10; $i++) { $rule = $monitorgenerator->create_rule($record); $ruleids[] = $rule->id; $rule = $monitorgenerator->create_rule($record2); // Create rules in a different plugin. } $ruledata = \tool_monitor\rule_manager::get_rules_by_event('\\core\\event\\calendar_event_created'); $this->assertEmpty(array_diff(array_keys($ruledata), $ruleids)); $this->assertCount(10, $ruledata); }
/** * Function to generate rule data. * * @param \stdClass|array $record data to insert as rule entry. * * @return \tool_monitor\rule An instance of rule class. */ public function create_rule($record = null) { global $USER; $this->rulecount++; $i = $this->rulecount; $now = time(); $record = (object) (array) $record; if (!isset($record->userid)) { $record->userid = $USER->id; } if (!isset($record->courseid)) { $record->courseid = 0; } if (!isset($record->name)) { $record->name = 'Test rule ' . $i; } if (!isset($record->description)) { $record->description = 'Rule description ' . $i; } if (!isset($record->descriptionformat)) { $record->descriptionformat = FORMAT_HTML; } if (!isset($record->frequency)) { $record->frequency = 5; } if (!isset($record->minutes)) { $record->minutes = 5; } if (!isset($record->template)) { $record->template = 'Rule message template ' . $i; } if (!isset($record->templateformat)) { $record->templateformat = FORMAT_HTML; } if (!isset($record->timewindow)) { $record->timewindow = $record->minutes * 60; } if (!isset($record->timecreated)) { $record->timecreated = $now; } if (!isset($record->timemodified)) { $record->timemodified = $now; } if (!isset($record->plugin)) { $record->plugin = 'core'; } if (!isset($record->eventname)) { $record->eventname = '\\core\\event\\blog_entry_created'; } unset($record->minutes); // Remove the minutes shortcut to the timewindow. return \tool_monitor\rule_manager::add_rule($record); }
if (!empty($action) && $action == 'changestatus') { require_sesskey(); require_capability('tool/monitor:managetool', context_system::instance()); // Toggle status of the plugin. set_config('enablemonitor', $status, 'tool_monitor'); redirect(new moodle_url('/admin/tool/monitor/managerules.php', array('courseid' => 0))); } // Copy/delete rule if needed. if (!empty($action) && $ruleid) { require_sesskey(); // If the rule does not exist, then redirect back as the rule must have already been deleted. if (!($rule = $DB->get_record('tool_monitor_rules', array('id' => $ruleid), '*', IGNORE_MISSING))) { redirect(new moodle_url('/admin/tool/monitor/managerules.php', array('courseid' => $courseid))); } echo $OUTPUT->header(); $rule = \tool_monitor\rule_manager::get_rule($rule); switch ($action) { case 'copy': // No need to check for capability here as it is done at the start of the page. $rule->duplicate_rule($courseid); echo $OUTPUT->notification(get_string('rulecopysuccess', 'tool_monitor'), 'notifysuccess'); break; case 'delete': if ($rule->can_manage_rule()) { $confirmurl = new moodle_url($CFG->wwwroot . '/admin/tool/monitor/managerules.php', array('ruleid' => $ruleid, 'courseid' => $courseid, 'action' => 'delete', 'confirm' => true, 'sesskey' => sesskey())); $cancelurl = new moodle_url($CFG->wwwroot . '/admin/tool/monitor/managerules.php', array('courseid' => $courseid)); if ($confirm) { $rule->delete_rule(); echo $OUTPUT->notification(get_string('ruledeletesuccess', 'tool_monitor'), 'notifysuccess'); } else { $strconfirm = get_string('ruleareyousure', 'tool_monitor', $rule->get_name($context));
// You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Displays help via AJAX call. * * @copyright 2014 Mark Nelson <*****@*****.**> * @package tool_monitor * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ define('NO_MOODLE_COOKIES', true); define('AJAX_SCRIPT', true); require_once '../../../config.php'; $type = required_param('type', PARAM_ALPHA); $id = required_param('id', PARAM_INT); $lang = optional_param('lang', 'en', PARAM_LANG); // We don't actually modify the session here as we have NO_MOODLE_COOKIES set. $SESSION->lang = $lang; $PAGE->set_url('/admin/tool/monitor/help_ajax.php'); if ($type == 'rule') { $item = \tool_monitor\rule_manager::get_rule($id); } else { // Must be a subscription. $item = \tool_monitor\subscription_manager::get_subscription($id); } if ($item->courseid) { $PAGE->set_context(context_course::instance($item->courseid)); } else { // Must be system context. $PAGE->set_context(context_system::instance()); } echo json_encode(tool_monitor\output\helpicon\renderable::get_help_string_parameters($type, $id, true));
/** * 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')); }
$subscriptioncount = \tool_monitor\subscription_manager::count_rule_subscriptions($ruleid); } else { $rule = new stdClass(); $subscriptioncount = 0; } $mform = new tool_monitor\rule_form(null, array('eventlist' => $eventlist, 'pluginlist' => $pluginlist, 'rule' => $rule, 'courseid' => $courseid, 'subscriptioncount' => $subscriptioncount)); if ($mform->is_cancelled()) { redirect(new moodle_url('/admin/tool/monitor/managerules.php', array('courseid' => $courseid))); exit; } if ($mformdata = $mform->get_data()) { $rule = \tool_monitor\rule_manager::clean_ruledata_form($mformdata); if (empty($rule->id)) { \tool_monitor\rule_manager::add_rule($rule); } else { \tool_monitor\rule_manager::update_rule($rule); } redirect($manageurl); } else { echo $OUTPUT->header(); $mform->set_data($rule); // If there's any subscription for this rule, display an information message. if ($subscriptioncount > 0) { echo $OUTPUT->notification(get_string('disablefieldswarning', 'tool_monitor'), 'notifyproblem'); } $mform->display(); echo $OUTPUT->footer(); exit; } echo $OUTPUT->header(); if (!empty($ruleid)) {
} else { $subscription = \tool_monitor\subscription_manager::get_subscription($subscriptionid); echo $OUTPUT->header(); echo $OUTPUT->confirm(get_string('subareyousure', 'tool_monitor', $subscription->get_name($coursecontext)), $confirmurl, $cancelurl); echo $OUTPUT->footer(); exit; } break; default: } } else { echo $OUTPUT->header(); } $renderer = $PAGE->get_renderer('tool_monitor', 'managesubs'); // Render the course selector. $totalrules = \tool_monitor\rule_manager::count_rules_by_courseid($courseid); $rules = new \tool_monitor\output\managesubs\rules('toolmonitorrules', $indexurl, $courseid); $usercourses = $rules->get_user_courses_select(); if (!empty($usercourses)) { echo $renderer->render($usercourses); } else { // Nothing to show at all. Show a notification. echo $OUTPUT->notification(get_string('rulenopermission', 'tool_monitor'), 'notifyproblem'); } // Render the current subscriptions list. $totalsubs = \tool_monitor\subscription_manager::count_user_subscriptions(); if (!empty($totalsubs)) { // Show the subscriptions section only if there are subscriptions. $subs = new \tool_monitor\output\managesubs\subs('toolmonitorsubs', $indexurl, $courseid); echo $OUTPUT->heading(get_string('currentsubscriptions', 'tool_monitor'), 3); echo $renderer->render($subs);
/** * Test the rule deleted event. */ public function test_rule_deleted() { // Create the items we need. $monitorgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor'); $course = $this->getDataGenerator()->create_course(); // Create the rule we are going to delete. $createrule = new stdClass(); $createrule->courseid = $course->id; $rule = $monitorgenerator->create_rule($createrule); // Trigger and capture the event. $sink = $this->redirectEvents(); \tool_monitor\rule_manager::delete_rule($rule->id); $events = $sink->get_events(); $this->assertCount(1, $events); $event = reset($events); // Confirm that the event contains the expected values. $this->assertInstanceOf('\\tool_monitor\\event\\rule_deleted', $event); $this->assertEquals(context_course::instance($course->id), $event->get_context()); $this->assertEquals($rule->id, $event->objectid); $this->assertEventContextNotUsed($event); // Now let's delete a system rule (courseid = 0). $createrule = new stdClass(); $createrule->courseid = 0; $rule = $monitorgenerator->create_rule($createrule); // Trigger and capture the event. $sink = $this->redirectEvents(); \tool_monitor\rule_manager::delete_rule($rule->id); $events = $sink->get_events(); $this->assertCount(1, $events); $event = reset($events); // Confirm that the event uses the system context. $this->assertInstanceOf('\\tool_monitor\\event\\rule_deleted', $event); $this->assertEquals(context_system::instance(), $event->get_context()); }