$temp->add(new admin_setting_configcheckbox('allowuserblockhiding', new lang_string('allowuserblockhiding', 'admin'), new lang_string('configallowuserblockhiding', 'admin'), 1));
$temp->add(new admin_setting_configcheckbox('allowblockstodock', new lang_string('allowblockstodock', 'admin'), new lang_string('configallowblockstodock', 'admin'), 1));
$temp->add(new admin_setting_configtextarea('custommenuitems', new lang_string('custommenuitems', 'admin'), new lang_string('configcustommenuitems', 'admin'), '', PARAM_TEXT, '50', '10'));
+ $temp->add(new admin_setting_configtextarea(
+ 'customusermenuitems',
+ new lang_string('customusermenuitems', 'admin'),
+ new lang_string('configcustomusermenuitems', 'admin'),
+ 'messages,message|/message/index.php|message
+myfiles,moodle|/user/files.php|download
+mybadges,badges|/badges/mybadges.php|award',
+ PARAM_TEXT,
+ '50',
+ '10'
+ ));
$temp->add(new admin_setting_configcheckbox('enabledevicedetection', new lang_string('enabledevicedetection', 'admin'), new lang_string('configenabledevicedetection', 'admin'), 1));
$temp->add(new admin_setting_devicedetectregex('devicedetectregex', new lang_string('devicedetectregex', 'admin'), new lang_string('devicedetectregex_desc', 'admin'), ''));
$ADMIN->add('themes', $temp);
$defaults = array('value'=>0, 'forced'=>false, 'adv'=>true);
$temp->add(new admin_setting_gradecat_combo('grade_aggregateoutcomes', new lang_string('aggregateoutcomes', 'grades'),
new lang_string('aggregateoutcomes_help', 'grades'), $defaults, $options));
- $temp->add(new admin_setting_gradecat_combo('grade_aggregatesubcats', new lang_string('aggregatesubcats', 'grades'),
- new lang_string('aggregatesubcats_help', 'grades'), $defaults, $options));
$options = array(0 => new lang_string('none'));
for ($i=1; $i<=20; $i++) {
$string['validationmsg_filesnumber'] = 'Not enough files found in the package';
$string['validationmsg_filestatus'] = 'Unable to extract all files';
$string['validationmsg_filestatus_info'] = 'Attempting to extract file {$a->file} resulted in error \'{$a->status}\'.';
+$string['validationmsg_foundlangfile'] = 'Found language file';
$string['validationmsg_maturity'] = 'Declared maturity level';
$string['validationmsg_maturity_help'] = 'The plugin can declare its maturity level. If the maintainer considers the plugin stable, the declared maturity level will read MATURITY_STABLE. All other maturity levels (such as alpha or beta) should be considered unstable and a warning is raised.';
$string['validationmsg_missingexpectedlangenfile'] = 'English language file name mismatch';
* }
*
* @package tool_langimport
+ * @since Moodle 2.8
* @copyright 2014 Dan Poltawski <dan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
* }
*
* @package tool_langimport
+ * @since Moodle 2.8
* @copyright 2014 Dan Poltawski <dan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
* }
*
* @package tool_langimport
+ * @since Moodle 2.8
* @copyright 2014 Dan Poltawski <dan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
DAYSECS => get_string('oneday', 'tool_messageinbound'),
WEEKSECS => get_string('oneweek', 'tool_messageinbound'),
YEARSECS => get_string('oneyear', 'tool_messageinbound'),
- '' => get_string('noexpiry', 'tool_messageinbound'),
+ 0 => get_string('noexpiry', 'tool_messageinbound'),
);
$mform->addElement('select', 'defaultexpiration', get_string('defaultexpiration', 'tool_messageinbound'), $options);
$mform->addHelpButton('defaultexpiration', 'defaultexpiration', 'tool_messageinbound');
--- /dev/null
+<?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/>.
+
+/**
+ * The tool_monitor rule created event.
+ *
+ * @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\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * The tool_monitor rule created event class.
+ *
+ * @package tool_monitor
+ * @since Moodle 2.8
+ * @copyright 2014 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class rule_created extends \core\event\base {
+
+ /**
+ * Init method.
+ *
+ * @return void
+ */
+ protected function init() {
+ $this->data['objecttable'] = 'tool_monitor_rules';
+ $this->data['crud'] = 'c';
+ $this->data['edulevel'] = self::LEVEL_OTHER;
+ }
+
+ /**
+ * Return localised event name.
+ *
+ * @return string
+ */
+ public static function get_name() {
+ return get_string('eventrulecreated', 'tool_monitor');
+ }
+
+ /**
+ * Returns description of what happened.
+ *
+ * @return string
+ */
+ public function get_description() {
+ return "The user with id '$this->userid' created the event monitor rule with id '$this->objectid'.";
+ }
+
+ /**
+ * Get URL related to the action
+ *
+ * @return \moodle_url
+ */
+ public function get_url() {
+ return new \moodle_url('/admin/tool/monitor/edit.php', array('ruleid' => $this->objectid,
+ 'courseid' => $this->courseid));
+ }
+}
--- /dev/null
+<?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/>.
+
+/**
+ * The tool_monitor rule deleted event.
+ *
+ * @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\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * The tool_monitor rule deleted event class.
+ *
+ * @package tool_monitor
+ * @since Moodle 2.8
+ * @copyright 2014 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class rule_deleted extends \core\event\base {
+
+ /**
+ * Init method.
+ *
+ * @return void
+ */
+ protected function init() {
+ $this->data['objecttable'] = 'tool_monitor_rules';
+ $this->data['crud'] = 'd';
+ $this->data['edulevel'] = self::LEVEL_OTHER;
+ }
+
+ /**
+ * Return localised event name.
+ *
+ * @return string
+ */
+ public static function get_name() {
+ return get_string('eventruledeleted', 'tool_monitor');
+ }
+
+ /**
+ * Returns description of what happened.
+ *
+ * @return string
+ */
+ public function get_description() {
+ return "The user with id '$this->userid' deleted the event monitor rule with id '$this->objectid'.";
+ }
+
+ /**
+ * Get URL related to the action
+ *
+ * @return \moodle_url
+ */
+ public function get_url() {
+ return new \moodle_url('/admin/tool/monitor/managerules.php', array('courseid' => $this->courseid));
+ }
+}
--- /dev/null
+<?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/>.
+
+/**
+ * The tool_monitor rule updated event.
+ *
+ * @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\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * The tool_monitor rule updated event class.
+ *
+ * @package tool_monitor
+ * @since Moodle 2.8
+ * @copyright 2014 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class rule_updated extends \core\event\base {
+
+ /**
+ * Init method.
+ *
+ * @return void
+ */
+ protected function init() {
+ $this->data['objecttable'] = 'tool_monitor_rules';
+ $this->data['crud'] = 'u';
+ $this->data['edulevel'] = self::LEVEL_OTHER;
+ }
+
+ /**
+ * Return localised event name.
+ *
+ * @return string
+ */
+ public static function get_name() {
+ return get_string('eventruleupdated', 'tool_monitor');
+ }
+
+ /**
+ * Returns description of what happened.
+ *
+ * @return string
+ */
+ public function get_description() {
+ return "The user with id '$this->userid' updated the event monitor rule with id '$this->objectid'.";
+ }
+
+ /**
+ * Get URL related to the action
+ *
+ * @return \moodle_url
+ */
+ public function get_url() {
+ return new \moodle_url('/admin/tool/monitor/edit.php', array('ruleid' => $this->objectid,
+ 'courseid' => $this->courseid));
+ }
+}
--- /dev/null
+<?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/>.
+
+/**
+ * The tool_monitor subscription created event.
+ *
+ * @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\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * The tool_monitor subscription created event class.
+ *
+ * @package tool_monitor
+ * @since Moodle 2.8
+ * @copyright 2014 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class subscription_created extends \core\event\base {
+
+ /**
+ * Init method.
+ *
+ * @return void
+ */
+ protected function init() {
+ $this->data['objecttable'] = 'tool_monitor_subscriptions';
+ $this->data['crud'] = 'c';
+ $this->data['edulevel'] = self::LEVEL_TEACHING;
+ }
+
+ /**
+ * Return localised event name.
+ *
+ * @return string
+ */
+ public static function get_name() {
+ return get_string('eventsubcreated', 'tool_monitor');
+ }
+
+ /**
+ * Returns description of what happened.
+ *
+ * @return string
+ */
+ public function get_description() {
+ return "The user with id '$this->userid' created the event monitor subscription with id '$this->objectid'.";
+ }
+}
--- /dev/null
+<?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/>.
+
+/**
+ * The tool_monitor subscription criteria met event.
+ *
+ * @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\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * The tool_monitor subscription criteria met event class.
+ *
+ * @property-read array $other {
+ * Extra information about event.
+ *
+ * - string subscriptionid: id of the subscription.
+ * }
+ *
+ * @package tool_monitor
+ * @since Moodle 2.8
+ * @copyright 2014 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class subscription_criteria_met extends \core\event\base {
+
+ /**
+ * Init method.
+ *
+ * @return void
+ */
+ protected function init() {
+ $this->data['crud'] = 'c';
+ $this->data['edulevel'] = self::LEVEL_TEACHING;
+ }
+
+ /**
+ * Return localised event name.
+ *
+ * @return string
+ */
+ public static function get_name() {
+ return get_string('eventsubcriteriamet', 'tool_monitor');
+ }
+
+ /**
+ * Returns description of what happened.
+ *
+ * @return string
+ */
+ public function get_description() {
+ return "The criteria for the subscription with id '{$this->other['subscriptionid']}' was met.";
+ }
+
+ /**
+ * Custom validation.
+ *
+ * @throws \coding_exception
+ * @return void
+ */
+ protected function validate_data() {
+ parent::validate_data();
+
+ if (!isset($this->other['subscriptionid'])) {
+ throw new \coding_exception('The \'subscriptionid\' value must be set in other.');
+ }
+ }
+}
--- /dev/null
+<?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/>.
+
+/**
+ * The tool_monitor subscription deleted event.
+ *
+ * @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\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * The tool_monitor subscription deleted event class.
+ *
+ * @package tool_monitor
+ * @since Moodle 2.8
+ * @copyright 2014 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class subscription_deleted extends \core\event\base {
+
+ /**
+ * Init method.
+ *
+ * @return void
+ */
+ protected function init() {
+ $this->data['objecttable'] = 'tool_monitor_subscriptions';
+ $this->data['crud'] = 'd';
+ $this->data['edulevel'] = self::LEVEL_TEACHING;
+ }
+
+ /**
+ * Return localised event name.
+ *
+ * @return string
+ */
+ public static function get_name() {
+ return get_string('eventsubdeleted', 'tool_monitor');
+ }
+
+ /**
+ * Returns description of what happened.
+ *
+ * @return string
+ */
+ public function get_description() {
+ return "The user with id '$this->userid' deleted the event monitor subscription with id '$this->objectid'.";
+ }
+}
*/
public static function course_deleted(\core\event\course_deleted $event) {
$rules = rule_manager::get_rules_by_courseid($event->courseid);
+ $context = null;
+ if ($event->contextlevel == CONTEXT_COURSE) {
+ $context = $event->get_context();
+ }
foreach ($rules as $rule) {
- rule_manager::delete_rule($rule->id);
+ rule_manager::delete_rule($rule->id, $context);
}
}
$select = "SELECT COUNT(id) FROM {tool_monitor_events} ";
$now = time();
$messagestosend = array();
+ $allsubids = array();
// Let us now process the events and check for subscriptions.
foreach ($events as $eventobj) {
$idstosend = array();
foreach ($subscriptions as $subscription) {
$starttime = $now - $subscription->timewindow;
+ $starttime = ($starttime > $subscription->lastnotificationsent) ? $starttime : $subscription->lastnotificationsent;
if ($subscription->courseid == 0) {
// Site level subscription. Count all events.
$where = "eventname = :eventname AND timecreated > :starttime";
$count = $DB->count_records_sql($sql, $params);
if (!empty($count) && $count >= $subscription->frequency) {
$idstosend[] = $subscription->id;
+
+ // Trigger a subscription_criteria_met event.
+ // It's possible that the course has been deleted since the criteria was met, so in that case use
+ // the system context. Set it here and change later if needed.
+ $context = \context_system::instance();
+ // We can't perform if (!empty($subscription->courseid)) below as it uses the magic method
+ // __get to return the variable, which will always result in being empty.
+ $courseid = $subscription->courseid;
+ if (!empty($courseid)) {
+ if ($coursecontext = \context_course::instance($courseid, IGNORE_MISSING)) {
+ $context = $coursecontext;
+ }
+ }
+
+ $params = array(
+ 'userid' => $subscription->userid,
+ 'courseid' => $subscription->courseid,
+ 'context' => $context,
+ 'other' => array(
+ 'subscriptionid' => $subscription->id
+ )
+ );
+ $event = \tool_monitor\event\subscription_criteria_met::create($params);
+ $event->trigger();
}
}
if (!empty($idstosend)) {
$messagestosend[] = array('subscriptionids' => $idstosend, 'event' => $eventobj);
+ $allsubids = array_merge($allsubids, $idstosend);
}
}
+ if (!empty($allsubids)) {
+ // Update the last trigger flag.
+ list($sql, $params) = $DB->get_in_or_equal($allsubids, SQL_PARAMS_NAMED);
+ $params['now'] = $now;
+ $sql = "UPDATE {tool_monitor_subscriptions} SET lastnotificationsent = :now WHERE id $sql";
+ $DB->execute($sql, $params);
+ }
+
// Schedule a task to send notification.
if (!empty($messagestosend)) {
$adhocktask = new notification_task();
$subscriptionids = $data->subscriptionids;
foreach ($subscriptionids as $id) {
if ($message = $this->generate_message($id, $eventobj)) {
+ mtrace("Sending message to the user with id " . $message->userto->id . " for the subscription with id $id...");
message_send($message);
+ mtrace("Sent.");
}
}
}
return false;
}
$user = \core_user::get_user($subscription->userid);
+ if (empty($user)) {
+ // User doesn't exist. Should never happen, nothing to do return.
+ return false;
+ }
$context = \context_user::instance($user->id, IGNORE_MISSING);
if ($context === false) {
// User context doesn't exist. Should never happen, nothing to do return.
+++ /dev/null
-<?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/>.
-
-/**
- * The file for the renderable class for the tool_monitor help icon.
- *
- * @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\output\helpicon;
-
-defined('MOODLE_INTERNAL') || die;
-
-/**
- * Renderable class for the tool_monitor help icon.
- *
- * @since Moodle 2.8
- * @package tool_monitor
- * @copyright 2014 Mark Nelson <markn@moodle.com>
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class renderable implements \renderable {
-
- /**
- * @var string $type the type we are displaying the help icon for (either rule or subscription).
- */
- public $type;
-
- /**
- * @var int $id the id of the type.
- */
- public $id;
-
- /**
- * The constructor.
- *
- * @param string $type the type we are displaying the help icon for (either rule or subscription).
- * @param int $id the id of the type.
- */
- public function __construct($type, $id) {
- $this->type = $type;
- $this->id = $id;
- }
-
- /**
- * 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);
- }
-}
+++ /dev/null
-<?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/>.
-
-/**
- * The file for the renderer class for the tool_monitor help icon.
- *
- * @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\output\helpicon;
-
-defined('MOODLE_INTERNAL') || die;
-
-/**
- * Renderer class for tool_monitor help icons.
- *
- * @since Moodle 2.8
- * @package tool_monitor
- * @copyright 2014 Mark Nelson <markn@moodle.com>
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class renderer extends \plugin_renderer_base {
-
- /**
- * Get the HTML for the help icon.
- *
- * @param renderable $renderable renderable widget
- *
- * @return string the HTML of the help icon to display.
- */
- protected function render_renderable(renderable $renderable) {
- global $CFG;
-
- // First get the help image icon.
- $src = $this->pix_url('help');
-
- if ($renderable->type == 'rule') {
- $title = get_string('rulehelp', 'tool_monitor');
- } else { // Must be a subscription.
- $title = get_string('subhelp', 'tool_monitor');
- }
-
- $alt = get_string('helpwiththis');
-
- $attributes = array('src' => $src, 'alt' => $alt, 'class' => 'iconhelp');
- $output = \html_writer::empty_tag('img', $attributes);
-
- // Now create the link around it - we need https on loginhttps pages.
- $urlparams = array();
- $urlparams['type'] = $renderable->type;
- $urlparams['id'] = $renderable->id;
- $urlparams['lang'] = current_language();
- $url = new \moodle_url($CFG->httpswwwroot . '/admin/tool/monitor/help.php', $urlparams);
-
- // Note: this title is displayed only if JS is disabled, otherwise the link will have the new ajax tooltip.
- $title = get_string('helpprefix2', '', trim($title, ". \t"));
-
- $attributes = array('href' => $url, 'title' => $title, 'aria-haspopup' => 'true', 'target' => '_blank');
- $output = \html_writer::tag('a', $output, $attributes);
-
- // Now, finally the span.
- return \html_writer::tag('span', $output, array('class' => 'helptooltip'));
- }
-}
public function __construct($uniqueid, \moodle_url $url, $courseid = 0, $perpage = 100) {
parent::__construct($uniqueid);
+ $this->set_attribute('id', 'toolmonitorrules_table');
$this->set_attribute('class', 'toolmonitor managerules generaltable generalbox');
- $this->define_columns(array('name', 'description', 'plugin', 'eventname', 'filters', 'manage'));
+ $this->define_columns(array('name', 'description', 'course', 'plugin', 'eventname', 'filters', 'manage'));
$this->define_headers(array(
- get_string('name'),
+ get_string('rulename', 'tool_monitor'),
get_string('description'),
- get_string('plugin'),
- get_string('eventname'),
+ get_string('course'),
+ get_string('area', 'tool_monitor'),
+ get_string('event', 'tool_monitor'),
get_string('frequency', 'tool_monitor'),
get_string('manage', 'tool_monitor'),
)
* Generate content for name column.
*
* @param \tool_monitor\rule $rule rule object
- *
* @return string html used to display the column field.
*/
public function col_name(\tool_monitor\rule $rule) {
* Generate content for description column.
*
* @param \tool_monitor\rule $rule rule object
- *
* @return string html used to display the column field.
*/
public function col_description(\tool_monitor\rule $rule) {
}
/**
- * Generate content for plugin column.
+ * Generate content for course column.
*
* @param \tool_monitor\rule $rule rule object
+ * @return string html used to display the context column field.
+ */
+ public function col_course(\tool_monitor\rule $rule) {
+ $coursename = $rule->get_course_name($this->context);
+
+ $courseid = $rule->courseid;
+ if (empty($courseid)) {
+ return $coursename;
+ } else {
+ return \html_writer::link(new \moodle_url('/course/view.php', array('id' => $this->courseid)), $coursename);
+ }
+ }
+
+ /**
+ * Generate content for plugin column.
*
+ * @param \tool_monitor\rule $rule rule object
* @return string html used to display the column field.
*/
public function col_plugin(\tool_monitor\rule $rule) {
* Generate content for eventname column.
*
* @param \tool_monitor\rule $rule rule object
- *
* @return string html used to display the column field.
*/
public function col_eventname(\tool_monitor\rule $rule) {
* Generate content for filters column.
*
* @param \tool_monitor\rule $rule rule object
- *
* @return string html used to display the filters column field.
*/
public function col_filters(\tool_monitor\rule $rule) {
* Generate content for manage column.
*
* @param \tool_monitor\rule $rule rule object
- *
* @return string html used to display the manage column field.
*/
public function col_manage(\tool_monitor\rule $rule) {
$manage = '';
// We don't need to check for capability at course level since, user is never shown this page,
// if he doesn't have the capability.
- if ($this->hassystemcap || ($rule->courseid !== 0)) {
+ if ($this->hassystemcap || ($rule->courseid != 0)) {
// There might be site rules which the user can not manage.
$editurl = new \moodle_url($CFG->wwwroot. '/admin/tool/monitor/edit.php', array('ruleid' => $rule->id,
'courseid' => $rule->courseid, 'sesskey' => sesskey()));
$icon = $OUTPUT->render(new \pix_icon('t/copy', get_string('duplicaterule', 'tool_monitor')));
$manage .= \html_writer::link($copyurl, $icon, array('class' => 'action-icon'));
- $a = $rule->get_name($this->context);
- $action = new \component_action('click', 'M.util.show_confirm_dialog', array('message' => get_string('ruleareyousure',
- 'tool_monitor', $a)));
- $icon = $OUTPUT->action_link($deleteurl, new \pix_icon('t/delete', get_string('deleterule', 'tool_monitor')), $action);
- $manage .= $icon;
+ $icon = $OUTPUT->render(new \pix_icon('t/delete', get_string('deleterule', 'tool_monitor')));
+ $manage .= \html_writer::link($deleteurl, $icon, array('class' => 'action-icon'));
} else {
- $manage = '-';
+ $manage = get_string('nopermission', 'tool_monitor');
}
return $manage;
}
}
/**
- * Html to add a button for adding a new rul.
+ * Html to add a button for adding a new rule.
*
* @param int $courseid course id.
*
$addurl = new \moodle_url($CFG->wwwroot. '/admin/tool/monitor/edit.php', array('courseid' => $courseid));
return \html_writer::link($addurl, $button);
}
+
+ /**
+ * Html to add a link to go to the subscription page.
+ *
+ * @param moodle_url $manageurl The url of the subscription page.
+ *
+ * @return string html for the link to the subscription page.
+ */
+ public function render_subscriptions_link($manageurl) {
+ echo \html_writer::start_div();
+ $a = \html_writer::link($manageurl, get_string('managesubscriptions', 'tool_monitor'));
+ $link = \html_writer::tag('span', get_string('managesubscriptionslink', 'tool_monitor', $a));
+ echo $link;
+ echo \html_writer::end_div();
+ }
}
* @return string to display on the mangesubs page.
*/
protected function render_course_select(rules $renderable) {
- $select = $renderable->get_user_courses_select();
- return $this->render($select);;
+ if ($select = $renderable->get_user_courses_select()) {
+ return $this->render($select);
+ }
}
/**
return $o;
}
+
+ /**
+ * Html to add a link to go to the rule manager page.
+ *
+ * @param moodle_url $ruleurl The url of the rule manager page.
+ *
+ * @return string html for the link to the rule manager page.
+ */
+ public function render_rules_link($ruleurl) {
+ echo \html_writer::start_div();
+ $a = \html_writer::link($ruleurl, get_string('managerules', 'tool_monitor'));
+ $link = \html_writer::tag('span', get_string('manageruleslink', 'tool_monitor', $a));
+ echo $link;
+ echo \html_writer::end_div();
+ }
}
*/
protected $context;
- /**
- * @var \tool_monitor\output\helpicon\renderer the help icon renderer.
- */
- protected $helpiconrenderer;
-
/**
* Sets up the table_log parameters.
*
* @param int $perpage Number of rules to display per page.
*/
public function __construct($uniqueid, \moodle_url $url, $courseid = 0, $perpage = 100) {
- global $PAGE;
-
parent::__construct($uniqueid);
$this->set_attribute('class', 'toolmonitor subscriberules generaltable generalbox');
- $this->define_columns(array('name', 'description', 'select'));
+ $this->define_columns(array('name', 'description', 'course', 'plugin', 'eventname', 'filters', 'select'));
$this->define_headers(array(
- get_string('name'),
+ get_string('rulename', 'tool_monitor'),
get_string('description'),
- get_string('select')
+ get_string('course'),
+ get_string('area', 'tool_monitor'),
+ get_string('event', 'tool_monitor'),
+ get_string('frequency', 'tool_monitor'),
+ ''
)
);
$this->courseid = $courseid;
$this->pageable(true);
$this->is_downloadable(false);
$this->define_baseurl($url);
- $this->helpiconrenderer = $PAGE->get_renderer('tool_monitor', 'helpicon');
$total = \tool_monitor\rule_manager::count_rules_by_courseid($this->courseid);
$this->totalcount = $total;
}
* Generate content for name column.
*
* @param \tool_monitor\rule $rule rule object
- *
- * @return string html used to display the column field.
+ * @return string html used to display the rule name.
*/
public function col_name(\tool_monitor\rule $rule) {
- $name = $rule->get_name($this->context);
- $helpicon = new \tool_monitor\output\helpicon\renderable('rule', $rule->id);
- $helpicon = $this->helpiconrenderer->render($helpicon);
-
- return $name . $helpicon;
+ return $rule->get_name($this->context);
}
/**
* Generate content for description column.
*
* @param \tool_monitor\rule $rule rule object
- *
- * @return string html used to display the column field.
+ * @return string html used to display the description.
*/
public function col_description(\tool_monitor\rule $rule) {
return $rule->get_description($this->context);
}
+ /**
+ * Generate content for course column.
+ *
+ * @param \tool_monitor\rule $rule rule object
+ * @return string html used to display the course name.
+ */
+ public function col_course(\tool_monitor\rule $rule) {
+ $coursename = $rule->get_course_name($this->context);
+
+ $courseid = $rule->courseid;
+ if (empty($courseid)) {
+ return $coursename;
+ } else {
+ return \html_writer::link(new \moodle_url('/course/view.php', array('id' => $this->courseid)), $coursename);
+ }
+ }
+
/**
* Generate content for plugin column.
*
* @param \tool_monitor\rule $rule rule object
+ * @return string html used to display the plugin name.
+ */
+ public function col_plugin(\tool_monitor\rule $rule) {
+ return $rule->get_plugin_name();
+ }
+
+ /**
+ * Generate content for eventname column.
*
- * @return string html used to display the column field.
+ * @param \tool_monitor\rule $rule rule object
+ * @return string html used to display the event name.
+ */
+ public function col_eventname(\tool_monitor\rule $rule) {
+ return $rule->get_event_name();
+ }
+
+ /**
+ * Generate content for filters column.
+ *
+ * @param \tool_monitor\rule $rule rule object
+ * @return string html used to display the filters.
+ */
+ public function col_filters(\tool_monitor\rule $rule) {
+ return $rule->get_filters_description();
+ }
+
+ /**
+ * Generate content for select column.
+ *
+ * @param \tool_monitor\rule $rule rule object
+ * @return string html used to display the select field.
*/
public function col_select(\tool_monitor\rule $rule) {
global $OUTPUT;
- $select = $rule->get_module_select($this->courseid);
- return is_object($select) ? $OUTPUT->render($select) : $select;
+
+ $options = $rule->get_subscribe_options($this->courseid);
+ $text = get_string('subscribeto', 'tool_monitor', $rule->get_name($this->context));
+
+ if ($options instanceof \single_select) {
+ $options->set_label($text, array('class' => 'accesshide'));
+ return $OUTPUT->render($options);
+ } else if ($options instanceof \moodle_url) {
+ // A \moodle_url to subscribe.
+ $icon = $OUTPUT->pix_icon('t/add', $text);
+ $link = new \action_link($options, $icon);
+ return $OUTPUT->render($link);
+ } else {
+ return $options;
+ }
}
/**
/**
* Gets a list of courses where the current user can subscribe to rules as a dropdown.
*
- * @return \single_select list of courses.
+ * @return \single_select|bool returns the list of courses, or false if the select box
+ * should not be displayed.
*/
public function get_user_courses_select() {
- $courses = get_user_capability_course('tool/monitor:subscribe', null, true, 'fullname');
+ global $DB;
+
+ // If the number of courses on the site exceed the maximum drop down limit do not display the select box.
+ $numcourses = $DB->count_records('course');
+ if ($numcourses > COURSE_MAX_COURSES_PER_DROPDOWN) {
+ return false;
+ }
+
$options = array(0 => get_string('site'));
- $systemcontext = \context_system::instance();
- foreach ($courses as $course) {
- $options[$course->id] = format_text($course->fullname, array('context' => $systemcontext));
+ if ($courses = get_user_capability_course('tool/monitor:subscribe', null, true, 'fullname')) {
+ foreach ($courses as $course) {
+ $options[$course->id] = format_string($course->fullname, true,
+ array('context' => \context_course::instance($course->id)));
+ }
}
$url = new \moodle_url('/admin/tool/monitor/index.php');
$select = new \single_select($url, 'courseid', $options, $this->courseid);
*/
protected $context;
- /**
- * @var \tool_monitor\output\helpicon\renderer the help icon renderer.
- */
- protected $helpiconrenderer;
-
/**
* Sets up the table_log parameters.
*
* @param int $perpage Number of rules to display per page.
*/
public function __construct($uniqueid, \moodle_url $url, $courseid = 0, $perpage = 100) {
- global $PAGE;
-
parent::__construct($uniqueid);
$this->set_attribute('class', 'toolmonitor subscriptions generaltable generalbox');
- $this->define_columns(array('name', 'course', 'instance', 'unsubscribe', 'editrule'));
+ $this->define_columns(array('name', 'description', 'course', 'plugin', 'eventname', 'filters', 'unsubscribe'));
$this->define_headers(array(
- get_string('name'),
+ get_string('rulename', 'tool_monitor'),
+ get_string('description'),
get_string('course'),
- get_string('moduleinstance', 'tool_monitor'),
- get_string('unsubscribe', 'tool_monitor'),
- get_string('editrule', 'tool_monitor')
+ get_string('area', 'tool_monitor'),
+ get_string('event', 'tool_monitor'),
+ get_string('frequency', 'tool_monitor'),
+ get_string('unsubscribe', 'tool_monitor')
)
);
$this->courseid = $courseid;
$this->pageable(true);
$this->is_downloadable(false);
$this->define_baseurl($url);
- $this->helpiconrenderer = $PAGE->get_renderer('tool_monitor', 'helpicon');
}
/**
* Generate content for name column.
*
* @param \tool_monitor\subscription $sub subscription object
- *
- * @return string html used to display the column field.
+ * @return string html used to display the rule name.
*/
public function col_name(\tool_monitor\subscription $sub) {
- $name = $sub->get_name($this->context);
- $helpicon = new \tool_monitor\output\helpicon\renderable('subscription', $sub->id);
- $helpicon = $this->helpiconrenderer->render($helpicon);
+ return $sub->get_name($this->context);
+ }
- return $name . $helpicon;
+ /**
+ * Generate content for description column.
+ *
+ * @param \tool_monitor\subscription $sub subscription object
+ * @return string html used to display the description.
+ */
+ public function col_description(\tool_monitor\subscription $sub) {
+ return $sub->get_description($this->context);
}
/**
* Generate content for course column.
*
* @param \tool_monitor\subscription $sub subscription object
- *
- * @return string html used to display the column field.
+ * @return string html used to display the course name.
*/
public function col_course(\tool_monitor\subscription $sub) {
- return $sub->get_course_name($this->context);
+ $coursename = $sub->get_course_name($this->context);
+
+ $courseid = $sub->courseid;
+ if (empty($courseid)) {
+ return $coursename;
+ } else {
+ return \html_writer::link(new \moodle_url('/course/view.php', array('id' => $this->courseid)), $coursename);
+ }
}
/**
- * Generate content for description column.
+ * Generate content for plugin column.
*
* @param \tool_monitor\subscription $sub subscription object
+ * @return string html used to display the plugin name.
+ */
+ public function col_plugin(\tool_monitor\subscription $sub) {
+ return $sub->get_plugin_name();
+ }
+
+ /**
+ * Generate content for eventname column.
*
- * @return string html used to display the column field.
+ * @param \tool_monitor\subscription $sub subscription object
+ * @return string html used to display the event name.
*/
- public function col_instance(\tool_monitor\subscription $sub) {
- return $sub->get_instance_name();
+ public function col_eventname(\tool_monitor\subscription $sub) {
+ return $sub->get_event_name();
}
/**
- * Generate content for manage column.
+ * Generate content for filters column.
*
* @param \tool_monitor\subscription $sub subscription object
+ * @return string html used to display the filters.
+ */
+ public function col_filters(\tool_monitor\subscription $sub) {
+ return $sub->get_filters_description();
+ }
+
+ /**
+ * Generate content for unsubscribe column.
*
- * @return string html used to display the column field.
+ * @param \tool_monitor\subscription $sub subscription object
+ * @return string html used to display the unsubscribe field.
*/
public function col_unsubscribe(\tool_monitor\subscription $sub) {
global $OUTPUT, $CFG;
- $a = $sub->get_name($this->context);
$deleteurl = new \moodle_url($CFG->wwwroot. '/admin/tool/monitor/index.php', array('subscriptionid' => $sub->id,
'action' => 'unsubscribe', 'courseid' => $this->courseid, 'sesskey' => sesskey()));
- $action = new \component_action('click', 'M.util.show_confirm_dialog', array('message' => get_string('subareyousure',
- 'tool_monitor', $a)));
- $icon = $OUTPUT->action_link($deleteurl,
- new \pix_icon('t/delete', get_string('deletesubscription', 'tool_monitor')), $action);
- return $icon;
- }
+ $icon = $OUTPUT->render(new \pix_icon('t/delete', get_string('deletesubscription', 'tool_monitor')));
- /**
- * Generate content for edit rule column.
- *
- * @param \tool_monitor\subscription $sub subscription object
- *
- * @return string html used to display the column field.
- */
- public function col_editrule(\tool_monitor\subscription $sub) {
- if ($sub->can_manage_rule()) {
- // User can manage rule.
- $editurl = new \moodle_url('/admin/tool/monitor/edit.php', array('ruleid' => $sub->ruleid,
- 'courseid' => $sub->rulecourseid));
- return \html_writer::link($editurl, get_string('editrule', 'tool_monitor'));
- }
- return '-';
+ return \html_writer::link($deleteurl, $icon, array('class' => 'action-icon'));
}
/**
}
/**
- * Generate a select drop down with list of possible modules for a given course and rule.
+ * Gets the rule subscribe options for a given course and rule.
+ *
+ * Could be a select drop down with a list of possible module
+ * instances or a single link to subscribe if the rule plugin
+ * is not a module.
*
* @param int $courseid course id
*
- * @return \single_select a single select object
+ * @return \single_select|\moodle_url|string
* @throws \coding_exception
*/
- public function get_module_select($courseid) {
+ public function get_subscribe_options($courseid) {
global $CFG;
- $options = array();
- if (strpos($this->plugin, 'mod_') === 0) {
- $options[0] = get_string('allmodules', 'tool_monitor');
+
+ $url = new \moodle_url($CFG->wwwroot. '/admin/tool/monitor/index.php', array(
+ 'courseid' => $courseid,
+ 'ruleid' => $this->id,
+ 'action' => 'subscribe',
+ 'sesskey' => sesskey()
+ ));
+
+ if (strpos($this->plugin, 'mod_') !== 0) {
+ return $url;
+
} else {
- $options[0] = get_string('allevents', 'tool_monitor');
- }
- if (strpos($this->plugin, 'mod_') === 0) {
+ // Single select when the plugin is an activity.
+ $options = array();
+ $options[0] = get_string('allmodules', 'tool_monitor');
+
if ($courseid == 0) {
// They need to be in a course to select module instance.
return get_string('selectcourse', 'tool_monitor');
}
+
// Let them select an instance.
$cms = get_fast_modinfo($courseid);
$instances = $cms->get_instances_of(str_replace('mod_', '', $this->plugin));
$options[$cminfo->id] = $cminfo->get_formatted_name();
}
}
+
+ return new \single_select($url, 'cmid', $options);
}
- $url = new \moodle_url($CFG->wwwroot. '/admin/tool/monitor/index.php', array('courseid' => $courseid, 'ruleid' => $this->id,
- 'action' => 'subscribe', 'sesskey' => sesskey()));
- return new \single_select($url, 'cmid', $options, '', $nothing = array('' => 'choosedots'));
}
/**
}
/**
- * Get properly formatted name of the rule associated.
+ * Get properly formatted name of the course associated.
*
* @param \context $context context where this name would be displayed.
+ * @return string The course fullname.
+ */
+ public function get_course_name($context) {
+ $courseid = $this->courseid;
+ if (empty($courseid)) {
+ return get_string('site');
+ } else {
+ $course = get_course($courseid);
+ return format_string($course->fullname, true, array('context' => $context));
+ }
+ }
+
+ /**
+ * Get properly formatted name of the rule associated.
*
+ * @param \context $context context where this name would be displayed.
* @return string Formatted name of the rule.
*/
public function get_name(\context $context) {
* Get properly formatted description of the rule associated.
*
* @param \context $context context where this description would be displayed.
- *
* @return string Formatted description of the rule.
*/
public function get_description(\context $context) {
$pluginlist = $this->_customdata['pluginlist'];
$rule = $this->_customdata['rule'];
$courseid = $this->_customdata['courseid'];
+ $subscriptioncount = $this->_customdata['subscriptioncount'];
// General section header.
$mform->addElement('header', 'general', get_string('general'));
);
// Name field.
- $mform->addElement('text', 'name', get_string('name', 'tool_monitor'), 'size="50"');
+ $mform->addElement('text', 'name', get_string('rulename', 'tool_monitor'), 'size="50"');
$mform->addRule('name', get_string('required'), 'required');
$mform->setType('name', PARAM_TEXT);
- $mform->addHelpButton('name', 'name', 'tool_monitor');
// Plugin field.
- $mform->addElement('select', 'plugin', get_string('selectplugin', 'tool_monitor'), $pluginlist);
+ $mform->addElement('select', 'plugin', get_string('areatomonitor', 'tool_monitor'), $pluginlist);
$mform->addRule('plugin', get_string('required'), 'required');
- $mform->addHelpButton('plugin', 'selectplugin', 'tool_monitor');
// Event field.
- $mform->addElement('select', 'eventname', get_string('selectevent', 'tool_monitor'), $eventlist);
+ $mform->addElement('select', 'eventname', get_string('event', 'tool_monitor'), $eventlist);
$mform->addRule('eventname', get_string('required'), 'required');
- $mform->addHelpButton('eventname', 'selectevent', 'tool_monitor');
+
+ // Freeze plugin and event fields for editing if there's a subscription for this rule.
+ if ($subscriptioncount > 0) {
+ $mform->freeze('plugin');
+ $mform->setConstant('plugin', $rule->plugin);
+ $mform->freeze('eventname');
+ $mform->setConstant('eventname', $rule->eventname);
+ }
// Description field.
- $mform->addElement('editor', 'description', get_string('description', 'tool_monitor'), $editoroptions);
- $mform->addHelpButton('description', 'description', 'tool_monitor');
+ $mform->addElement('editor', 'description', get_string('description'), $editoroptions);
// Filters.
- $mform->addElement('header', 'customisefilters', get_string('customisefilters', 'tool_monitor'));
$freq = array(1 => 1, 5 => 5, 10 => 10, 20 => 20, 30 => 30, 40 => 40, 50 => 50, 60 => 60, 70 => 70, 80 => 80, 90 => 90,
100 => 100, 1000 => 1000);
- $mform->addElement('select', 'frequency', get_string('selectfrequency', 'tool_monitor'), $freq);
+ $mform->addElement('select', 'frequency', get_string('frequency', 'tool_monitor'), $freq);
$mform->addRule('frequency', get_string('required'), 'required');
- $mform->addHelpButton('frequency', 'selectfrequency', 'tool_monitor');
+ $mform->addHelpButton('frequency', 'frequency', 'tool_monitor');
$mins = array(1 => 1, 5 => 5, 10 => 10, 15 => 15, 20 => 20, 25 => 25, 30 => 30, 35 => 35, 40 => 40, 45 => 45, 50 => 50,
55 => 55, 60 => 60);
- $mform->addElement('select', 'minutes', get_string('selectminutes', 'tool_monitor'), $mins);
+ $mform->addElement('select', 'minutes', get_string('inminutes', 'tool_monitor'), $mins);
$mform->addRule('minutes', get_string('required'), 'required');
// Message template.
- $mform->addElement('header', 'customisemessage', get_string('customisemessage', 'tool_monitor'));
$mform->addElement('editor', 'template', get_string('messagetemplate', 'tool_monitor'), $editoroptions);
- $mform->setDefault('template', get_string('defaultmessagetpl', 'tool_monitor'));
+ $mform->setDefault('template', get_string('defaultmessagetemplate', 'tool_monitor'));
$mform->addRule('template', get_string('required'), 'required');
$mform->addHelpButton('template', 'messagetemplate', 'tool_monitor');
// Action buttons.
- $this->add_action_buttons(false, get_string('savechanges'));
+ $this->add_action_buttons(true, get_string('savechanges'));
}
/**
$ruledata->timemodified = $now;
$ruledata->id = $DB->insert_record('tool_monitor_rules', $ruledata);
+
+ // Trigger a rule created event.
+ if ($ruledata->id) {
+ if (!empty($ruledata->courseid)) {
+ $courseid = $ruledata->courseid;
+ $context = \context_course::instance($ruledata->courseid);
+ } else {
+ $courseid = 0;
+ $context = \context_system::instance();
+ }
+
+ $params = array(
+ 'objectid' => $ruledata->id,
+ 'courseid' => $courseid,
+ 'context' => $context
+ );
+ $event = \tool_monitor\event\rule_created::create($params);
+ $event->trigger();
+ }
+
return new rule($ruledata);
}
* Delete a rule and associated subscriptions, by rule id.
*
* @param int $ruleid id of rule to be deleted.
+ * @param \context|null $coursecontext the context of the course - this is passed when we
+ * can not get the context via \context_course as the course has been deleted.
*
* @return bool
*/
- public static function delete_rule($ruleid) {
+ public static function delete_rule($ruleid, $coursecontext = null) {
global $DB;
- subscription_manager::remove_all_subscriptions_for_rule($ruleid);
- return $DB->delete_records('tool_monitor_rules', array('id' => $ruleid));
+ subscription_manager::remove_all_subscriptions_for_rule($ruleid, $coursecontext);
+
+ // Retrieve the rule from the DB before we delete it, so we have a record when we trigger a rule deleted event.
+ $rule = $DB->get_record('tool_monitor_rules', array('id' => $ruleid));
+
+ $success = $DB->delete_records('tool_monitor_rules', array('id' => $ruleid));
+
+ // If successful trigger a rule deleted event.
+ if ($success) {
+ // It is possible that we are deleting rules associated with a deleted course, so we should be
+ // passing the context as the second parameter.
+ if (!is_null($coursecontext)) {
+ $context = $coursecontext;
+ $courseid = $rule->courseid;
+ } else if (!empty($rule->courseid) && ($context = \context_course::instance($rule->courseid,
+ IGNORE_MISSING))) {
+ $courseid = $rule->courseid;
+ } else {
+ $courseid = 0;
+ $context = \context_system::instance();
+ }
+
+ $params = array(
+ 'objectid' => $rule->id,
+ 'courseid' => $courseid,
+ 'context' => $context
+ );
+ $event = \tool_monitor\event\rule_deleted::create($params);
+ $event->add_record_snapshot('tool_monitor_rules', $rule);
+ $event->trigger();
+ }
+
+ return $success;
}
/**
throw new \coding_exception('Invalid rule ID.');
}
$ruledata->timemodified = time();
- return $DB->update_record('tool_monitor_rules', $ruledata);
+
+ $success = $DB->update_record('tool_monitor_rules', $ruledata);
+
+ // If successful trigger a rule updated event.
+ if ($success) {
+ // If we do not have the course id we need to retrieve it.
+ if (!isset($ruledata->courseid)) {
+ $courseid = $DB->get_field('tool_monitor_rules', 'courseid', array('id' => $ruledata->id), MUST_EXIST);
+ } else {
+ $courseid = $ruledata->courseid;
+ }
+
+ if (!empty($courseid)) {
+ $context = \context_course::instance($courseid);
+ } else {
+ $context = \context_system::instance();
+ }
+
+ $params = array(
+ 'objectid' => $ruledata->id,
+ 'courseid' => $courseid,
+ 'context' => $context
+ );
+ $event = \tool_monitor\event\rule_updated::create($params);
+ $event->trigger();
+ }
+
+ return $success;
}
/**
* Get properly formatted name of the rule associated.
*
* @param \context $context context where this name would be displayed.
- *
* @return string Formatted name of the rule.
*/
public function get_name(\context $context) {
* Get properly formatted description of the rule associated.
*
* @param \context $context context where this description would be displayed.
- *
* @return string Formatted description of the rule.
*/
public function get_description(\context $context) {
* Get properly formatted name of the course associated.
*
* @param \context $context context where this name would be displayed.
- *
* @return string Formatted name of the rule.
*/
public function get_course_name(\context $context) {
- global $SITE;
$courseid = $this->courseid;
if (empty($courseid)) {
- $coursename = format_string($SITE->fullname, true, array('context' => $context));
+ return get_string('site');
} else {
- $course = get_course($this->courseid);
- $link = new \moodle_url('/course/view.php', array('id' => $course->id));
- $coursename = format_string($course->fullname, true, array('context' => $context));
- $coursename = \html_writer::link($link, $coursename);
+ $course = get_course($courseid);
+ return format_string($course->fullname, true, array('context' => $context));
}
- return $coursename;
}
/**
}
$subscription->timecreated = time();
- return $DB->insert_record('tool_monitor_subscriptions', $subscription);
+ $subscription->id = $DB->insert_record('tool_monitor_subscriptions', $subscription);
+
+ // Trigger a subscription created event.
+ if ($subscription->id) {
+ if (!empty($subscription->courseid)) {
+ $courseid = $subscription->courseid;
+ $context = \context_course::instance($subscription->courseid);
+ } else {
+ $courseid = 0;
+ $context = \context_system::instance();
+ }
+
+ $params = array(
+ 'objectid' => $subscription->id,
+ 'courseid' => $courseid,
+ 'context' => $context
+ );
+ $event = \tool_monitor\event\subscription_created::create($params);
+ $event->trigger();
+ }
+
+ return $subscription->id;
}
/**
if ($checkuser && $subscription->userid != $USER->id) {
throw new \coding_exception('Invalid subscription supplied');
}
- return $DB->delete_records('tool_monitor_subscriptions', array('id' => $subscription->id));
+
+ // Store the subscription before we delete it.
+ $subscription = $DB->get_record('tool_monitor_subscriptions', array('id' => $subscription->id));
+
+ $success = $DB->delete_records('tool_monitor_subscriptions', array('id' => $subscription->id));
+
+ // If successful trigger a subscription_deleted event.
+ if ($success) {
+ if (!empty($subscription->courseid)) {
+ $courseid = $subscription->courseid;
+ $context = \context_course::instance($subscription->courseid);
+ } else {
+ $courseid = 0;
+ $context = \context_system::instance();
+ }
+
+ $params = array(
+ 'objectid' => $subscription->id,
+ 'courseid' => $courseid,
+ 'context' => $context
+ );
+ $event = \tool_monitor\event\subscription_deleted::create($params);
+ $event->add_record_snapshot('tool_monitor_subscriptions', $subscription);
+ $event->trigger();
+ }
+
+ return $success;
}
/**
* Delete all subscribers for a given rule.
*
* @param int $ruleid rule id.
+ * @param \context|null $coursecontext the context of the course - this is passed when we
+ * can not get the context via \context_course as the course has been deleted.
*
* @return bool
*/
- public static function remove_all_subscriptions_for_rule($ruleid) {
+ public static function remove_all_subscriptions_for_rule($ruleid, $coursecontext = null) {
global $DB;
- return $DB->delete_records('tool_monitor_subscriptions', array('ruleid' => $ruleid));
+
+ // Store all the subscriptions we have to delete.
+ $subscriptions = $DB->get_recordset('tool_monitor_subscriptions', array('ruleid' => $ruleid));
+
+ // Now delete them.
+ $success = $DB->delete_records('tool_monitor_subscriptions', array('ruleid' => $ruleid));
+
+ // If successful and there were subscriptions that were deleted trigger a subscription deleted event.
+ if ($success && $subscriptions) {
+ foreach ($subscriptions as $subscription) {
+ // It is possible that we are deleting rules associated with a deleted course, so we should be
+ // passing the context as the second parameter.
+ if (!is_null($coursecontext)) {
+ $context = $coursecontext;
+ $courseid = $subscription->courseid;
+ } else if (!empty($subscription->courseid) && ($coursecontext =
+ \context_course::instance($subscription->courseid, IGNORE_MISSING))) {
+ $courseid = $subscription->courseid;
+ $context = $coursecontext;
+ } else {
+ $courseid = 0;
+ $context = \context_system::instance();
+ }
+
+ $params = array(
+ 'objectid' => $subscription->id,
+ 'courseid' => $courseid,
+ 'context' => $context
+ );
+ $event = \tool_monitor\event\subscription_deleted::create($params);
+ $event->add_record_snapshot('tool_monitor_subscriptions', $subscription);
+ $event->trigger();
+ }
+ }
+
+ $subscriptions->close();
+
+ return $success;
}
/**
}
return $result;
}
+
+ /**
+ * Get count of subscriptions for a given rule.
+ *
+ * @param int $ruleid rule id of the subscription.
+ *
+ * @return int number of subscriptions
+ */
+ public static function count_rule_subscriptions($ruleid) {
+ global $DB;
+ $sql = self::get_subscription_join_rule_sql(true);
+ $sql .= "WHERE s.ruleid = :ruleid";
+
+ return $DB->count_records_sql($sql, array('ruleid' => $ruleid));
+ }
}
--- /dev/null
+<?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');
+ }
+ }
+}
<?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="tool/monitor/db" VERSION="20140708" COMMENT="XMLDB file for Moodle tool/monitor"
+<XMLDB PATH="tool/monitor/db" VERSION="20141103" COMMENT="XMLDB file for Moodle tool/monitor"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
<FIELD NAME="cmid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Course module id"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="User id of the subscriber"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Timestamp of when this subscription was created"/>
+ <FIELD NAME="lastnotificationsent" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Timestamp of the time when a notification was last sent for this subscription."/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
--- /dev/null
+<?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' => '*'
+ )
+);
--- /dev/null
+<?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/>.
+
+/**
+ * Upgrade scirpt for tool_monitor.
+ *
+ * @package tool_monitor
+ * @copyright 2014 onwards Ankit Agarwal <ankit.agrr@gmail.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Upgrade the plugin.
+ *
+ * @param int $oldversion
+ * @return bool always true
+ */
+function xmldb_tool_monitor_upgrade($oldversion) {
+ global $DB;
+
+ $dbman = $DB->get_manager();
+
+ if ($oldversion < 2014102000) {
+
+ // Define field lastnotificationsent to be added to tool_monitor_subscriptions.
+ $table = new xmldb_table('tool_monitor_subscriptions');
+ $field = new xmldb_field('lastnotificationsent', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'timecreated');
+
+ // Conditionally launch add field lastnotificationsent.
+ if (!$dbman->field_exists($table, $field)) {
+ $dbman->add_field($table, $field);
+ }
+
+ // Monitor savepoint reached.
+ upgrade_plugin_savepoint(true, 2014102000, 'tool', 'monitor');
+ }
+
+ return true;
+}
require_capability('tool/monitor:managerules', $context);
// Set up the page.
-$a = new stdClass();
-$a->coursename = $coursename;
-$a->reportname = get_string('pluginname', 'tool_monitor');
-$title = get_string('title', 'tool_monitor', $a);
$url = new moodle_url("/admin/tool/monitor/edit.php", array('courseid' => $courseid, 'ruleid' => $ruleid));
$manageurl = new moodle_url("/admin/tool/monitor/managerules.php", array('courseid' => $courseid));
-
$PAGE->set_url($url);
$PAGE->set_pagelayout('report');
-$PAGE->set_title($title);
-$PAGE->set_heading($title);
+$PAGE->set_title($coursename);
+$PAGE->set_heading($coursename);
// Get data ready for mform.
$eventlist = tool_monitor\eventlist::get_all_eventlist(true);
if (!empty($ruleid)) {
$rule = \tool_monitor\rule_manager::get_rule($ruleid)->get_mform_set_data();
$rule->minutes = $rule->timewindow / MINSECS;
+ $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));
+ '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);
} 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)) {
+ echo $OUTPUT->heading(get_string('editrule', 'tool_monitor'));
+} else {
+ echo $OUTPUT->heading(get_string('addrule', 'tool_monitor'));
+}
+$mform->set_data($rule);
+$mform->display();
+echo $OUTPUT->footer();
+++ /dev/null
-<?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/>.
-
-/**
- * Displays help on a new page.
- *
- * @copyright 2014 Mark Nelson <markn@moodle.com>
- * @package tool_monitor
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-define('NO_MOODLE_COOKIES', 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.php');
-$PAGE->set_pagelayout('popup');
-
-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());
-}
-
-// Get the help string data.
-$data = tool_monitor\output\helpicon\renderable::get_help_string_parameters($type, $id);
-
-echo $OUTPUT->header();
-if (!empty($data->heading)) {
- echo $OUTPUT->heading($data->heading, 1, 'helpheading');
-}
-echo $data->text;
-if (isset($data->completedoclink)) {
- echo $data->completedoclink;
-}
-echo $OUTPUT->footer();
+++ /dev/null
-<?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/>.
-
-/**
- * Displays help via AJAX call.
- *
- * @copyright 2014 Mark Nelson <markn@moodle.com>
- * @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));
$cmid = optional_param('cmid', 0, PARAM_INT);
$ruleid = optional_param('ruleid', 0, PARAM_INT);
$subscriptionid = optional_param('subscriptionid', 0, PARAM_INT);
+$confirm = optional_param('confirm', false, PARAM_BOOL);
// Validate course id.
if (empty($courseid)) {
$PAGE->set_context($context);
// Set up the page.
-$a = new stdClass();
-$a->coursename = $sitename;
-$a->reportname = get_string('pluginname', 'tool_monitor');
-$title = get_string('title', 'tool_monitor', $a);
-$indexurl = new moodle_url("/admin/tool/monitor/index.php", array('courseid' => $courseid));
-
+$indexurl = new moodle_url('/admin/tool/monitor/index.php', array('courseid' => $courseid));
$PAGE->set_url($indexurl);
$PAGE->set_pagelayout('report');
-$PAGE->set_title($title);
-$PAGE->set_heading($title);
-
-echo $OUTPUT->header();
+$PAGE->set_title($sitename);
+$PAGE->set_heading($sitename);
// Create/delete subscription if needed.
if (!empty($action)) {
case 'subscribe' :
$rule = \tool_monitor\rule_manager::get_rule($ruleid);
$rule->subscribe_user($courseid, $cmid);
+ echo $OUTPUT->header();
echo $OUTPUT->notification(get_string('subcreatesuccess', 'tool_monitor'), 'notifysuccess');
break;
case 'unsubscribe' :
- \tool_monitor\subscription_manager::delete_subscription($subscriptionid);
- echo $OUTPUT->notification(get_string('subdeletesuccess', 'tool_monitor'), 'notifysuccess');
+ // If the subscription does not exist, then redirect back as the subscription must have already been deleted.
+ if (!$subscription = $DB->record_exists('tool_monitor_subscriptions', array('id' => $subscriptionid))) {
+ redirect(new moodle_url('/admin/tool/monitor/index.php', array('courseid' => $courseid)));
+ }
+
+ // Set the URLs.
+ $confirmurl = new moodle_url('/admin/tool/monitor/index.php', array('subscriptionid' => $subscriptionid,
+ 'courseid' => $courseid, 'action' => 'unsubscribe', 'confirm' => true,
+ 'sesskey' => sesskey()));
+ $cancelurl = new moodle_url('/admin/tool/monitor/index.php', array('subscriptionid' => $subscriptionid,
+ 'courseid' => $courseid, 'sesskey' => sesskey()));
+ if ($confirm) {
+ \tool_monitor\subscription_manager::delete_subscription($subscriptionid);
+ echo $OUTPUT->header();
+ echo $OUTPUT->notification(get_string('subdeletesuccess', 'tool_monitor'), 'notifysuccess');
+ } else {
+ $subscription = \tool_monitor\subscription_manager::get_subscription($subscriptionid);
+ echo $OUTPUT->header();
+ echo $OUTPUT->confirm(get_string('subareyousure', 'tool_monitor', $subscription->get_name($context)),
+ $confirmurl, $cancelurl);
+ echo $OUTPUT->footer();
+ exit();
+ }
break;
default:
}
+} else {
+ echo $OUTPUT->header();
}
// Render the current subscriptions list.
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'));
+ echo $OUTPUT->heading(get_string('currentsubscriptions', 'tool_monitor'), 3);
echo $renderer->render($subs);
}
// Render the potential rules list.
$totalrules = \tool_monitor\rule_manager::count_rules_by_courseid($courseid);
-echo $OUTPUT->heading(get_string('rulescansubscribe', 'tool_monitor'));
+echo $OUTPUT->heading(get_string('rulescansubscribe', 'tool_monitor'), 3);
$rules = new \tool_monitor\output\managesubs\rules('toolmonitorrules', $indexurl, $courseid);
echo $renderer->render($rules);
+
+// Check if the user can manage the course rules we are viewing.
+if (empty($courseid)) {
+ $canmanagerules = has_capability('tool/monitor:managerules', $context);
+} else {
+ $canmanagerules = has_capability('tool/monitor:managerules', $coursecontext);
+}
if (empty($totalrules)) {
// No rules present. Show a link to manage rules page if permissions permit.
echo html_writer::start_div();
echo html_writer::tag('span', get_string('norules', 'tool_monitor'));
- if (has_capability('tool/monitor:managerules', $context)) {
+ if ($canmanagerules) {
$manageurl = new moodle_url("/admin/tool/monitor/managerules.php", array('courseid' => $courseid));
$a = html_writer::link($manageurl, get_string('managerules', 'tool_monitor'));
$link = " ";
echo $link;
}
echo html_writer::end_div();
+} else if ($canmanagerules) {
+ $manageurl = new moodle_url("/admin/tool/monitor/managerules.php", array('courseid' => $courseid));
+ echo $renderer->render_rules_link($manageurl);
}
echo $OUTPUT->footer();
$string['addrule'] = 'Add a new rule';
$string['allevents'] = 'All events';
-$string['allmodules'] = 'All modules';
+$string['allmodules'] = 'All instances';
+$string['area'] = 'Area';
+$string['areatomonitor'] = 'Area to monitor';
$string['core'] = 'Core';
-$string['customisefilters'] = 'Select the frequency of the events';
-$string['customisemessage'] = 'Customise the notification message';
$string['currentsubscriptions'] = 'Your current subscriptions';
-$string['description_help'] = "Description is displayed to users when they want to subscribe to this rule. This helps them understand what the rule is about.";
-$string['defaultmessagetpl'] = 'Rule "{rulename}" has happened. You can find further details at {link}';
+$string['defaultmessagetemplate'] = 'The rule "{rulename}" you have subscribed to has occurred - please find further details at {link}';
$string['deleterule'] = 'Delete rule';
$string['deletesubscription'] = 'Delete subscription';
$string['description'] = 'Description:';
+$string['disablefieldswarning'] = 'Plugin and events fields can not be edited because this rule already has subscriptions.';
$string['duplicaterule'] = 'Duplicate rule';
$string['editrule'] = 'Edit rule';
+$string['event'] = 'Event';
$string['eventnotfound'] = 'Event not found';
+$string['eventrulecreated'] = 'Rule created';
+$string['eventruledeleted'] = 'Rule deleted';
+$string['eventruleupdated'] = 'Rule updated';
+$string['eventsubcreated'] = 'Subscription created';
+$string['eventsubcriteriamet'] = 'Subscription criteria met';
+$string['eventsubdeleted'] = 'Subscription deleted';
$string['errorincorrectevent'] = 'Please select an event related to the selected plugin';
-$string['freqdesc'] = '{$a->freq} times in {$a->mins} minutes';
-$string['frequency'] = 'Frequency';
+$string['freqdesc'] = '{$a->freq} time(s) in {$a->mins} minute(s)';
+$string['frequency'] = 'Notification threshold';
+$string['frequency_help'] = 'The number of events within a specified time period required for a notification message to be sent.';
+$string['inminutes'] = 'in minutes';
$string['invalidmodule'] = 'Invalid module';
-$string['norules'] = 'There are no rules you can subscribe to.';
-$string['manageruleslink'] = 'You can manage rules from {$a} page.';
-$string['moduleinstance'] = 'Module instance';
+$string['manageruleslink'] = 'You can manage rules from the {$a} page.';
+$string['managesubscriptionslink'] = 'You can subscribe to rules from the {$a} page.';
$string['manage'] = 'Manage';
$string['managesubscriptions'] = 'Event monitoring';
$string['managerules'] = 'Event monitoring rules';
-$string['messageheader'] = 'Customise your notification message';
$string['messageprovider:notification'] = 'Notifications of rule subscriptions';
-$string['messagetemplate'] = 'Message template';
-$string['messagetemplate_help'] = 'This is the content of the message that will be sent to users, when the given conditions of the rule are met. You are allowed to use following templates in this.
-<br /> {link} - Link to the location where the event happened.
-<br /> {modulelink} - Link to the module where the event has happened.
-<br /> {rulename} - Name of this rule.
-<br /> {description} - Rule description.
-<br /> {eventname} - Name of the event associated with the rule.';
-$string['minutes'] = 'in minutes:';
-$string['name'] = 'Name of the rule: ';
-$string['name_help'] = "Choose a name for the rule.";
+$string['nopermission'] = 'No permission';
+$string['messagetemplate'] = 'Notification message';
+$string['messagetemplate_help'] = 'A notification message is sent to subscribers once the notification threshold has been reached. It can include any or all of the following placeholders:
+<br /><br />
+* Link to the location of the event {link}<br />
+* Link to the area monitored {modulelink}<br />
+* Rule name {rulename}<br />
+* Description {description}<br />
+* Event {eventname}';
+$string['monitor:managerules'] = 'Manage event monitor rules';
+$string['monitor:subscribe'] = 'Subscribe to event monitor rules';
+$string['norules'] = 'There are no event monitoring rules.';
$string['pluginname'] = 'Event monitor';
$string['processevents'] = 'Process events';
+$string['rulename'] = 'Rule name';
$string['ruleareyousure'] = 'Are you sure you want to delete rule "{$a}"?';
$string['rulecopysuccess'] = 'Rule successfully duplicated';
$string['ruledeletesuccess'] = 'Rule successfully deleted';
$string['rulescansubscribe'] = 'Rules you can subscribe to';
$string['selectacourse'] = 'Select a course';
$string['selectcourse'] = 'Visit this report at course level to get a list of possible modules';
-$string['selectevent'] = 'Select an event:';
-$string['selectevent_help'] = "Select an event to monitor. Please note that some events are only triggered for the entire site (e.g. 'course created') and will never trigger when subscribed to from within a course.";
-$string['selectfrequency'] = 'Frequency of events:';
-$string['selectfrequency_help'] = "Frequency defines the denisty of the event occurrence. Select criterias to define how frequently the event should happen to trigger the notification.";
-$string['selectminutes'] = 'in minutes:';
-$string['selectplugin'] = 'Select the plugin type:';
-$string['selectplugin_help'] = "Select a plugin that you are interested in monitoring. The event list below would be updated to display events from the selected plugin.";
$string['subareyousure'] = 'Are you sure you want to delete this subscription for the rule "{$a}"?';
$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['title'] = '{$a->coursename} : {$a->reportname}';
-$string['monitor:managerules'] = 'Manage event monitor rules';
-$string['monitor:subscribe'] = 'Subscribe to event monitor rules';
+$string['subscribeto'] = 'Subscribe to rule "{$a}"';
+$string['taskcleanevents'] = 'Removes any unnecessary event monitor events';
$string['unsubscribe'] = 'Unsubscribe';
*/
function tool_monitor_extend_navigation_user_settings($navigation, $user, $usercontext, $course, $coursecontext) {
global $USER;
- if (($USER->id == $user->id)) {
+ if (($USER->id == $user->id) && (has_capability('tool/monitor:subscribe', $coursecontext))) {
$url = new moodle_url('/admin/tool/monitor/index.php', array('courseid' => $course->id));
$subsnode = navigation_node::create(get_string('managesubscriptions', 'tool_monitor'), $url,
navigation_node::TYPE_SETTING, null, null, new pix_icon('i/settings', ''));
$courseid = optional_param('courseid', 0, PARAM_INT);
$ruleid = optional_param('ruleid', 0, PARAM_INT);
$action = optional_param('action', '', PARAM_ALPHA);
+$confirm = optional_param('confirm', false, PARAM_BOOL);
// Validate course id.
if (empty($courseid)) {
require_capability('tool/monitor:managerules', $context);
// Set up the page.
-$a = new stdClass();
-$a->coursename = $coursename;
-$a->reportname = get_string('pluginname', 'tool_monitor');
-$title = get_string('title', 'tool_monitor', $a);
$manageurl = new moodle_url("/admin/tool/monitor/managerules.php", array('courseid' => $courseid));
-
$PAGE->set_url($manageurl);
$PAGE->set_pagelayout('report');
-$PAGE->set_title($title);
-$PAGE->set_heading($title);
+$PAGE->set_title($coursename);
+$PAGE->set_heading($coursename);
// Site level report.
if (empty($courseid)) {
admin_externalpage_setup('toolmonitorrules', '', null, '', array('pagelayout' => 'report'));
}
-echo $OUTPUT->header();
-
// Copy/delete rule if needed.
if (!empty($action) && $ruleid) {
require_sesskey();
- $rule = \tool_monitor\rule_manager::get_rule($ruleid);
+
+ // 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);
if ($rule->can_manage_rule()) {
switch ($action) {
case 'copy' :
echo $OUTPUT->notification(get_string('rulecopysuccess', 'tool_monitor'), 'notifysuccess');
break;
case 'delete' :
- $rule->delete_rule();
- echo $OUTPUT->notification(get_string('ruledeletesuccess', 'tool_monitor'), 'notifysuccess');
+ $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 {
+ echo $OUTPUT->confirm(get_string('ruleareyousure', 'tool_monitor', $rule->get_name($context)),
+ $confirmurl, $cancelurl);
+ echo $OUTPUT->footer();
+ exit();
+ }
break;
default:
}
// User doesn't have permissions. Should never happen for real users.
throw new moodle_exception('rulenopermissions', 'tool_monitor', $manageurl, $action);
}
+} else {
+ echo $OUTPUT->header();
}
+echo $OUTPUT->heading(get_string('managerules', 'tool_monitor'));
+
// Render the rule list.
$renderable = new \tool_monitor\output\managerules\renderable('toolmonitorrules', $manageurl, $courseid);
$renderer = $PAGE->get_renderer('tool_monitor', 'managerules');
echo $renderer->render($renderable);
+if (has_capability('tool/monitor:subscribe', $context)) {
+ $manageurl = new moodle_url("/admin/tool/monitor/index.php", array('courseid' => $courseid));
+ echo $renderer->render_subscriptions_link($manageurl);
+}
echo $OUTPUT->footer();
*/
defined('MOODLE_INTERNAL') || die;
-if ($hassiteconfig) {
-
- // Manage rules page.
- $url = new moodle_url('/admin/tool/monitor/managerules.php', array('courseid' => 0));
- $temp = new admin_externalpage('toolmonitorrules', get_string('managerules', 'tool_monitor'), $url,
- 'tool/monitor:managerules');
- $ADMIN->add('reports', $temp);
-}
+// Manage rules page.
+$temp = new admin_externalpage(
+ 'toolmonitorrules',
+ get_string('managerules', 'tool_monitor'),
+ new moodle_url('/admin/tool/monitor/managerules.php', array('courseid' => 0)),
+ 'tool/monitor:managerules'
+);
+$ADMIN->add('reports', $temp);
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
- And I log in as "admin"
- And I follow "Course 1"
- And I navigate to "Event monitoring rules" node in "Course administration > Reports"
- And I press "Add a new rule"
- And I set the following fields to these values:
- | name | New rule course level |
- | plugin | Forum |
- | eventname | Post created |
- | id_description | I want a rule to monitor posts created on a forum |
- | frequency | 1 |
- | minutes | 1 |
- | Message template | The forum post was created. {modulelink} |
- And I press "Save changes"
- And I navigate to "Event monitoring rules" node in "Site administration > Reports"
- And I press "Add a new rule"
- And I set the following fields to these values:
- | name | New rule site level |
- | plugin | Forum |
- | eventname | Post created |
- | id_description | I want a rule to monitor posts created on a forum |
- | frequency | 1 |
- | minutes | 1 |
- | Message template | The forum post was created. {modulelink} |
- And I press "Save changes"
- And I log out
+ And I log in as "admin"
+ And I follow "Course 1"
+ And I navigate to "Event monitoring rules" node in "Course administration > Reports"
+ And I press "Add a new rule"
+ And I set the following fields to these values:
+ | name | New rule course level |
+ | plugin | Forum |
+ | eventname | Post created |
+ | id_description | I want a rule to monitor posts created on a forum |
+ | frequency | 1 |
+ | minutes | 1 |
+ | Notification message | The forum post was created. {modulelink} |
+ And I press "Save changes"
+ And I navigate to "Event monitoring rules" node in "Site administration > Reports"
+ And I press "Add a new rule"
+ And I set the following fields to these values:
+ | name | New rule site level |
+ | plugin | Forum |
+ | eventname | Post created |
+ | id_description | I want a rule to monitor posts created on a forum |
+ | frequency | 1 |
+ | minutes | 1 |
+ | Notification message | The forum post was created. {modulelink} |
+ And I press "Save changes"
+ And I log out
Scenario: Add a rule on course level
Given I log in as "teacher1"
- And I am on homepage
- And I follow "Course 1"
- And I navigate to "Event monitoring rules" node in "Course administration > Reports"
- When I press "Add a new rule"
- And I set the following fields to these values:
- | name | New rule |
- | plugin | Forum |
- | eventname | Post created |
- | id_description | I want a rule to monitor posts created on a forum |
- | frequency | 1 |
- | minutes | 1 |
- | Message template | The forum post was created. {modulelink} |
- And I press "Save changes"
- Then I should see "New rule"
- And I should see "I want a rule to monitor posts created on a forum"
- And I should see "Forum"
- And I should see "Post created"
- And I should see "1 times in 1 minutes"
+ And I am on homepage
+ And I follow "Course 1"
+ And I navigate to "Event monitoring rules" node in "Course administration > Reports"
+ When I press "Add a new rule"
+ And I set the following fields to these values:
+ | name | New rule |
+ | plugin | Forum |
+ | eventname | Post created |
+ | id_description | I want a rule to monitor posts created on a forum |
+ | frequency | 1 |
+ | minutes | 1 |
+ | Notification message | The forum post was created. {modulelink} |
+ And I press "Save changes"
+ Then "New rule" row "Course" column of "toolmonitorrules_table" table should contain "Course 1"
+ And I should see "I want a rule to monitor posts created on a forum"
+ And I should see "Forum"
+ And I should see "Post created"
+ And I should see "1 time(s) in 1 minute(s)"
Scenario: Delete a rule on course level
Given I log in as "teacher1"
- And I follow "Course 1"
- And I navigate to "Event monitoring rules" node in "Course administration > Reports"
- When I click on "Delete rule" "link"
- Then I should see "Are you sure you want to delete rule \"New rule course level\"?"
- And I press "Yes"
- And I should see "Rule successfully deleted"
- And I should not see "New rule course level"
+ And I follow "Course 1"
+ And I navigate to "Event monitoring rules" node in "Course administration > Reports"
+ When I click on "Delete rule" "link"
+ Then I should see "Are you sure you want to delete rule \"New rule course level\"?"
+ And I press "Continue"
+ And I should see "Rule successfully deleted"
+ And I should not see "New rule course level"
Scenario: Edit a rule on course level
Given I log in as "teacher1"
- And I follow "Course 1"
- And I navigate to "Event monitoring rules" node in "Course administration > Reports"
- When I click on "Edit rule" "link"
- And I set the following fields to these values:
- | name | New rule quiz |
- | plugin | Quiz |
- | eventname | Quiz attempt deleted |
- | id_description | I want a rule to monitor quiz attempts deleted |
- | frequency | 5 |
- | minutes | 5 |
- | Message template | Quiz attempt deleted. {modulelink} |
- And I press "Save changes"
- Then I should see "New rule quiz"
- And I should see "I want a rule to monitor quiz attempts deleted"
- And I should see "Quiz attempt deleted"
- And I should see "5 times in 5 minutes"
+ And I follow "Course 1"
+ And I navigate to "Event monitoring rules" node in "Course administration > Reports"
+ When I click on "Edit rule" "link"
+ And I set the following fields to these values:
+ | name | New rule quiz |
+ | plugin | Quiz |
+ | eventname | Quiz attempt deleted |
+ | id_description | I want a rule to monitor quiz attempts deleted |
+ | frequency | 5 |
+ | minutes | 5 |
+ | Notification message | Quiz attempt deleted. {modulelink} |
+ And I press "Save changes"
+ Then I should see "New rule quiz"
+ And I should see "I want a rule to monitor quiz attempts deleted"
+ And I should see "Quiz attempt deleted"
+ And I should see "5 time(s) in 5 minute(s)"
Scenario: Duplicate a rule on course level
Given I log in as "teacher1"
- And I follow "Course 1"
- And I navigate to "Event monitoring rules" node in "Course administration > Reports"
- When I click on "Duplicate rule" "link"
- Then I should see "Rule successfully duplicated"
- And "#toolmonitorrules_r1" "css_element" should appear before "#toolmonitorrules_r2" "css_element"
- And I should see "New rule"
- And I should see "I want a rule to monitor posts created on a forum"
- And I should see "Forum"
- And I should see "Post created"
- And I should see "1 times in 1 minutes"
+ And I follow "Course 1"
+ And I navigate to "Event monitoring rules" node in "Course administration > Reports"
+ When I click on "Duplicate rule" "link"
+ Then I should see "Rule successfully duplicated"
+ And "#toolmonitorrules_r1" "css_element" should appear before "#toolmonitorrules_r2" "css_element"
+ And I should see "New rule"
+ And I should see "I want a rule to monitor posts created on a forum"
+ And I should see "Forum"
+ And I should see "Post created"
+ And I should see "1 time(s) in 1 minute(s)"
Scenario: Add a rule on site level
Given I log in as "admin"
- And I navigate to "Event monitoring rules" node in "Site administration > Reports"
- When I press "Add a new rule"
- And I set the following fields to these values:
- | name | New rule |
- | plugin | Forum |
- | eventname | Post created |
- | id_description | I want a rule to monitor posts created on a forum |
- | frequency | 1 |
- | minutes | 1 |
- | Message template | The forum post was created. {modulelink} |
- And I press "Save changes"
- Then I should see "New rule"
- And I should see "I want a rule to monitor posts created on a forum"
- And I should see "Forum"
- And I should see "Post created"
- And I should see "1 times in 1 minutes"
+ And I navigate to "Event monitoring rules" node in "Site administration > Reports"
+ When I press "Add a new rule"
+ And I set the following fields to these values:
+ | name | New rule |
+ | plugin | Forum |
+ | eventname | Post created |
+ | id_description | I want a rule to monitor posts created on a forum |
+ | frequency | 1 |
+ | minutes | 1 |
+ | Notification message | The forum post was created. {modulelink} |
+ And I press "Save changes"
+ Then "New rule" row "Course" column of "toolmonitorrules_table" table should contain "Site"
+ And I should see "I want a rule to monitor posts created on a forum"
+ And I should see "Forum"
+ And I should see "Post created"
+ And I should see "1 time(s) in 1 minute(s)"
Scenario: Delete a rule on site level
Given I log in as "admin"
- And I navigate to "Event monitoring rules" node in "Site administration > Reports"
- When I click on "Delete rule" "link"
- Then I should see "Are you sure you want to delete rule \"New rule site level\"?"
- And I press "Yes"
- And I should see "Rule successfully deleted"
- And I should not see "New rule site level"
+ And I navigate to "Event monitoring rules" node in "Site administration > Reports"
+ When I click on "Delete rule" "link"
+ Then I should see "Are you sure you want to delete rule \"New rule site level\"?"
+ And I press "Continue"
+ And I should see "Rule successfully deleted"
+ And I should not see "New rule site level"
Scenario: Edit a rule on site level
Given I log in as "admin"
- And I navigate to "Event monitoring rules" node in "Site administration > Reports"
- When I click on "Edit rule" "link"
- And I set the following fields to these values:
- | name | New Rule Quiz |
- | plugin | Quiz |
- | eventname | Quiz attempt deleted |
- | id_description | I want a rule to monitor quiz attempts deleted |
- | frequency | 5 |
- | minutes | 5 |
- | Message template | Quiz attempt deleted. {modulelink} |
- And I press "Save changes"
- Then I should see "New Rule Quiz"
- And I should see "I want a rule to monitor quiz attempts deleted"
- And I should see "Quiz attempt deleted"
- And I should see "5 times in 5 minutes"
+ And I navigate to "Event monitoring rules" node in "Site administration > Reports"
+ When I click on "Edit rule" "link"
+ And I set the following fields to these values:
+ | name | New Rule Quiz |
+ | plugin | Quiz |
+ | eventname | Quiz attempt deleted |
+ | id_description | I want a rule to monitor quiz attempts deleted |
+ | frequency | 5 |
+ | minutes | 5 |
+ | Notification message | Quiz attempt deleted. {modulelink} |
+ And I press "Save changes"
+ Then I should see "New Rule Quiz"
+ And I should see "I want a rule to monitor quiz attempts deleted"
+ And I should see "Quiz attempt deleted"
+ And I should see "5 time(s) in 5 minute(s)"
Scenario: Duplicate a rule on site level
Given I log in as "admin"
- And I navigate to "Event monitoring rules" node in "Site administration > Reports"
- When I click on "Duplicate rule" "link"
- Then I should see "Rule successfully duplicated"
- And "#toolmonitorrules_r2" "css_element" should appear after "#toolmonitorrules_r1" "css_element"
- And I should see "I want a rule to monitor posts created on a forum"
- And I should see "Forum"
- And I should see "Post created"
- And I should see "1 times in 1 minutes"
+ And I navigate to "Event monitoring rules" node in "Site administration > Reports"
+ When I click on "Duplicate rule" "link"
+ Then I should see "Rule successfully duplicated"
+ And "#toolmonitorrules_r2" "css_element" should appear after "#toolmonitorrules_r1" "css_element"
+ And I should see "I want a rule to monitor posts created on a forum"
+ And I should see "Forum"
+ And I should see "Post created"
+ And I should see "1 time(s) in 1 minute(s)"
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
- And I log in as "admin"
- And I follow "Course 1"
- And I navigate to "Event monitoring rules" node in "Course administration > Reports"
- And I press "Add a new rule"
- And I set the following fields to these values:
- | name | New rule course level |
- | plugin | Core |
- | eventname | Course viewed |
- | id_description | I want a rule to monitor when a course is viewed. |
- | frequency | 1 |
- | minutes | 1 |
- | Message template | The course was viewed. {modulelink} |
- And I press "Save changes"
- And I navigate to "Event monitoring rules" node in "Site administration > Reports"
- And I press "Add a new rule"
- And I set the following fields to these values:
- | name | New rule site level |
- | plugin | Core |
- | eventname | Course viewed |
- | id_description | I want a rule to monitor when a course is viewed. |
- | frequency | 1 |
- | minutes | 1 |
- | Message template | The course was viewed. {modulelink} |
- And I press "Save changes"
- And I log out
+ And I log in as "admin"
+ And I follow "Course 1"
+ And I navigate to "Event monitoring rules" node in "Course administration > Reports"
+ And I press "Add a new rule"
+ And I set the following fields to these values:
+ | name | New rule course level |
+ | plugin | Core |
+ | eventname | Course viewed |
+ | id_description | I want a rule to monitor when a course is viewed. |
+ | frequency | 1 |
+ | minutes | 1 |
+ | Notification message | The course was viewed. {modulelink} |
+ And I press "Save changes"
+ And I navigate to "Event monitoring rules" node in "Site administration > Reports"
+ And I press "Add a new rule"
+ And I set the following fields to these values:
+ | name | New rule site level |
+ | plugin | Core |
+ | eventname | Course viewed |
+ | id_description | I want a rule to monitor when a course is viewed. |
+ | frequency | 1 |
+ | minutes | 1 |
+ | Notification message | The course was viewed. {modulelink} |
+ And I press "Save changes"
+ And I log out
Scenario: Subscribe to a rule on course level
Given I log in as "teacher1"
- And I follow "Course 1"
- And I navigate to "Event monitoring" node in "My profile settings"
- And I set the field "courseid" to "Course 1"
- When I set the field "cmid" to "All events"
- Then I should see "Subscription successfully created"
- And "#toolmonitorsubs_r0" "css_element" should exist
+ And I follow "Course 1"
+ And I navigate to "Event monitoring" node in "My profile settings"
+ And I set the field "Select a course" to "Course 1"
+ When I follow "Subscribe to rule \"New rule course level\""
+ Then I should see "Subscription successfully created"
+ And "#toolmonitorsubs_r0" "css_element" should exist
Scenario: Delete a subscription on course level
Given I log in as "teacher1"
- And I follow "Course 1"
- And I navigate to "Event monitoring" node in "My profile settings"
- And I set the field "courseid" to "Course 1"
- And I set the field "cmid" to "All events"
- And I should see "Subscription successfully created"
- When I click on "Delete subscription" "link"
- And I should see "Are you sure you want to delete this subscription for the rule \"New rule course level\"?"
- And I press "Yes"
- Then I should see "Subscription successfully removed"
- And "#toolmonitorsubs_r0" "css_element" should not exist
+ And I follow "Course 1"
+ And I navigate to "Event monitoring" node in "My profile settings"
+ And I set the field "Select a course" to "Course 1"
+ And I follow "Subscribe to rule \"New rule course level\""
+ And I should see "Subscription successfully created"
+ When I click on "Delete subscription" "link" in the "New rule course level" "table_row"
+ And I should see "Are you sure you want to delete this subscription for the rule \"New rule course level\"?"
+ And I press "Continue"
+ Then I should see "Subscription successfully removed"
+ And "#toolmonitorsubs_r0" "css_element" should not exist
Scenario: Subscribe to a rule on site level
Given I log in as "admin"
- And I navigate to "Event monitoring" node in "My profile settings"
- And I set the field "courseid" to "Site"
- When I set the field "cmid" to "All events"
- Then I should see "Subscription successfully created"
- And "#toolmonitorsubs_r0" "css_element" should exist
+ And I navigate to "Event monitoring" node in "My profile settings"
+ And I set the field "Select a course" to "Site"
+ When I follow "Subscribe to rule \"New rule site level\""
+ Then I should see "Subscription successfully created"
+ And "#toolmonitorsubs_r0" "css_element" should exist
Scenario: Delete a subscription on site level
Given I log in as "admin"
- And I navigate to "Event monitoring" node in "My profile settings"
- And I set the field "courseid" to "Site"
- And I set the field "cmid" to "All events"
- And I should see "Subscription successfully created"
- And "#toolmonitorsubs_r0" "css_element" should exist
- When I click on "Delete subscription" "link"
- And I should see "Are you sure you want to delete this subscription for the rule \"New rule site level\"?"
- And I press "Yes"
- Then I should see "Subscription successfully removed"
- And "#toolmonitorsubs_r0" "css_element" should not exist
+ And I navigate to "Event monitoring" node in "My profile settings"
+ And I set the field "Select a course" to "Site"
+ And I follow "Subscribe to rule \"New rule site level\""
+ And I should see "Subscription successfully created"
+ And "#toolmonitorsubs_r0" "css_element" should exist
+ When I click on "Delete subscription" "link" in the "New rule site level" "table_row"
+ And I should see "Are you sure you want to delete this subscription for the rule \"New rule site level\"?"
+ And I press "Continue"
+ Then I should see "Subscription successfully removed"
+ And "#toolmonitorsubs_r0" "css_element" should not exist
Scenario: Receiving notification on site level
Given I log in as "admin"
- And I navigate to "Messaging" node in "My profile settings"
- And I click on "input[name^=tool_monitor_notification_loggedin]" "css_element"
- And I press "Update profile"
- And I am on homepage
- And I follow "Course 1"
- And I navigate to "Event monitoring" node in "My profile settings"
- And I set the field "courseid" to "Site"
- And I set the field "cmid" to "All events"
- And I should see "Subscription successfully created"
- And "#toolmonitorsubs_r0" "css_element" should exist
- And I am on homepage
- And I trigger cron
- And I am on homepage
- And I expand "My profile" node
- When I follow "Messages"
- And I follow "Do not reply to this email (1)"
- Then I should see "The course was viewed."
+ And I navigate to "Messaging" node in "My profile settings"
+ And I click on "input[name^=tool_monitor_notification_loggedin]" "css_element"
+ And I press "Update profile"
+ And I am on homepage
+ And I follow "Course 1"
+ And I navigate to "Event monitoring" node in "My profile settings"
+ And I set the field "Select a course" to "Site"
+ And I follow "Subscribe to rule \"New rule site level\""
+ And I should see "Subscription successfully created"
+ And "#toolmonitorsubs_r0" "css_element" should exist
+ And I am on homepage
+ And I trigger cron
+ And I am on homepage
+ When I navigate to "Messages" node in "My profile"
+ And I follow "Do not reply to this email (1)"
+ Then I should see "The course was viewed."
Scenario: Receiving notification on course level
Given I log in as "teacher1"
- And I navigate to "Messaging" node in "My profile settings"
- And I click on "input[name^=tool_monitor_notification_loggedin]" "css_element"
- And I press "Update profile"
- And I am on homepage
- And I follow "Course 1"
- And I navigate to "Event monitoring" node in "My profile settings"
- And I set the field "courseid" to "Course 1"
- And I set the field "cmid" to "All events"
- And I should see "Subscription successfully created"
- And "#toolmonitorsubs_r0" "css_element" should exist
- And I am on homepage
- And I follow "Course 1"
- And I trigger cron
- And I am on homepage
- And I expand "My profile" node
- When I follow "Messages"
- And I follow "Do not reply to this email (1)"
- Then I should see "The course was viewed."
+ And I navigate to "Messaging" node in "My profile settings"
+ And I click on "input[name^=tool_monitor_notification_loggedin]" "css_element"
+ And I press "Update profile"
+ And I am on homepage
+ And I follow "Course 1"
+ And I navigate to "Event monitoring" node in "My profile settings"
+ And I set the field "Select a course" to "Course 1"
+ And I follow "Subscribe to rule \"New rule course level\""
+ And I should see "Subscription successfully created"
+ And "#toolmonitorsubs_r0" "css_element" should exist
+ And I am on homepage
+ And I follow "Course 1"
+ And I trigger cron
+ And I am on homepage
+ When I navigate to "Messages" node in "My profile"
+ And I follow "Do not reply to this email (1)"
+ Then I should see "The course was viewed."
+
+ Scenario: Navigating via quick link to rules
+ Given I log in as "admin"
+ When I navigate to "Event monitoring" node in "My profile settings"
+ Then I should see "You can manage rules from the Event monitoring rules page."
+ And I follow "Event monitoring rules"
+ And I should see "Event monitor"
+ And I should see "You can subscribe to rules from the Event monitoring page."
+ And I log out
+ And I log in as "teacher1"
+ And I follow "Course 1"
+ And I navigate to "Event monitoring" node in "My profile settings"
+ And I should see "You can manage rules from the Event monitoring rules page."
$this->resetAfterTest(true);
$user = $this->getDataGenerator()->create_user();
- $course = $this->getDataGenerator()->create_course();
+ $course1 = $this->getDataGenerator()->create_course();
+ $course2 = $this->getDataGenerator()->create_course();
$monitorgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor');
$rule = new stdClass();
$rule->userid = $user->id;
- $rule->courseid = $course->id;
+ $rule->courseid = $course1->id;
$rule->plugin = 'test';
$sub = new stdClass();
- $sub->courseid = $course->id;
+ $sub->courseid = $course1->id;
$sub->userid = $user->id;
// Add 10 rules for this course with subscriptions.
$monitorgenerator->create_subscription($sub);
}
- // Add 10 random rules for random courses.
+ // Add 10 random rules for course 2.
+ $rule->courseid = $course2->id;
for ($i = 0; $i < 10; $i++) {
- $rule->courseid = rand(10000000, 50000000);
$createdrule = $monitorgenerator->create_rule($rule);
$sub->courseid = $rule->courseid;
$sub->ruleid = $createdrule->id;
// Verify data before course delete.
$totalrules = \tool_monitor\rule_manager::get_rules_by_plugin('test');
$this->assertCount(20, $totalrules);
- $courserules = \tool_monitor\rule_manager::get_rules_by_courseid($course->id);
+ $courserules = \tool_monitor\rule_manager::get_rules_by_courseid($course1->id);
$this->assertCount(10, $courserules);
$totalsubs = $DB->get_records('tool_monitor_subscriptions');
$this->assertCount(20, $totalsubs);
- $coursesubs = \tool_monitor\subscription_manager::get_user_subscriptions_for_course($course->id, 0, 0, $user->id);
+ $coursesubs = \tool_monitor\subscription_manager::get_user_subscriptions_for_course($course1->id, 0, 0, $user->id);
$this->assertCount(10, $coursesubs);
// Let us delete the course now.
- delete_course($course->id, false);
+ delete_course($course1->id, false);
// Verify data after course delete.
$totalrules = \tool_monitor\rule_manager::get_rules_by_plugin('test');
$this->assertCount(10, $totalrules);
- $courserules = \tool_monitor\rule_manager::get_rules_by_courseid($course->id);
+ $courserules = \tool_monitor\rule_manager::get_rules_by_courseid($course1->id);
$this->assertCount(0, $courserules); // Making sure all rules are deleted.
$totalsubs = $DB->get_records('tool_monitor_subscriptions');
$this->assertCount(10, $totalsubs);
- $coursesubs = \tool_monitor\subscription_manager::get_user_subscriptions_for_course($course->id, 0, 0, $user->id);
+ $coursesubs = \tool_monitor\subscription_manager::get_user_subscriptions_for_course($course1->id, 0, 0, $user->id);
$this->assertCount(0, $coursesubs); // Making sure all subscriptions are deleted.
}
$this->verify_processed_data($msgsink);
}
+ /**
+ * Test that same events are not used twice to calculate conditions for a single subscription.
+ */
+ public function test_multiple_notification_not_sent() {
+ global $USER;
+
+ $this->resetAfterTest();
+ $this->setAdminUser();
+ $messagesink = $this->redirectMessages();
+
+ // Generate data.
+ $course = $this->getDataGenerator()->create_course();
+ $toolgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor');
+
+ $rulerecord = new stdClass();
+ $rulerecord->courseid = $course->id;
+ $rulerecord->eventname = '\mod_book\event\course_module_instance_list_viewed';
+ $rulerecord->frequency = 5;
+
+ $rule = $toolgenerator->create_rule($rulerecord);
+
+ $subrecord = new stdClass();
+ $subrecord->courseid = $course->id;
+ $subrecord->ruleid = $rule->id;
+ $subrecord->userid = $USER->id;
+ $toolgenerator->create_subscription($subrecord);
+
+ for ($i = 0; $i < 7; $i++) {
+ // Now let us trigger 7 instances of the event.
+ $event = \mod_book\event\course_module_instance_list_viewed::create_from_course($course);
+ $event->trigger();
+ sleep(1); // Add a second delay, to prevent time collisions.
+ }
+ $this->run_adhock_tasks();
+ $messages = $messagesink->get_messages();
+ $this->assertCount(1, $messages); // There should be only one message not 3.
+ for ($i = 0; $i < 3; $i++) {
+ // Now let us trigger 5 more instances of the event.
+ $event = \mod_book\event\course_module_instance_list_viewed::create_from_course($course);
+ $event->trigger();
+ }
+
+ $this->run_adhock_tasks();
+ $messages = $messagesink->get_messages();
+ $this->assertCount(2, $messages); // There should be two messages now.
+ }
+
/**
* Run adhoc tasks.
*/
protected function run_adhock_tasks() {
+ ob_start();
while ($task = \core\task\manager::get_next_adhoc_task(time())) {
$task->execute();
\core\task\manager::adhoc_task_complete($task);
}
+ ob_clean(); // Suppress mtrace debugging info.
}
/**
$this->resetAfterTest(true);
$user = $this->getDataGenerator()->create_user();
- $course = $this->getDataGenerator()->create_course();
+ $course1 = $this->getDataGenerator()->create_course();
+ $course2 = $this->getDataGenerator()->create_course();
$monitorgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor');
$rule = new stdClass();
$rule->userid = $user->id;
- $rule->courseid = $course->id;
+ $rule->courseid = $course1->id;
$rule->plugin = 'test';
$sub = new stdClass();
- $sub->courseid = $course->id;
+ $sub->courseid = $course1->id;
$sub->userid = $user->id;
// Add 10 rules for this course with subscriptions.
$monitorgenerator->create_subscription($sub);
}
- // Add 10 random rules for random courses.
+ // Add 10 random rules for course 2.
+ $rule->courseid = $course2->id;
for ($i = 0; $i < 10; $i++) {
- $rule->courseid = rand(10000000, 50000000);
$createdrule = $monitorgenerator->create_rule($rule);
$sub->courseid = $rule->courseid;
$sub->ruleid = $createdrule->id;
$this->resetAfterTest(true);
$user = $this->getDataGenerator()->create_user();
- $course = $this->getDataGenerator()->create_course();
+ $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 = $course->id;
+ $cm->course = $course1->id;
$book = $this->getDataGenerator()->create_module('book', $cm);
$rule = new stdClass();
$rule->userid = $user->id;
- $rule->courseid = $course->id;
+ $rule->courseid = $course1->id;
$rule->plugin = 'test';
$sub = new stdClass();
- $sub->courseid = $course->id;
+ $sub->courseid = $course1->id;
$sub->userid = $user->id;
$sub->cmid = $book->cmid;
$monitorgenerator->create_subscription($sub);
}
- // Add 10 random rules for random courses.
+ // Add 10 random rules for course 2.
+ $rule->courseid = $course2->id;
for ($i = 0; $i < 10; $i++) {
- $rule->courseid = rand(10000000, 50000000);
$createdrule = $monitorgenerator->create_rule($rule);
$sub->courseid = $rule->courseid;
$sub->ruleid = $createdrule->id;
--- /dev/null
+<?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/>.
+
+/**
+ * Events tests.
+ *
+ * @package tool_monitor
+ * @category test
+ * @copyright 2014 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Tests that the tool_monitor events are valid and triggered correctly.
+ */
+class tool_monitor_events_testcase extends advanced_testcase {
+
+ /**
+ * Tests set up.
+ */
+ public function setUp() {
+ $this->resetAfterTest();
+ }
+
+ /**
+ * Test the rule created event.
+ */
+ public function test_rule_created() {
+ // Create the items we need to create a rule.
+ $course = $this->getDataGenerator()->create_course();
+ $user = $this->getDataGenerator()->create_user();
+
+ // Create the variables for the rule we want to create.
+ $ruledata = new stdClass();
+ $ruledata->userid = $user->id;
+ $ruledata->courseid = $course->id;
+ $ruledata->description = 'Rule description';
+ $ruledata->descriptionformat = FORMAT_HTML;
+ $ruledata->template = 'A message template';
+ $ruledata->templateformat = FORMAT_HTML;
+ $ruledata->frequency = 1;
+ $ruledata->timewindow = 60;
+
+ // Trigger and capture the event.
+ $sink = $this->redirectEvents();
+ $rule = \tool_monitor\rule_manager::add_rule($ruledata);
+ $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_created', $event);
+ $this->assertEquals(context_course::instance($course->id), $event->get_context());
+ $this->assertEquals($rule->id, $event->objectid);
+ $this->assertEventContextNotUsed($event);
+
+ // Now let's add a system rule (courseid = 0).
+ $ruledata->courseid = 0;
+
+ // Trigger and capture the event.
+ $sink = $this->redirectEvents();
+ \tool_monitor\rule_manager::add_rule($ruledata);
+ $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_created', $event);
+ $this->assertEquals(context_system::instance(), $event->get_context());
+ }
+
+ /**
+ * Test the rule updated event.
+ */
+ public function test_rule_updated() {
+ // 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 update.
+ $createrule = new stdClass();
+ $createrule->courseid = $course->id;
+ $rule = $monitorgenerator->create_rule($createrule);
+
+ // Trigger and capture the event.
+ $sink = $this->redirectEvents();
+ $updaterule = new stdClass();
+ $updaterule->id = $rule->id;
+ \tool_monitor\rule_manager::update_rule($updaterule);
+ $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_updated', $event);
+ $this->assertEquals(context_course::instance($course->id), $event->get_context());
+ $this->assertEquals($rule->id, $event->objectid);
+ $this->assertEventContextNotUsed($event);
+
+ // Now let's update a system rule (courseid = 0).
+ $createrule->courseid = 0;
+ $rule = $monitorgenerator->create_rule($createrule);
+
+ // Trigger and capture the event.
+ $sink = $this->redirectEvents();
+ $updaterule = new stdClass();
+ $updaterule->id = $rule->id;
+ \tool_monitor\rule_manager::update_rule($updaterule);
+ $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_updated', $event);
+ $this->assertEquals(context_system::instance(), $event->get_context());
+ }
+
+ /**
+ * 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());
+ }
+
+ /**
+ * Test the subscription created event.
+ */
+ public function test_subscription_created() {
+ // Create the items we need to test this.
+ $user = $this->getDataGenerator()->create_user();
+ $course = $this->getDataGenerator()->create_course();
+ $monitorgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor');
+
+ // Create a rule to subscribe to.
+ $rule = $monitorgenerator->create_rule();
+
+ // Trigger and capture the event.
+ $sink = $this->redirectEvents();
+ $subscriptionid = \tool_monitor\subscription_manager::create_subscription($rule->id, $course->id, 0, $user->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\subscription_created', $event);
+ $this->assertEquals(context_course::instance($course->id), $event->get_context());
+ $this->assertEquals($subscriptionid, $event->objectid);
+ $this->assertEventContextNotUsed($event);
+
+ // Create a system subscription - trigger and capture the event.
+ $sink = $this->redirectEvents();
+ \tool_monitor\subscription_manager::create_subscription($rule->id, 0, 0, $user->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\subscription_created', $event);
+ $this->assertEquals(context_system::instance(), $event->get_context());
+ }
+
+ /**
+ * Test the subscription deleted event.
+ */
+ public function test_subscription_deleted() {
+ // Create the items we need to test this.
+ $user = $this->getDataGenerator()->create_user();
+ $course = $this->getDataGenerator()->create_course();
+ $monitorgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor');
+
+ // Create a rule to subscribe to.
+ $rule = $monitorgenerator->create_rule();
+
+ $sub = new stdClass();
+ $sub->courseid = $course->id;
+ $sub->userid = $user->id;
+ $sub->ruleid = $rule->id;
+
+ // Create the subscription we are going to delete.
+ $subscription = $monitorgenerator->create_subscription($sub);
+
+ // Trigger and capture the event.
+ $sink = $this->redirectEvents();
+ \tool_monitor\subscription_manager::delete_subscription($subscription->id, false);
+ $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_deleted', $event);
+ $this->assertEquals(context_course::instance($course->id), $event->get_context());
+ $this->assertEquals($subscription->id, $event->objectid);
+ $this->assertEventContextNotUsed($event);
+
+ // Now let's delete a system subscription.
+ $sub = new stdClass();
+ $sub->courseid = 0;
+ $sub->userid = $user->id;
+ $sub->ruleid = $rule->id;
+
+ // Create the subscription we are going to delete.
+ $subscription = $monitorgenerator->create_subscription($sub);
+
+ // Trigger and capture the event.
+ $sink = $this->redirectEvents();
+ \tool_monitor\subscription_manager::delete_subscription($subscription->id, false);
+ $events = $sink->get_events();
+ $this->assertCount(1, $events);
+ $event = reset($events);
+
+ // Confirm that the event uses the system context.
+ $this->assertInstanceOf('\tool_monitor\event\subscription_deleted', $event);
+ $this->assertEquals(context_system::instance(), $event->get_context());
+
+ // Now, create a bunch of subscriptions for the rule we created.
+ $subids = array();
+ $sub->courseid = $course->id;
+ for ($i = 1; $i <= 10; $i++) {
+ $sub->userid = $i;
+ $subscription = $monitorgenerator->create_subscription($sub);
+ $subids[$subscription->id] = $subscription;
+ }
+
+ // Trigger and capture the events.
+ $sink = $this->redirectEvents();
+ \tool_monitor\subscription_manager::remove_all_subscriptions_for_rule($rule->id);
+ $events = $sink->get_events();
+
+ // Check that there were 10 events in total.
+ $this->assertCount(10, $events);
+
+ // Get all the events and ensure they are valid.
+ foreach ($events as $event) {
+ $this->assertInstanceOf('\tool_monitor\event\subscription_deleted', $event);
+ $this->assertEquals(context_course::instance($course->id), $event->get_context());
+ $this->assertEventContextNotUsed($event);
+ $this->assertArrayHasKey($event->objectid, $subids);
+ unset($subids[$event->objectid]);
+ }
+
+ // We should have found all the subscriptions.
+ $this->assertEmpty($subids);
+ }
+
+ /**
+ * 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);
+ }
+}
$monitorgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor');
+ $course1 = $this->getDataGenerator()->create_course();
+ $course2 = $this->getDataGenerator()->create_course();
+
$record = new stdClass();
- $record->courseid = 3;
+ $record->courseid = $course1->id;
$record2 = new stdClass();
- $record2->courseid = 4;
+ $record2->courseid = $course2->id;
$ruleids = array();
for ($i = 0; $i < 10; $i++) {
$ruleids[] = $rule->id;
$rule = $monitorgenerator->create_rule($record2); // Create rules in a different course.
}
- $ruledata = \tool_monitor\rule_manager::get_rules_by_courseid(3);
- $this->assertEquals($ruleids, array_keys($ruledata));
+ $ruledata = \tool_monitor\rule_manager::get_rules_by_courseid($course1->id);
+ $this->assertEmpty(array_merge(array_diff(array_keys($ruledata), $ruleids), array_diff($ruleids, array_keys($ruledata))));
$this->assertCount(20, $ruledata);
}
}
$ruledata = \tool_monitor\rule_manager::get_rules_by_plugin('core');
- $this->assertEquals($ruleids, array_keys($ruledata));
+ $this->assertEmpty(array_merge(array_diff(array_keys($ruledata), $ruleids), array_diff($ruleids, array_keys($ruledata))));
$this->assertCount(10, $ruledata);
}
--- /dev/null
+<?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/>.
+
+/**
+ * Unit tests for subscription manager api.
+ *
+ * @package tool_monitor
+ * @category test
+ * @copyright 2014 onwards Simey Lameze <simey@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+
+/**
+ * Tests for subscription manager.
+ *
+ * Class tool_monitor_subscription_manager_testcase.
+ */
+class tool_monitor_subscription_manager_testcase extends advanced_testcase {
+
+ /**
+ * Test count_rule_subscriptions method.
+ */
+ public function test_count_rule_subscriptions() {
+
+ $this->setAdminUser();
+ $this->resetAfterTest(true);
+
+ // Create users.
+ $user1 = $this->getDataGenerator()->create_user();
+ $user2 = $this->getDataGenerator()->create_user();
+
+ // Create few rules.
+ $monitorgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor');
+ $rule1 = $monitorgenerator->create_rule();
+ $rule2 = $monitorgenerator->create_rule();
+ $subs = \tool_monitor\subscription_manager::count_rule_subscriptions($rule1->id);
+
+ // No subscriptions at this point.
+ $this->assertEquals(0, $subs);
+
+ // Subscribe user 1 to rule 1.
+ $record = new stdClass;
+ $record->ruleid = $rule1->id;
+ $record->userid = $user1->id;
+ $monitorgenerator->create_subscription($record);
+
+ // Subscribe user 2 to rule 1.
+ $record->userid = $user2->id;
+ $monitorgenerator->create_subscription($record);
+
+ // Subscribe user 2 to rule 2.
+ $record->ruleid = $rule2->id;
+ $monitorgenerator->create_subscription($record);
+
+ // Should have 2 subscriptions for rule 1 and 1 subscription for rule 2
+ $subs1 = \tool_monitor\subscription_manager::count_rule_subscriptions($rule1->id);
+ $subs2 = \tool_monitor\subscription_manager::count_rule_subscriptions($rule2->id);
+ $this->assertEquals(2, $subs1);
+ $this->assertEquals(1, $subs2);
+ }
+}
\ No newline at end of file
--- /dev/null
+<?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/>.
+
+/**
+ * Unit tests for the tool_monitor clean events task.
+ *
+ * @package tool_monitor
+ * @category test
+ * @copyright 2014 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+
+/**
+ * Class used to test the tool_monitor clean events task.
+ */
+class tool_monitor_task_clean_events_testcase extends advanced_testcase {
+
+ /**
+ * Test set up.
+ */
+ public function setUp() {
+ $this->resetAfterTest(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', array(), 'id');
+ $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', array(), 'id');
+ $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'));
+ }
+}
defined('MOODLE_INTERNAL') || die;
-$plugin->version = 2014061900; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->version = 2014102000; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2014061900; // Requires this Moodle version.
$plugin->component = 'tool_monitor'; // Full name of the plugin (used for diagnostics).
initializer: function() {
this.plugin = Y.one(SELECTORS.PLUGIN);
this.eventname = Y.one(SELECTORS.EVENTNAME);
+ var selection = this.eventname.get('value'); // Get selected event name.
+ this.updateEventsList();
+ this.updateSelection(selection);
this.plugin.on('change', this.updateEventsList, this);
},
}
}, this);
+ },
+
+ /**
+ * Method to update the selected node from the options list.
+ *
+ * @method updateSelection
+ * @param {string} selection The options node value that should be selected.
+ */
+ updateSelection: function(selection) {
+ this.eventname.get('options').each(function(opt) {
+ if (opt.get('value') === selection) {
+ opt.set('selected', 'selected');
+ }
+ }, this);
}
}, {
NAME: 'dropDown',
*/
class tool_uploadcourse_course_testcase extends advanced_testcase {
+ /**
+ * Tidy up open files that may be left open.
+ */
+ protected function tearDown() {
+ gc_collect_cycles();
+ }
+
public function test_proceed_without_prepare() {
$this->resetAfterTest(true);
$mode = tool_uploadcourse_processor::MODE_CREATE_NEW;
*/
class tool_uploadcourse_processor_testcase extends advanced_testcase {
+ /**
+ * Tidy up open files that may be left open.
+ */
+ protected function tearDown() {
+ gc_collect_cycles();
+ }
+
public function test_basic() {
global $DB;
$this->resetAfterTest(true);
if ($scount) {
if ($scount < MAX_BULK_USERS) {
- $in = implode(',', $SESSION->bulk_users);
+ $bulkusers = $SESSION->bulk_users;
} else {
$bulkusers = array_slice($SESSION->bulk_users, 0, MAX_BULK_USERS, true);
- $in = implode(',', $bulkusers);
}
- $userlist['susers'] = $DB->get_records_select_menu('user', "id IN ($in)", null, 'fullname', 'id,'.$DB->sql_fullname().' AS fullname');
+ list($in, $inparams) = $DB->get_in_or_equal($bulkusers);
+ $userlist['susers'] = $DB->get_records_select_menu('user', "id $in", $inparams, 'fullname', 'id,'.$DB->sql_fullname().' AS fullname');
}
return $userlist;
set_config('host', $CFG->dbhost.':'.$CFG->dboptions['dbport'], 'auth/db');
}
- switch (get_class($DB)) {
- case 'mssql_native_moodle_database':
- set_config('type', 'mssql_n', 'auth/db');
- set_config('sybasequoting', '1', 'auth/db');
- break;
+ switch ($DB->get_dbfamily()) {
- case 'mariadb_native_moodle_database':
- case 'mysqli_native_moodle_database':
+ case 'mysql':
set_config('type', 'mysqli', 'auth/db');
set_config('setupsql', "SET NAMES 'UTF-8'", 'auth/db');
set_config('sybasequoting', '0', 'auth/db');
}
break;
- case 'oci_native_moodle_database':
+ case 'oracle':
set_config('type', 'oci8po', 'auth/db');
set_config('sybasequoting', '1', 'auth/db');
break;
- case 'pgsql_native_moodle_database':
+ case 'postgres':
set_config('type', 'postgres7', 'auth/db');
$setupsql = "SET NAMES 'UTF-8'";
if (!empty($CFG->dboptions['dbschema'])) {
}
break;
- case 'sqlsrv_native_moodle_database':
- set_config('type', 'mssqlnative', 'auth/db');
+ case 'mssql':
+ if (get_class($DB) == 'mssql_native_moodle_database') {
+ set_config('type', 'mssql_n', 'auth/db');
+ } else {
+ set_config('type', 'mssqlnative', 'auth/db');
+ }
set_config('sybasequoting', '1', 'auth/db');
break;
default:
- throw new exception('Unknown database driver '.get_class($DB));
+ throw new exception('Unknown database family ' . $DB->get_dbfamily());
}
$table = new xmldb_table('auth_db_users');
* The name of the component. Used by the configuration.
*/
const COMPONENT_NAME = 'auth_manual';
+ const LEGACY_COMPONENT_NAME = 'auth/manual';
/**
* Constructor.
*/
function auth_plugin_manual() {
$this->authtype = 'manual';
- $this->config = get_config(self::COMPONENT_NAME);
+ $config = get_config(self::COMPONENT_NAME);
+ $legacyconfig = get_config(self::LEGACY_COMPONENT_NAME);
+ $this->config = (object)array_merge((array)$legacyconfig, (array)$config);
}
/**
// hamburger.
// However, the user menu *always* needs to be expanded.
- $xpath ="//div[@class='usermenu']//a[contains(concat(' ', @class, ' '), ' toggle-display ')]";
+ $xpath = "//div[@class='usermenu']//a[contains(concat(' ', @class, ' '), ' toggle-display ')]";
array_unshift($steps, new When('I click on "'.$xpath.'" "xpath_element"'));
return $steps;
// The list of fields should include the text field added in setUp(),
// but should not include the textarea field added just now.
$fields = condition::get_custom_profile_fields();
- $this->assertEquals(array('frogtype'), array_keys($fields));
+ $this->assertArrayHasKey('frogtype', $fields);
+ $this->assertArrayNotHasKey('longtext', $fields);
}
/**
$replace_values = array($i,
$i - 1,
- $topic['title'],
+ entities::safexml($topic['title']),
$node_node_course_sections_section_mods_mod);
} else {
* Closes the questions wrapper
*/
public function on_questions_end() {
- $this->xmlwriter->end_tag('questions');
+ if ($this->questionswrapperwritten) {
+ $this->xmlwriter->end_tag('questions');
+ }
}
/**
$grade_category = new backup_nested_element('grade_category', array('id'), array(
//'courseid',
'parent', 'depth', 'path', 'fullname', 'aggregation', 'keephigh',
- 'droplow', 'aggregateonlygraded', 'aggregateoutcomes', 'aggregatesubcats',
+ 'droplow', 'aggregateonlygraded', 'aggregateoutcomes',
'timecreated', 'timemodified', 'hidden'));
$letters = new backup_nested_element('grade_letters');
}
}
+ // Add a warning about a removed setting.
+ if (!empty($data->aggregatesubcats)) {
+ set_config('show_aggregatesubcats_upgrade_' . $data->courseid, 1);
+ }
+
//need to insert a course category
if (empty($newitemid)) {
$newitemid = $DB->insert_record('grade_categories', $data);
*/
class core_backup_moodle2_testcase extends advanced_testcase {
+ /**
+ * Tidy up open files that may be left open.
+ */
+ protected function tearDown() {
+ gc_collect_cycles();
+ }
+
/**
* Tests the availability field on modules and sections is correctly
* backed up and restored.
// Roles that can award this badge.
$acceptedroles = array_keys($badge->criteria[BADGE_CRITERIA_TYPE_MANUAL]->params);
+if (empty($acceptedroles)) {
+ echo $OUTPUT->header();
+ $return = html_writer::link(new moodle_url('recipients.php', array('id' => $badge->id)), $strrecipients);
+ echo $OUTPUT->notification(get_string('notacceptedrole', 'badges', $return));
+ echo $OUTPUT->footer();
+ die();
+}
+
if (count($acceptedroles) > 1) {
// If there is more than one role that can award a badge, prompt user to make a selection.
// If it is an admin, include all accepted roles, otherwise only the ones that current user has in this context.
public function review($userid, $filtered = false) {
global $DB;
+ // Roles should always have a parameter.
+ if (empty($this->params)) {
+ return false;
+ }
+
// Users were already filtered by criteria completion.
if ($filtered) {
return true;
And I expand all fieldsets
And I set the field "Phone" to "123456789"
And I press "Update profile"
- And I follow "My badges"
+ And I navigate to "My badges" node in "My profile"
Then I should see "Profile Badge"
And I should not see "There are no badges available."
Then I should see "Recipients (2)"
And I log out
And I log in as "student"
- And I expand "My profile" node
- And I follow "My badges"
+ And I navigate to "My badges" node in "My profile"
Then I should see "Site Badge"
@javascript
And I log out
And I log in as "student1"
And I follow "Course 1"
- And I expand "My profile" node
- And I follow "My badges"
+ And I navigate to "My badges" node in "My profile"
Then I should see "Course Badge"
@javascript
And I log out
And I log in as "student1"
And I follow "Course 1"
- And I expand "My profile" node
- And I follow "My badges"
+ And I navigate to "My badges" node in "My profile"
Then I should see "There are no badges available."
And I follow "Home"
And I follow "Course 1"
And I press "Mark as complete: Test assignment name"
- And I expand "My profile" node
- And I follow "My badges"
+ And I navigate to "My badges" node in "My profile"
Then I should see "Course Badge"
@javascript
And I log out
And I log in as "student1"
And I follow "Course 1"
- And I expand "My profile" node
- And I follow "My badges"
+ And I navigate to "My badges" node in "My profile"
Then I should see "There are no badges available."
And I follow "Home"
And I follow "Course 1"
And I am on homepage
And I log out
And I log in as "student1"
- And I expand "My profile" node
- And I follow "My badges"
+ And I navigate to "My badges" node in "My profile"
Then I should see "Course Badge"
if (!isset($modinfo->instances[$modname][$instanceid])) {
continue;
}
- $entry['cmid'] = $modinfo->instances[$modname][$instanceid]->id;
if ($log->action == 'add mod') {
$entry['action'] = 0;
} else {
$entry['action'] = 1;
}
+ $entry['cmid'] = $modinfo->instances[$modname][$instanceid]->id;
}
$entries[] = $entry;
}
} else {
$editbuttons = '';
}
- if ($mod->visible || has_capability('moodle/course:viewhiddenactivities', $context)) {
+ if ($mod->visible || has_capability('moodle/course:viewhiddenactivities', $mod->context)) {
if ($ismoving) {
if ($mod->id == $USER->activitycopy) {
continue;
} else {
$editbuttons = '';
}
- if ($mod->visible || has_capability('moodle/course:viewhiddenactivities', $context)) {
+ if ($mod->visible || has_capability('moodle/course:viewhiddenactivities', $mod->context)) {
if ($ismoving) {
if ($mod->id == $USER->activitycopy) {
continue;
return $this->content;
}
}
-
-
* be set to false.
*/
public function get_many($keys) {
+ $return = array();
$result = $this->connection->getMulti($keys);
if (!is_array($result)) {
$result = array();
}
foreach ($keys as $key) {
if (!array_key_exists($key, $result)) {
- $result[$key] = false;
+ $return[$key] = false;
+ } else {
+ $return[$key] = $result[$key];
}
}
- return $result;
+ return $return;
}
/**
}
$store = new cachestore_mongodb('Test mongodb', $configuration);
+ if (!$store->is_ready()) {
+ return false;
+ }
$store->initialise($definition);
return $store;
$configuration['usesafe'] = 1;
$store = new cachestore_mongodb('Test mongodb', $configuration);
+ if (!$store->is_ready()) {
+ return false;
+ }
$store->initialise($definition);
return $store;
}
// Now display all the calendar
- $daytime = $display->tstart - DAYSECS;
+ $daytime = strtotime('-1 day', $display->tstart);
for($day = 1; $day <= $display->maxdays; ++$day, ++$dayweek) {
- $daytime += DAYSECS;
+ $daytime = strtotime('+1 day', $daytime);
if($dayweek > $display->maxwday) {
// We need to change week (table row)
$content .= '</tr><tr>';
case 'day':
$days = calendar_get_days();
- $prevtimestamp = $time - DAYSECS;
- $nexttimestamp = $time + DAYSECS;
+ $prevtimestamp = strtotime('-1 day', $time);
+ $nexttimestamp = strtotime('+1 day', $time);
$prevdate = $calendartype->timestamp_to_date_array($prevtimestamp);
$nextdate = $calendartype->timestamp_to_date_array($nexttimestamp);
$timeend = calendar_time_representation($event->timestart + $event->timeduration);
// Set printable representation.
- if ($now >= $usermidnightstart && $now < ($usermidnightstart + DAYSECS)) {
+ if ($now >= $usermidnightstart && $now < strtotime('+1 day', $usermidnightstart)) {
$url = calendar_get_link_href(new moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $endtime);
$eventtime = $timestart . ' <strong>»</strong> ' . html_writer::link($url, $dayend) . $timeend;
} else {
* @return int tomorrow timestamp
*/
public function timestamp_tomorrow() {
- return $this->time + DAYSECS;
+ return strtotime('+1 day', $this->time);
}
/**
* Adds the pretend blocks for the calendar
$timezone;
$eventrecord->timestart = strtotime($event->properties['DTSTART'][0]->value . ' ' . $tz);
if (empty($event->properties['DTEND'])) {
- $eventrecord->timeduration = 3600; // one hour if no end time specified
+ $eventrecord->timeduration = 0; // no duration if no end time specified
} else {
$endtz = isset($event->properties['DTEND'][0]->parameters['TZID']) ? $event->properties['DTEND'][0]->parameters['TZID'] :
$timezone;
$weekend = intval($CFG->calendar_weekend);
}
- $daytime = $display->tstart - DAYSECS;
+ $daytime = strtotime('-1 day', $display->tstart);
for ($day = 1; $day <= $display->maxdays; ++$day, ++$dayweek) {
- $daytime = $daytime + DAYSECS;
+ $daytime = strtotime('+1 day', $daytime);
if($dayweek > $display->maxwday) {
// We need to change week (table row)
$table->data[] = $row;
public function extend_course_navigation($navigation, navigation_node $node) {
// Display orphaned activities for the users who can see them.
$context = context_course::instance($this->courseid);
- if (has_all_capabilities(array('moodle/course:viewhiddensections',
- 'moodle/course:viewhiddenactivities'), $context)) {
+ if (has_capability('moodle/course:viewhiddensections', $context)) {
$modinfo = get_fast_modinfo($this->courseid);
if (!empty($modinfo->sections[1])) {
$section1 = $modinfo->get_section_info(1);
$orphanednode->nodetype = navigation_node::NODETYPE_BRANCH;
$orphanednode->add_class('orphaned');
foreach ($modinfo->sections[1] as $cmid) {
- $this->navigation_add_activity($orphanednode, $modinfo->cms[$cmid]);
+ if (has_capability('moodle/course:viewhiddenactivities', context_module::instance($cmid))) {
+ $this->navigation_add_activity($orphanednode, $modinfo->cms[$cmid]);
+ }
}
}
}
$returntomod = optional_param('return', 0, PARAM_BOOL);
redirect("$CFG->wwwroot/course/modedit.php?update=$update&return=$returntomod&sr=$sectionreturn");
-} else if (!empty($duplicate)) {
+} else if (!empty($duplicate) and confirm_sesskey()) {
$cm = get_coursemodule_from_id('', $duplicate, 0, true, MUST_EXIST);
$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);