[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/admin/tool/monitor/classes/ -> eventobservers.php (source)

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Observer class containing methods monitoring various events.
  19   *
  20   * @package    tool_monitor
  21   * @copyright  2014 onwards Ankit Agarwal <ankit.agrr@gmail.com>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace tool_monitor;
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  /**
  30   * Observer class containing methods monitoring various events.
  31   *
  32   * @since      Moodle 2.8
  33   * @package    tool_monitor
  34   * @copyright  2014 onwards Ankit Agarwal <ankit.agrr@gmail.com>
  35   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class eventobservers {
  38  
  39      /** @var array $buffer buffer of events. */
  40      protected $buffer = array();
  41  
  42      /** @var int Number of entries in the buffer. */
  43      protected $count = 0;
  44  
  45      /** @var  eventobservers a reference to a self instance. */
  46      protected static $instance;
  47  
  48      /**
  49       * Course delete event observer.
  50       * This observer monitors course delete event, and when a course is deleted it deletes any rules and subscriptions associated
  51       * with it, so no orphan data is left behind.
  52       *
  53       * @param \core\event\course_deleted $event The course deleted event.
  54       */
  55      public static function course_deleted(\core\event\course_deleted $event) {
  56          $rules = rule_manager::get_rules_by_courseid($event->courseid, 0, 0, false);
  57          foreach ($rules as $rule) {
  58              rule_manager::delete_rule($rule->id, $event->get_context());
  59          }
  60      }
  61  
  62      /**
  63       * The observer monitoring all the events.
  64       *
  65       * This observers puts small event objects in buffer for later writing to the database. At the end of the request the buffer
  66       * is cleaned up and all data dumped into the tool_monitor_events table.
  67       *
  68       * @param \core\event\base $event event object
  69       */
  70      public static function process_event(\core\event\base $event) {
  71          if (!get_config('tool_monitor', 'enablemonitor')) {
  72              return; // The tool is disabled. Nothing to do.
  73          }
  74  
  75          if (empty(self::$instance)) {
  76              self::$instance = new static();
  77              // Register shutdown handler - this is useful for buffering, processing events, etc.
  78              \core_shutdown_manager::register_function(array(self::$instance, 'process_buffer'));
  79          }
  80  
  81          self::$instance->buffer_event($event);
  82  
  83          if (PHPUNIT_TEST) {
  84              // Process buffer after every event when unit testing.
  85              self::$instance->process_buffer();
  86  
  87          }
  88      }
  89  
  90      /**
  91       * Api to buffer events to store, to reduce db queries.
  92       *
  93       * @param \core\event\base $event
  94       */
  95      protected function buffer_event(\core\event\base $event) {
  96  
  97          // If there are no subscriptions for this event do not buffer it.
  98          if (!\tool_monitor\subscription_manager::event_has_subscriptions($event->eventname, $event->courseid)) {
  99              return;
 100          }
 101  
 102          $eventdata = $event->get_data();
 103          $eventobj = new \stdClass();
 104          $eventobj->eventname = $eventdata['eventname'];
 105          $eventobj->contextid = $eventdata['contextid'];
 106          $eventobj->contextlevel = $eventdata['contextlevel'];
 107          $eventobj->contextinstanceid = $eventdata['contextinstanceid'];
 108          if ($event->get_url()) {
 109              // Get link url if exists.
 110              $eventobj->link = $event->get_url()->out();
 111          } else {
 112              $eventobj->link = '';
 113          }
 114          $eventobj->courseid = $eventdata['courseid'];
 115          $eventobj->timecreated = $eventdata['timecreated'];
 116  
 117          $this->buffer[] = $eventobj;
 118          $this->count++;
 119      }
 120  
 121      /**
 122       * This method process all events stored in the buffer.
 123       *
 124       * This is a multi purpose api. It does the following:-
 125       * 1. Write event data to tool_monitor_events
 126       * 2. Find out users that need to be notified about rule completion and schedule a task to send them messages.
 127       */
 128      public function process_buffer() {
 129          global $DB;
 130  
 131          $events = $this->flush(); // Flush data.
 132  
 133          $select = "SELECT COUNT(id) FROM {tool_monitor_events} ";
 134          $now = time();
 135          $messagestosend = array();
 136          $allsubids = array();
 137  
 138          // Let us now process the events and check for subscriptions.
 139          foreach ($events as $eventobj) {
 140              $subscriptions = subscription_manager::get_subscriptions_by_event($eventobj);
 141              $idstosend = array();
 142              foreach ($subscriptions as $subscription) {
 143                  // Only proceed to fire events and notifications if the subscription is active.
 144                  if (!subscription_manager::subscription_is_active($subscription)) {
 145                      continue;
 146                  }
 147                  $starttime = $now - $subscription->timewindow;
 148                  $starttime = ($starttime > $subscription->lastnotificationsent) ? $starttime : $subscription->lastnotificationsent;
 149                  if ($subscription->courseid == 0) {
 150                      // Site level subscription. Count all events.
 151                      $where = "eventname = :eventname AND timecreated >  :starttime";
 152                      $params = array('eventname' => $eventobj->eventname, 'starttime' => $starttime);
 153                  } else {
 154                      // Course level subscription.
 155                      if ($subscription->cmid == 0) {
 156                          // All modules.
 157                          $where = "eventname = :eventname AND courseid = :courseid AND timecreated > :starttime";
 158                          $params = array('eventname' => $eventobj->eventname, 'courseid' => $eventobj->courseid,
 159                                  'starttime' => $starttime);
 160                      } else {
 161                          // Specific module.
 162                          $where = "eventname = :eventname AND courseid = :courseid AND contextinstanceid = :cmid
 163                                  AND timecreated > :starttime";
 164                          $params = array('eventname' => $eventobj->eventname, 'courseid' => $eventobj->courseid,
 165                                  'cmid' => $eventobj->contextinstanceid, 'starttime' => $starttime);
 166  
 167                      }
 168                  }
 169                  $sql = $select . "WHERE " . $where;
 170                  $count = $DB->count_records_sql($sql, $params);
 171                  if (!empty($count) && $count >= $subscription->frequency) {
 172                      $idstosend[] = $subscription->id;
 173  
 174                      // Trigger a subscription_criteria_met event.
 175                      // It's possible that the course has been deleted since the criteria was met, so in that case use
 176                      // the system context. Set it here and change later if needed.
 177                      $context = \context_system::instance();
 178                      // We can't perform if (!empty($subscription->courseid)) below as it uses the magic method
 179                      // __get to return the variable, which will always result in being empty.
 180                      $courseid = $subscription->courseid;
 181                      if (!empty($courseid)) {
 182                          if ($coursecontext = \context_course::instance($courseid, IGNORE_MISSING)) {
 183                              $context = $coursecontext;
 184                          }
 185                      }
 186  
 187                      $params = array(
 188                          'userid' => $subscription->userid,
 189                          'courseid' => $subscription->courseid,
 190                          'context' => $context,
 191                          'other' => array(
 192                              'subscriptionid' => $subscription->id
 193                          )
 194                      );
 195                      $event = \tool_monitor\event\subscription_criteria_met::create($params);
 196                      $event->trigger();
 197                  }
 198              }
 199              if (!empty($idstosend)) {
 200                  $messagestosend[] = array('subscriptionids' => $idstosend, 'event' => $eventobj);
 201                  $allsubids = array_merge($allsubids, $idstosend);
 202              }
 203          }
 204  
 205          if (!empty($allsubids)) {
 206              // Update the last trigger flag.
 207              list($sql, $params) = $DB->get_in_or_equal($allsubids, SQL_PARAMS_NAMED);
 208              $params['now'] = $now;
 209              $sql = "UPDATE {tool_monitor_subscriptions} SET lastnotificationsent = :now WHERE id $sql";
 210              $DB->execute($sql, $params);
 211          }
 212  
 213          // Schedule a task to send notification.
 214          if (!empty($messagestosend)) {
 215              $adhocktask = new notification_task();
 216              $adhocktask->set_custom_data($messagestosend);
 217              $adhocktask->set_component('tool_monitor');
 218              \core\task\manager::queue_adhoc_task($adhocktask);
 219          }
 220      }
 221  
 222      /**
 223       * Protected method that flushes the buffer of events and writes them to the database.
 224       *
 225       * @return array a copy of the events buffer.
 226       */
 227      protected function flush() {
 228          global $DB;
 229  
 230          // Flush the buffer to the db.
 231          $events = $this->buffer;
 232          $DB->insert_records('tool_monitor_events', $events); // Insert the whole chunk into the database.
 233          $this->buffer = array();
 234          $this->count = 0;
 235          return $events;
 236      }
 237  
 238      /**
 239       * Observer that monitors user deleted event and delete user subscriptions.
 240       *
 241       * @param \core\event\user_deleted $event the event object.
 242       */
 243      public static function user_deleted(\core\event\user_deleted $event) {
 244          $userid = $event->objectid;
 245          subscription_manager::delete_user_subscriptions($userid);
 246      }
 247  
 248      /**
 249       * Observer that monitors course module deleted event and delete user subscriptions.
 250       *
 251       * @param \core\event\course_module_deleted $event the event object.
 252       */
 253      public static function course_module_deleted(\core\event\course_module_deleted $event) {
 254          $cmid = $event->contextinstanceid;
 255          subscription_manager::delete_cm_subscriptions($cmid);
 256      }
 257  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1