Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

   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   * Airnotifier manager class
  19   *
  20   * @package    message_airnotifier
  21   * @category   external
  22   * @copyright  2012 Jerome Mouneyrac <jerome@moodle.com>
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   * @since Moodle 2.7
  25   */
  26  
  27  defined('MOODLE_INTERNAL') || die;
  28  
  29  /**
  30   * Airnotifier helper manager class
  31   *
  32   * @copyright  2012 Jerome Mouneyrac <jerome@moodle.com>
  33   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  34   */
  35  class message_airnotifier_manager {
  36  
  37      /** @var string The Airnotifier public instance URL */
  38      const AIRNOTIFIER_PUBLICURL = 'https://messages.moodle.net';
  39  
  40      /**
  41       * Include the relevant javascript and language strings for the device
  42       * toolbox YUI module
  43       *
  44       * @return bool
  45       */
  46      public function include_device_ajax() {
  47          global $PAGE, $CFG;
  48  
  49          $config = new stdClass();
  50          $config->resturl = '/message/output/airnotifier/rest.php';
  51          $config->pageparams = array();
  52  
  53          // Include toolboxes.
  54          $PAGE->requires->yui_module('moodle-message_airnotifier-toolboxes', 'M.message.init_device_toolbox', array(array(
  55                  'ajaxurl' => $config->resturl,
  56                  'config' => $config,
  57                  ))
  58          );
  59  
  60          // Required strings for the javascript.
  61          $PAGE->requires->strings_for_js(array('deletecheckdevicename'), 'message_airnotifier');
  62          $PAGE->requires->strings_for_js(array('show', 'hide'), 'moodle');
  63  
  64          return true;
  65      }
  66  
  67      /**
  68       * Return the user devices for a specific app.
  69       *
  70       * @param string $appname the app name .
  71       * @param int $userid if empty take the current user.
  72       * @return array all the devices
  73       */
  74      public function get_user_devices($appname, $userid = null) {
  75          global $USER, $DB;
  76  
  77          if (empty($userid)) {
  78              $userid = $USER->id;
  79          }
  80  
  81          $devices = array();
  82  
  83          $params = array('appid' => $appname, 'userid' => $userid);
  84  
  85          // First, we look all the devices registered for this user in the Moodle core.
  86          // We are going to allow only ios devices (since these are the ones that supports PUSH notifications).
  87          $userdevices = $DB->get_records('user_devices', $params);
  88          foreach ($userdevices as $device) {
  89              if (core_text::strtolower($device->platform)) {
  90                  // Check if the device is known by airnotifier.
  91                  if (!$airnotifierdev = $DB->get_record('message_airnotifier_devices',
  92                          array('userdeviceid' => $device->id))) {
  93  
  94                      // We have to create the device token in airnotifier.
  95                      if (! $this->create_token($device->pushid, $device->platform)) {
  96                          continue;
  97                      }
  98  
  99                      $airnotifierdev = new stdClass;
 100                      $airnotifierdev->userdeviceid = $device->id;
 101                      $airnotifierdev->enable = 1;
 102                      $airnotifierdev->id = $DB->insert_record('message_airnotifier_devices', $airnotifierdev);
 103                  }
 104                  $device->id = $airnotifierdev->id;
 105                  $device->enable = $airnotifierdev->enable;
 106                  $devices[] = $device;
 107              }
 108          }
 109  
 110          return $devices;
 111      }
 112  
 113      /**
 114       * Request and access key to Airnotifier
 115       *
 116       * @return mixed The access key or false in case of error
 117       */
 118      public function request_accesskey() {
 119          global $CFG, $USER;
 120  
 121          require_once($CFG->libdir . '/filelib.php');
 122  
 123          // Sending the request access key request to Airnotifier.
 124          $serverurl = $CFG->airnotifierurl . ':' . $CFG->airnotifierport . '/accesskeys/';
 125          // We use an APP Key "none", it can be anything.
 126          $header = array('Accept: application/json', 'X-AN-APP-NAME: ' . $CFG->airnotifierappname,
 127              'X-AN-APP-KEY: none');
 128          $curl = new curl();
 129          $curl->setHeader($header);
 130  
 131          // Site ids are stored as secrets in md5 in the Moodle public hub.
 132          $params = array(
 133              'url' => $CFG->wwwroot,
 134              'siteid' => md5($CFG->siteidentifier),
 135              'contact' => $USER->email,
 136              'description' => $CFG->wwwroot
 137              );
 138          $resp = $curl->post($serverurl, $params);
 139  
 140          if ($key = json_decode($resp, true)) {
 141              if (!empty($key['accesskey'])) {
 142                  return $key['accesskey'];
 143              }
 144          }
 145          debugging("Unexpected response from the Airnotifier server: $resp");
 146          return false;
 147      }
 148  
 149      /**
 150       * Create a device token in the Airnotifier instance
 151       * @param string $token The token to be created
 152       * @param string $deviceplatform The device platform (Android, iOS, iOS-fcm, etc...)
 153       * @return bool True if all was right
 154       */
 155      private function create_token($token, $deviceplatform = '') {
 156          global $CFG;
 157  
 158          if (!$this->is_system_configured()) {
 159              return false;
 160          }
 161  
 162          require_once($CFG->libdir . '/filelib.php');
 163  
 164          $serverurl = $CFG->airnotifierurl . ':' . $CFG->airnotifierport . '/tokens/' . $token;
 165          $header = array('Accept: application/json', 'X-AN-APP-NAME: ' . $CFG->airnotifierappname,
 166              'X-AN-APP-KEY: ' . $CFG->airnotifieraccesskey);
 167          $curl = new curl;
 168          $curl->setHeader($header);
 169          $params = [];
 170          if (!empty($deviceplatform)) {
 171              $params["device"] = $deviceplatform;
 172          }
 173          $resp = $curl->post($serverurl, $params);
 174  
 175          if ($token = json_decode($resp, true)) {
 176              if (!empty($token['status'])) {
 177                  return $token['status'] == 'ok' || $token['status'] == 'token exists';
 178              }
 179          }
 180          debugging("Unexpected response from the Airnotifier server: $resp");
 181          return false;
 182      }
 183  
 184      /**
 185       * Tests whether the airnotifier settings have been configured
 186       * @return boolean true if airnotifier is configured
 187       */
 188      public function is_system_configured() {
 189          global $CFG;
 190  
 191          return (!empty($CFG->airnotifierurl) && !empty($CFG->airnotifierport) &&
 192                  !empty($CFG->airnotifieraccesskey)  && !empty($CFG->airnotifierappname) &&
 193                  !empty($CFG->airnotifiermobileappname));
 194      }
 195  
 196      /**
 197       * Enables or disables a registered user device so it can receive Push notifications
 198       *
 199       * @param  int $deviceid the device id
 200       * @param  bool $enable  true to enable it, false to disable it
 201       * @return bool true if the device was enabled, false in case of error
 202       * @since  Moodle 3.2
 203       */
 204      public static function enable_device($deviceid, $enable) {
 205          global $DB, $USER;
 206  
 207          if (!$device = $DB->get_record('message_airnotifier_devices', array('id' => $deviceid), '*')) {
 208              return false;
 209          }
 210  
 211          // Check that the device belongs to the current user.
 212          if (!$userdevice = $DB->get_record('user_devices', array('id' => $device->userdeviceid, 'userid' => $USER->id), '*')) {
 213              return false;
 214          }
 215  
 216          $device->enable = $enable;
 217          return $DB->update_record('message_airnotifier_devices', $device);
 218      }
 219  
 220  }