diff --git a/admin/tool/monitor/classes/task/clean_events.php b/admin/tool/monitor/classes/task/clean_events.php new file mode 100644 index 00000000000..9efb360e898 --- /dev/null +++ b/admin/tool/monitor/classes/task/clean_events.php @@ -0,0 +1,142 @@ +<?php +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. + +/** + * Clean the tool_monitor_events table. + * + * @package tool_monitor + * @copyright 2014 Mark Nelson <markn@moodle.com> + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace tool_monitor\task; + +/** + * Simple task to clean the tool_monitor_events table. + */ +class clean_events extends \core\task\scheduled_task { + + /** + * Get a descriptive name for this task. + * + * @return string + */ + public function get_name() { + return get_string('taskcleanevents', 'tool_monitor'); + } + + /** + * Performs the cleaning of events. + */ + public function execute() { + global $DB; + + // Array to store which events have been triggered in which course. + $courses = array(); + + // Firstly, let's go through the site wide rules. There may be multiple rules for the site that rely on + // the same event being triggered, so we only remove the events when they reach the max timewindow. + if ($siterules = $DB->get_recordset('tool_monitor_rules', array('courseid' => 0), 'timewindow DESC')) { + // Go through each rule and check if there are any events we can remove. + foreach ($siterules as $rule) { + // Check if we have already processed this event. + if (isset($courses[$rule->courseid][$rule->eventname])) { + continue; + } + // Store the timewindow for this event. + $courses[$rule->courseid][$rule->eventname] = $rule->timewindow; + // Delete any events that may exist that have exceeded the timewindow. + $DB->delete_records_select('tool_monitor_events', 'eventname = :eventname AND + courseid = :courseid AND timecreated <= :timewindow', + array('eventname' => $rule->eventname, 'courseid' => $rule->courseid, + 'timewindow' => time() - $rule->timewindow)); + } + // Free resources. + $siterules->close(); + } + + // Now, get the course rules. The same applies here - there may be multiple rules for the course that rely on + // the same event being triggered, so we only remove the events when they reach the max timewindow. + if ($rules = $DB->get_recordset_select('tool_monitor_rules', 'courseid != 0', array(), 'timewindow DESC')) { + // Go through each rule and check if there are any events we can remove. + foreach ($rules as $rule) { + // Check if we have already processed this event for this particular course. + if (isset($courses[$rule->courseid][$rule->eventname])) { + continue; + } + // Add the course and event to the list. + $courses[$rule->courseid][$rule->eventname] = $rule->timewindow; + // If there is a site wide rule listening for this event do not remove it unless the maximum + // timewindow between the two has exceeded. + $timewindow = $rule->timewindow; + if (isset($courses[0][$rule->eventname]) && ($courses[0][$rule->eventname] > $timewindow)) { + $timewindow = $courses[0][$rule->eventname]; + } + // Delete any events that may exist that have exceeded the timewindow. + $DB->delete_records_select('tool_monitor_events', 'eventname = :eventname AND + courseid = :courseid AND timecreated <= :timewindow', + array('eventname' => $rule->eventname, 'courseid' => $rule->courseid, + 'timewindow' => time() - $timewindow)); + } + // Free resources. + $rules->close(); + } + + if ($siterules || $rules) { // Check that there are rules present. + // Get a list of all the events we have been through. + $allevents = array(); + foreach ($courses as $key => $value) { + foreach ($courses[$key] as $event => $notused) { + $allevents[] = $event; + } + } + // Remove all the events in the table that are not applicable to any rule. There may be a rule in one course + // listening for a certain event, but not in another course, so we can delete the event from the course + // where there is no rule. We also have to consider site wide rules. We may have an event that is triggered + // in a course we can't remove because there is a site wide rule for this event. + if ($events = $DB->get_recordset('tool_monitor_events')) { + // Array to store which events we need to remove. + $eventstodelete = array(); + // Store the current time. + $now = time(); + foreach ($events as $event) { + // If the event is not required for a course rule and there is no site wide rule for it, or + // it has extended past or equal to the timewindow for the site rule - it can be deleted. + if (!isset($courses[$event->courseid][$event->eventname]) && (!isset($courses[0][$event->eventname]) + || $courses[0][$event->eventname] <= ($now - $event->timecreated))) { + $eventstodelete[] = $event->id; + } + } + // Free resources. + $events->close(); + + // Remove the events. + if (!empty($eventstodelete)) { + list($eventidsql, $params) = $DB->get_in_or_equal($eventstodelete); + $DB->delete_records_select('tool_monitor_events', "id $eventidsql", $params); + } + } + + // Remove all the events in the table that are not used by any rule. + if (!empty($allevents)) { + list($eventnamesql, $params) = $DB->get_in_or_equal($allevents, SQL_PARAMS_QM, 'param', false); + $DB->delete_records_select('tool_monitor_events', "eventname $eventnamesql", $params); + } + } else { // No rules, just remove everything. + $DB->delete_records('tool_monitor_events'); + } + } +} diff --git a/admin/tool/monitor/db/tasks.php b/admin/tool/monitor/db/tasks.php new file mode 100644 index 00000000000..e70c3448110 --- /dev/null +++ b/admin/tool/monitor/db/tasks.php @@ -0,0 +1,36 @@ +<?php +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. + +/** + * This file defines tasks performed by the tool. + * + * @package tool_monitor + * @copyright 2014 Mark Nelson <markn@moodle.com> + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +// List of tasks. +$tasks = array( + array( + 'classname' => 'tool_monitor\task\clean_events', + 'blocking' => 0, + 'minute' => '*', + 'hour' => '*', + 'day' => '*', + 'dayofweek' => '*', + 'month' => '*' + ) +); diff --git a/admin/tool/monitor/lang/en/tool_monitor.php b/admin/tool/monitor/lang/en/tool_monitor.php index bfac7998977..0d39eeb6e6f 100644 --- a/admin/tool/monitor/lang/en/tool_monitor.php +++ b/admin/tool/monitor/lang/en/tool_monitor.php @@ -84,6 +84,7 @@ $string['subcreatesuccess'] = "Subscription successfully created"; $string['subdeletesuccess'] = "Subscription successfully removed"; $string['subhelp'] = 'Subscription details'; $string['subhelp_help'] = 'This subscription listens for when the event \'{$a->eventname}\' has been triggered in \'{$a->moduleinstance}\' {$a->frequency} time(s) in {$a->minutes} minute(s).'; +$string['taskcleanevents'] = 'Removes any unnecessary event monitor events'; $string['title'] = '{$a->coursename} : {$a->reportname}'; $string['monitor:managerules'] = 'Manage event monitor rules'; $string['monitor:subscribe'] = 'Subscribe to event monitor rules';