[ Index ]

PHP Cross Reference of moodle-2.8

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 <[email protected]>
  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 <[email protected]>
  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                  $starttime = $now - $subscription->timewindow;
 144                  $starttime = ($starttime > $subscription->lastnotificationsent) ? $starttime : $subscription->lastnotificationsent;
 145                  if ($subscription->courseid == 0) {
 146                      // Site level subscription. Count all events.
 147                      $where = "eventname = :eventname AND timecreated >  :starttime";
 148                      $params = array('eventname' => $eventobj->eventname, 'starttime' => $starttime);
 149                  } else {
 150                      // Course level subscription.
 151                      if ($subscription->cmid == 0) {
 152                          // All modules.
 153                          $where = "eventname = :eventname AND courseid = :courseid AND timecreated > :starttime";
 154                          $params = array('eventname' => $eventobj->eventname, 'courseid' => $eventobj->courseid,
 155                                  'starttime' => $starttime);
 156                      } else {
 157                          // Specific module.
 158                          $where = "eventname = :eventname AND courseid = :courseid AND contextinstanceid = :cmid
 159                                  AND timecreated > :starttime";
 160                          $params = array('eventname' => $eventobj->eventname, 'courseid' => $eventobj->courseid,
 161                                  'cmid' => $eventobj->contextinstanceid, 'starttime' => $starttime);
 162  
 163                      }
 164                  }
 165                  $sql = $select . "WHERE " . $where;
 166                  $count = $DB->count_records_sql($sql, $params);
 167                  if (!empty($count) && $count >= $subscription->frequency) {
 168                      $idstosend[] = $subscription->id;
 169  
 170                      // Trigger a subscription_criteria_met event.
 171                      // It's possible that the course has been deleted since the criteria was met, so in that case use
 172                      // the system context. Set it here and change later if needed.
 173                      $context = \context_system::instance();
 174                      // We can't perform if (!empty($subscription->courseid)) below as it uses the magic method
 175                      // __get to return the variable, which will always result in being empty.
 176                      $courseid = $subscription->courseid;
 177                      if (!empty($courseid)) {
 178                          if ($coursecontext = \context_course::instance($courseid, IGNORE_MISSING)) {
 179                              $context = $coursecontext;
 180                          }
 181                      }
 182  
 183                      $params = array(
 184                          'userid' => $subscription->userid,
 185                          'courseid' => $subscription->courseid,
 186                          'context' => $context,
 187                          'other' => array(
 188                              'subscriptionid' => $subscription->id
 189                          )
 190                      );
 191                      $event = \tool_monitor\event\subscription_criteria_met::create($params);
 192                      $event->trigger();
 193                  }
 194              }
 195              if (!empty($idstosend)) {
 196                  $messagestosend[] = array('subscriptionids' => $idstosend, 'event' => $eventobj);
 197                  $allsubids = array_merge($allsubids, $idstosend);
 198              }
 199          }
 200  
 201          if (!empty($allsubids)) {
 202              // Update the last trigger flag.
 203              list($sql, $params) = $DB->get_in_or_equal($allsubids, SQL_PARAMS_NAMED);
 204              $params['now'] = $now;
 205              $sql = "UPDATE {tool_monitor_subscriptions} SET lastnotificationsent = :now WHERE id $sql";
 206              $DB->execute($sql, $params);
 207          }
 208  
 209          // Schedule a task to send notification.
 210          if (!empty($messagestosend)) {
 211              $adhocktask = new notification_task();
 212              $adhocktask->set_custom_data($messagestosend);
 213              $adhocktask->set_component('tool_monitor');
 214              \core\task\manager::queue_adhoc_task($adhocktask);
 215          }
 216      }
 217  
 218      /**
 219       * Protected method that flushes the buffer of events and writes them to the database.
 220       *
 221       * @return array a copy of the events buffer.
 222       */
 223      protected function flush() {
 224          global $DB;
 225  
 226          // Flush the buffer to the db.
 227          $events = $this->buffer;
 228          $DB->insert_records('tool_monitor_events', $events); // Insert the whole chunk into the database.
 229          $this->buffer = array();
 230          $this->count = 0;
 231          return $events;
 232      }
 233  
 234      /**
 235       * Observer that monitors user deleted event and delete user subscriptions.
 236       *
 237       * @param \core\event\user_deleted $event the event object.
 238       */
 239      public static function user_deleted(\core\event\user_deleted $event) {
 240          $userid = $event->objectid;
 241          subscription_manager::delete_user_subscriptions($userid);
 242      }
 243  
 244      /**
 245       * Observer that monitors course module deleted event and delete user subscriptions.
 246       *
 247       * @param \core\event\course_module_deleted $event the event object.
 248       */
 249      public static function course_module_deleted(\core\event\course_module_deleted $event) {
 250          $cmid = $event->contextinstanceid;
 251          subscription_manager::delete_cm_subscriptions($cmid);
 252      }
 253  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1