Exemplo n.º 1
0
 /**
  * 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);
 }
Exemplo n.º 2
0
 /**
  * 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);
 }
Exemplo n.º 3
0
 /**
  * Api to buffer events to store, to reduce db queries.
  *
  * @param \core\event\base $event
  */
 protected function buffer_event(\core\event\base $event)
 {
     // If there are no subscriptions for this event do not buffer it.
     if (!\tool_monitor\subscription_manager::event_has_subscriptions($event->eventname, $event->courseid)) {
         return;
     }
     $eventdata = $event->get_data();
     $eventobj = new \stdClass();
     $eventobj->eventname = $eventdata['eventname'];
     $eventobj->contextid = $eventdata['contextid'];
     $eventobj->contextlevel = $eventdata['contextlevel'];
     $eventobj->contextinstanceid = $eventdata['contextinstanceid'];
     if ($event->get_url()) {
         // Get link url if exists.
         $eventobj->link = $event->get_url()->out();
     } else {
         $eventobj->link = '';
     }
     $eventobj->courseid = $eventdata['courseid'];
     $eventobj->timecreated = $eventdata['timecreated'];
     $this->buffer[] = $eventobj;
     $this->count++;
 }
 /**
  * Test to confirm that a suspended user's subscriptions are deactivated properly.
  */
 public function test_suspended_user()
 {
     global $DB;
     // Enrol the user as a teacher. This role should have the required capability.
     $this->getDataGenerator()->enrol_user($this->user->id, $this->course->id, $this->teacherrole->id);
     // Subscription should be active to start with.
     $this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
     // Suspend the user.
     $DB->set_field('user', 'suspended', '1', array('id' => $this->user->id));
     // Run the task.
     $task = new \tool_monitor\task\check_subscriptions();
     $task->execute();
     // The subscription should now be inactive.
     $this->reload_subscription();
     $this->assertEquals(false, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
     // Unsuspend the user.
     $DB->set_field('user', 'suspended', '0', array('id' => $this->user->id));
     // Run the task.
     $task = new \tool_monitor\task\check_subscriptions();
     $task->execute();
     // The subscription should now be active again.
     $this->reload_subscription();
     $this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
 }
Exemplo n.º 5
0
 /**
  * Test observer for course delete event.
  */
 public function test_course_deleted()
 {
     global $DB;
     $this->setAdminUser();
     $this->resetAfterTest(true);
     $user = $this->getDataGenerator()->create_user();
     $course1 = $this->getDataGenerator()->create_course();
     $course2 = $this->getDataGenerator()->create_course();
     $monitorgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor');
     $rule = new stdClass();
     $rule->userid = $user->id;
     $rule->courseid = $course1->id;
     $rule->plugin = 'test';
     $sub = new stdClass();
     $sub->courseid = $course1->id;
     $sub->userid = $user->id;
     // Add 10 rules for this course with subscriptions.
     for ($i = 0; $i < 10; $i++) {
         $createdrule = $monitorgenerator->create_rule($rule);
         $sub->ruleid = $createdrule->id;
         $monitorgenerator->create_subscription($sub);
     }
     // Add 10 random rules for course 2.
     $rule->courseid = $course2->id;
     for ($i = 0; $i < 10; $i++) {
         $createdrule = $monitorgenerator->create_rule($rule);
         $sub->courseid = $rule->courseid;
         $sub->ruleid = $createdrule->id;
         $monitorgenerator->create_subscription($sub);
     }
     // Add a site rule.
     $rule = new stdClass();
     $rule->userid = $user->id;
     $rule->courseid = 0;
     $rule->plugin = 'core';
     $monitorgenerator->create_rule($rule);
     // Verify that if we do not specify that we do not want the site rules, they are returned.
     $courserules = \tool_monitor\rule_manager::get_rules_by_courseid($course1->id);
     $this->assertCount(11, $courserules);
     // 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($course1->id, 0, 0, false);
     $this->assertCount(10, $courserules);
     $this->assertEquals(20, $DB->count_records('tool_monitor_subscriptions'));
     $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($course1->id, false);
     // Confirm the site rule still exists.
     $this->assertEquals(1, $DB->count_records('tool_monitor_rules', array('courseid' => 0)));
     // 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($course1->id, 0, 0, false);
     $this->assertCount(0, $courserules);
     // Making sure all rules are deleted.
     $this->assertEquals(10, $DB->count_records('tool_monitor_subscriptions'));
     $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.
 }
Exemplo n.º 6
0
 /**
  * Function to generate subscription data.
  *
  * @throws coding_exception if $record->ruleid or $record->userid not present.
  * @param \stdClass|array $record data to insert as subscription entry.
  *
  * @return \tool_monitor\subscription An instance of the subscription class.
  */
 public function create_subscription($record = null)
 {
     if (!isset($record->timecreated)) {
         $record->timecreated = time();
     }
     if (!isset($record->courseid)) {
         $record->courseid = 0;
     }
     if (!isset($record->ruleid)) {
         throw new coding_exception('$record->ruleid must be present in tool_monitor_generator::create_subscription()');
     }
     if (!isset($record->cmid)) {
         $record->cmid = 0;
     }
     if (!isset($record->userid)) {
         throw new coding_exception('$record->userid must be present in tool_monitor_generator::create_subscription()');
     }
     $sid = \tool_monitor\subscription_manager::create_subscription($record->ruleid, $record->courseid, $record->cmid, $record->userid);
     return \tool_monitor\subscription_manager::get_subscription($sid);
 }
Exemplo n.º 7
0
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
/**
 * Displays help via AJAX call.
 *
 * @copyright 2014 Mark Nelson <*****@*****.**>
 * @package tool_monitor
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
define('NO_MOODLE_COOKIES', true);
define('AJAX_SCRIPT', true);
require_once '../../../config.php';
$type = required_param('type', PARAM_ALPHA);
$id = required_param('id', PARAM_INT);
$lang = optional_param('lang', 'en', PARAM_LANG);
// We don't actually modify the session here as we have NO_MOODLE_COOKIES set.
$SESSION->lang = $lang;
$PAGE->set_url('/admin/tool/monitor/help_ajax.php');
if ($type == 'rule') {
    $item = \tool_monitor\rule_manager::get_rule($id);
} else {
    // Must be a subscription.
    $item = \tool_monitor\subscription_manager::get_subscription($id);
}
if ($item->courseid) {
    $PAGE->set_context(context_course::instance($item->courseid));
} else {
    // Must be system context.
    $PAGE->set_context(context_system::instance());
}
echo json_encode(tool_monitor\output\helpicon\renderable::get_help_string_parameters($type, $id, true));
Exemplo n.º 8
0
$eventlist = array_merge(array('' => get_string('choosedots')), $eventlist);
$pluginlist = array_merge(array('' => get_string('choosedots')), $pluginlist);
// Set up the yui module.
$PAGE->requires->yui_module('moodle-tool_monitor-dropdown', 'Y.M.tool_monitor.DropDown.init', array(array('eventlist' => $eventlist)));
// Site level report.
if (empty($courseid)) {
    admin_externalpage_setup('toolmonitorrules', '', null, '', array('pagelayout' => 'report'));
} else {
    // Course level report.
    $PAGE->navigation->override_active_url($manageurl);
}
// Mform setup.
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, 'subscriptioncount' => $subscriptioncount));
if ($mform->is_cancelled()) {
    redirect(new moodle_url('/admin/tool/monitor/managerules.php', array('courseid' => $courseid)));
    exit;
}
if ($mformdata = $mform->get_data()) {
    $rule = \tool_monitor\rule_manager::clean_ruledata_form($mformdata);
    if (empty($rule->id)) {
        \tool_monitor\rule_manager::add_rule($rule);
    } else {
        \tool_monitor\rule_manager::update_rule($rule);
Exemplo n.º 9
0
 /**
  * Checks all course-level rule subscriptions and activates/deactivates based on current course access.
  *
  * The ordering of checks within the task is important for optimisation purposes. The aim is to be able to make a decision
  * about whether to activate/deactivate each subscription without making unnecessary checks. The ordering roughly follows the
  * context model, starting with system and user checks and moving down to course and course-module only when necessary.
  *
  * For example, if the user is suspended, then any active subscription is made inactive right away. I.e. there is no need to
  * check site-level, course-level or course-module-level permissions. Likewise, if a subscriptions is site-level, there is no
  * need to check course-level and course-module-level permissions.
  *
  * The task performs the following checks, in this order:
  * 1. Check for a suspended user, breaking if suspended.
  * 2. Check for an incomplete (not set up) user, breaking if not fully set up.
  * 3. Check for the required capability in the relevant context, breaking if the capability is not found.
  * 4. Check whether the subscription is site-context, breaking if true.
  * 5. Check whether the user has course access, breaking only if the subscription is not also course-module-level.
  * 6. Check whether the user has course-module access.
  *
  * @since 3.2.0
  */
 public function execute()
 {
     global $DB;
     if (!get_config('tool_monitor', 'enablemonitor')) {
         return;
         // The tool is disabled. Nothing to do.
     }
     $toactivate = array();
     // Store the ids of subscriptions to be activated upon completion.
     $todeactivate = array();
     // Store the ids of subscriptions to be deactivated upon completion.
     // Resultset rows are ordered by userid and courseid to work nicely with get_fast_modinfo() caching.
     $sql = "SELECT u.id AS userid, u.firstname AS userfirstname, u.lastname AS userlastname, u.suspended AS usersuspended,\n                       u.email AS useremail, c.visible as coursevisible, c.cacherev as coursecacherev, s.courseid AS subcourseid,\n                       s.userid AS subuserid, s.cmid AS subcmid, s.inactivedate AS subinactivedate, s.id AS subid\n                  FROM {user} u\n                  JOIN {tool_monitor_subscriptions} s ON (s.userid = u.id)\n             LEFT JOIN {course} c ON (c.id = s.courseid)\n                 WHERE u.id = s.userid\n              ORDER BY s.userid, s.courseid";
     $rs = $DB->get_recordset_sql($sql);
     foreach ($rs as $row) {
         // Create skeleton records from the result. This should be enough to use in subsequent access calls and avoids DB hits.
         $sub = $this->get_subscription_from_rowdata($row);
         $sub = new subscription($sub);
         if (!isset($user) || $user->id != $sub->userid) {
             $user = $this->get_user_from_rowdata($row);
         }
         if ((!isset($course) || $course->id != $sub->courseid) && !empty($sub->courseid)) {
             $course = $this->get_course_from_rowdata($row);
         }
         // The user is suspended at site level, so deactivate any active subscriptions.
         if ($user->suspended) {
             if (subscription_manager::subscription_is_active($sub)) {
                 $todeactivate[] = $sub->id;
             }
             continue;
         }
         // Is the user fully set up? As per require_login on the subscriptions page.
         if (!$this->is_user_setup($user)) {
             if (subscription_manager::subscription_is_active($sub)) {
                 $todeactivate[] = $sub->id;
             }
             continue;
         }
         // Determine the context, based on the subscription course id.
         $sitelevelsubscription = false;
         if (empty($sub->courseid)) {
             $context = \context_system::instance();
             $sitelevelsubscription = true;
         } else {
             $context = \context_course::instance($sub->courseid);
         }
         // Check capability in the context.
         if (!has_capability('tool/monitor:subscribe', $context, $user)) {
             if (subscription_manager::subscription_is_active($sub)) {
                 $todeactivate[] = $sub->id;
             }
             continue;
         }
         // If the subscription is site-level, then we've run all the checks required to make an access decision.
         if ($sitelevelsubscription) {
             if (!subscription_manager::subscription_is_active($sub)) {
                 $toactivate[] = $sub->id;
             }
             continue;
         }
         // Check course access.
         if (!$this->user_can_access_course($user, $course, 'tool/monitor:subscribe')) {
             if (subscription_manager::subscription_is_active($sub)) {
                 $todeactivate[] = $sub->id;
             }
             continue;
         }
         // If the subscription has no course module relationship.
         if (empty($sub->cmid)) {
             if (!subscription_manager::subscription_is_active($sub)) {
                 $toactivate[] = $sub->id;
             }
             continue;
         }
         // Otherwise, check the course module info. We use the same checks as on the subscription page.
         $modinfo = get_fast_modinfo($course, $sub->userid);
         $cm = $modinfo->get_cm($sub->cmid);
         if (!$cm || !$cm->uservisible || !$cm->available) {
             if (subscription_manager::subscription_is_active($sub)) {
                 $todeactivate[] = $sub->id;
             }
             continue;
         }
         // The course module is available and visible, so make a decision.
         if (!subscription_manager::subscription_is_active($sub)) {
             $toactivate[] = $sub->id;
         }
     }
     $rs->close();
     // Activate/deactivate/delete relevant subscriptions.
     subscription_manager::activate_subscriptions($toactivate);
     subscription_manager::deactivate_subscriptions($todeactivate);
     subscription_manager::delete_stale_subscriptions();
 }
Exemplo n.º 10
0
 /**
  * Query the reader. Store results in the object for use by build_table.
  *
  * @param int $pagesize size of page for paginated displayed table.
  * @param bool $useinitialsbar do you want to use the initials bar.
  */
 public function query_db($pagesize, $useinitialsbar = true)
 {
     $total = \tool_monitor\subscription_manager::count_user_subscriptions();
     $this->pagesize($pagesize, $total);
     $subs = \tool_monitor\subscription_manager::get_user_subscriptions($this->get_page_start(), $this->get_page_size());
     $this->rawdata = $subs;
     // Set initial bars.
     if ($useinitialsbar) {
         $this->initialbars($total > $pagesize);
     }
 }
Exemplo n.º 11
0
} else {
    echo $OUTPUT->header();
}
$renderer = $PAGE->get_renderer('tool_monitor', 'managesubs');
// Render the course selector.
$totalrules = \tool_monitor\rule_manager::count_rules_by_courseid($courseid);
$rules = new \tool_monitor\output\managesubs\rules('toolmonitorrules', $indexurl, $courseid);
$usercourses = $rules->get_user_courses_select();
if (!empty($usercourses)) {
    echo $renderer->render($usercourses);
} else {
    // Nothing to show at all. Show a notification.
    echo $OUTPUT->notification(get_string('rulenopermission', 'tool_monitor'), 'notifyproblem');
}
// Render the current subscriptions list.
$totalsubs = \tool_monitor\subscription_manager::count_user_subscriptions();
if (!empty($totalsubs)) {
    // Show the subscriptions section only if there are subscriptions.
    $subs = new \tool_monitor\output\managesubs\subs('toolmonitorsubs', $indexurl, $courseid);
    echo $OUTPUT->heading(get_string('currentsubscriptions', 'tool_monitor'), 3);
    echo $renderer->render($subs);
}
// Render the potential rules list.
// Check the capability here before displaying any rules to subscribe to.
if (has_capability('tool/monitor:subscribe', $coursecontext)) {
    echo $OUTPUT->heading(get_string('rulescansubscribe', 'tool_monitor'), 3);
    echo $renderer->render($rules);
}
// Check if the user can manage the course rules we are viewing.
$canmanagerules = has_capability('tool/monitor:managerules', $coursecontext);
if (empty($totalrules)) {
Exemplo n.º 12
0
 /**
  * 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);
 }