Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [Versions 401 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  use core_external\external_api;
  18  use core_external\external_function_parameters;
  19  use core_external\external_multiple_structure;
  20  use core_external\external_single_structure;
  21  use core_external\external_value;
  22  use core_external\external_warnings;
  23  
  24  /**
  25   * External API for airnotifier web services
  26   *
  27   * @package    message_airnotifier
  28   * @category   external
  29   * @copyright  2012 Jerome Mouneyrac <jerome@moodle.com>
  30   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  31   * @since Moodle 2.7
  32   */
  33  class message_airnotifier_external extends external_api {
  34  
  35      /**
  36       * Returns description of method parameters
  37       *
  38       * @since Moodle 2.7
  39       */
  40      public static function is_system_configured_parameters() {
  41          return new external_function_parameters(
  42                  array()
  43          );
  44      }
  45  
  46      /**
  47       * Tests whether the airnotifier settings have been configured
  48       *
  49       * @since Moodle 2.7
  50       */
  51      public static function is_system_configured() {
  52          global $DB;
  53  
  54          // First, check if the plugin is disabled.
  55          $processor = $DB->get_record('message_processors', array('name' => 'airnotifier'), '*', MUST_EXIST);
  56          if (!$processor->enabled) {
  57              return 0;
  58          }
  59  
  60          // Then, check if the plugin is completly configured.
  61          $manager = new message_airnotifier_manager();
  62          return (int) $manager->is_system_configured();
  63      }
  64  
  65      /**
  66       * Returns description of method result value
  67       *
  68       * @return external_single_structure
  69       * @since Moodle 2.7
  70       */
  71      public static function is_system_configured_returns() {
  72          return new external_value( PARAM_INT, '0 if the system is not configured, 1 otherwise');
  73      }
  74  
  75      /**
  76       * Returns description of method parameters
  77       *
  78       * @since Moodle 2.7
  79       */
  80      public static function are_notification_preferences_configured_parameters() {
  81          return new external_function_parameters(
  82                  array(
  83                      'userids' => new external_multiple_structure(new external_value(PARAM_INT, 'user ID')),
  84                  )
  85          );
  86      }
  87  
  88      /**
  89       * Check if the users have notification preferences configured for the airnotifier plugin
  90       *
  91       * @param array $userids Array of user ids
  92       * @since Moodle 2.7
  93       */
  94      public static function are_notification_preferences_configured($userids) {
  95          global $CFG, $USER, $DB;
  96  
  97          require_once($CFG->dirroot . '/message/lib.php');
  98          $params = self::validate_parameters(self::are_notification_preferences_configured_parameters(),
  99                  array('userids' => $userids));
 100  
 101          list($sqluserids, $params) = $DB->get_in_or_equal($params['userids'], SQL_PARAMS_NAMED);
 102          $uselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
 103          $ujoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = u.id AND ctx.contextlevel = :contextlevel)";
 104          $params['contextlevel'] = CONTEXT_USER;
 105          $usersql = "SELECT u.* $uselect
 106                        FROM {user} u $ujoin
 107                       WHERE u.id $sqluserids";
 108          $users = $DB->get_recordset_sql($usersql, $params);
 109  
 110          $result = array(
 111              'users' => [],
 112              'warnings' => []
 113          );
 114          $hasuserupdatecap = has_capability('moodle/user:update', context_system::instance());
 115          foreach ($users as $user) {
 116  
 117              $currentuser = ($user->id == $USER->id);
 118  
 119              if ($currentuser or $hasuserupdatecap) {
 120  
 121                  if (!empty($user->deleted)) {
 122                      $warning = [];
 123                      $warning['item'] = 'user';
 124                      $warning['itemid'] = $user->id;
 125                      $warning['warningcode'] = '1';
 126                      $warning['message'] = "User $user->id was deleted";
 127                      $result['warnings'][] = $warning;
 128                      continue;
 129                  }
 130  
 131                  $preferences = [];
 132                  $preferences['userid'] = $user->id;
 133                  $preferences['configured'] = 0;
 134  
 135                  // Now we get for all the providers and all the states
 136                  // the user preferences to check if at least one is enabled for airnotifier plugin.
 137                  $providers = message_get_providers_for_user($user->id);
 138                  $configured = false;
 139  
 140                  foreach ($providers as $provider) {
 141                      if ($configured) {
 142                          break;
 143                      }
 144  
 145                      $prefstocheck = [];
 146                      $prefname = 'message_provider_'.$provider->component.'_'.$provider->name.'_enabled';
 147  
 148                      // First get forced settings.
 149                      if ($forcedpref = get_config('message', $prefname)) {
 150                          $prefstocheck = array_merge($prefstocheck, explode(',', $forcedpref));
 151                      }
 152  
 153                      // Then get user settings.
 154                      if ($userpref = get_user_preferences($prefname, '', $user->id)) {
 155                          $prefstocheck = array_merge($prefstocheck, explode(',', $userpref));
 156                      }
 157  
 158                      if (in_array('airnotifier', $prefstocheck)) {
 159                          $preferences['configured'] = 1;
 160                          $configured = true;
 161                          break;
 162                      }
 163                  }
 164  
 165                  $result['users'][] = $preferences;
 166              } else if (!$hasuserupdatecap) {
 167                  $warning = [];
 168                  $warning['item'] = 'user';
 169                  $warning['itemid'] = $user->id;
 170                  $warning['warningcode'] = '2';
 171                  $warning['message'] = "You don't have permissions for view user $user->id preferences";
 172                  $result['warnings'][] = $warning;
 173              }
 174  
 175          }
 176          $users->close();
 177  
 178          return $result;
 179      }
 180  
 181      /**
 182       * Returns description of method result value
 183       *
 184       * @return external_single_structure
 185       * @since Moodle 2.7
 186       */
 187      public static function are_notification_preferences_configured_returns() {
 188          return new external_single_structure(
 189              array(
 190                  'users' => new external_multiple_structure(
 191                      new external_single_structure(
 192                          array (
 193                              'userid'     => new external_value(PARAM_INT, 'userid id'),
 194                              'configured' => new external_value(PARAM_INT,
 195                                  '1 if the user preferences have been configured and 0 if not')
 196                          )
 197                      ),
 198                      'list of preferences by user'),
 199                  'warnings' => new external_warnings()
 200              )
 201          );
 202      }
 203  
 204      /**
 205       * Returns description of method parameters
 206       *
 207       * @since Moodle 3.2
 208       */
 209      public static function get_user_devices_parameters() {
 210          return new external_function_parameters(
 211              array(
 212                  'appid' => new external_value(PARAM_NOTAGS, 'App unique id (usually a reversed domain)'),
 213                  'userid' => new external_value(PARAM_INT, 'User id, 0 for current user', VALUE_DEFAULT, 0)
 214              )
 215          );
 216      }
 217  
 218      /**
 219       * Return the list of mobile devices that are registered in Moodle for the given user.
 220       *
 221       * @param  string  $appid  app unique id (usually a reversed domain)
 222       * @param  integer $userid the user id, 0 for current user
 223       * @return array warnings and devices
 224       * @throws moodle_exception
 225       * @since Moodle 3.2
 226       */
 227      public static function get_user_devices($appid, $userid = 0) {
 228          global $USER;
 229  
 230          $params = self::validate_parameters(
 231              self::get_user_devices_parameters(),
 232              array(
 233                  'appid' => $appid,
 234                  'userid' => $userid,
 235              )
 236          );
 237  
 238          $context = context_system::instance();
 239          self::validate_context($context);
 240  
 241          if (empty($params['userid'])) {
 242              $user = $USER;
 243          } else {
 244              $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
 245              core_user::require_active_user($user);
 246              // Allow only admins to retrieve other users devices.
 247              if ($user->id != $USER->id) {
 248                  require_capability('moodle/site:config', $context);
 249              }
 250          }
 251  
 252          $warnings = array();
 253          $devices = array();
 254          // Check if mobile notifications are enabled.
 255          if (!self::is_system_configured()) {
 256              $warnings[] = array(
 257                  'item' => 'user',
 258                  'itemid' => $user->id,
 259                  'warningcode' => 'systemnotconfigured',
 260                  'message' => 'Mobile notifications are not configured'
 261              );
 262          } else {
 263              // We catch exceptions here because get_user_devices may try to connect to Airnotifier.
 264              try {
 265                  $manager = new message_airnotifier_manager();
 266                  $devices = $manager->get_user_devices($appid, $user->id);
 267              } catch (Exception $e) {
 268                  $warnings[] = array(
 269                      'item' => 'user',
 270                      'itemid' => $user->id,
 271                      'warningcode' => 'errorgettingdevices',
 272                      'message' => $e->getMessage()
 273                  );
 274              }
 275          }
 276  
 277          return array(
 278              'devices' => $devices,
 279              'warnings' => $warnings
 280          );
 281      }
 282  
 283      /**
 284       * Returns description of method result value
 285       *
 286       * @return external_single_structure
 287       * @since Moodle 3.2
 288       */
 289      public static function get_user_devices_returns() {
 290          return new external_single_structure(
 291              array(
 292                  'devices' => new external_multiple_structure(
 293                      new external_single_structure(
 294                          array (
 295                              'id' => new external_value(PARAM_INT, 'Device id (in the message_airnotifier table)'),
 296                              'appid' => new external_value(PARAM_NOTAGS, 'The app id, something like com.moodle.moodlemobile'),
 297                              'name' => new external_value(PARAM_NOTAGS, 'The device name, \'occam\' or \'iPhone\' etc.'),
 298                              'model' => new external_value(PARAM_NOTAGS, 'The device model \'Nexus4\' or \'iPad1,1\' etc.'),
 299                              'platform' => new external_value(PARAM_NOTAGS, 'The device platform \'iOS\' or \'Android\' etc.'),
 300                              'version' => new external_value(PARAM_NOTAGS, 'The device version \'6.1.2\' or \'4.2.2\' etc.'),
 301                              'pushid' => new external_value(PARAM_RAW, 'The device PUSH token/key/identifier/registration id'),
 302                              'uuid' => new external_value(PARAM_RAW, 'The device UUID'),
 303                              'enable' => new external_value(PARAM_INT, 'Whether the device is enabled or not'),
 304                              'timecreated' => new external_value(PARAM_INT, 'Time created'),
 305                              'timemodified' => new external_value(PARAM_INT, 'Time modified'),
 306                          )
 307                      ),
 308                      'List of devices'
 309                  ),
 310                  'warnings' => new external_warnings()
 311              )
 312          );
 313      }
 314  
 315      /**
 316       * Returns description of method parameters
 317       *
 318       * @since Moodle 3.2
 319       */
 320      public static function enable_device_parameters() {
 321          return new external_function_parameters(
 322              array(
 323                  'deviceid' => new external_value(PARAM_INT, 'The device id'),
 324                  'enable' => new external_value(PARAM_BOOL, 'True for enable the device, false otherwise')
 325              )
 326          );
 327      }
 328  
 329      /**
 330       * Enables or disables a registered user device so it can receive Push notifications
 331       *
 332       * @param  integer $deviceid the device id
 333       * @param  bool $enable whether to enable the device
 334       * @return array warnings and success status
 335       * @throws moodle_exception
 336       * @since Moodle 3.2
 337       */
 338      public static function enable_device($deviceid, $enable) {
 339          global $USER;
 340  
 341          $params = self::validate_parameters(
 342              self::enable_device_parameters(),
 343              array(
 344                  'deviceid' => $deviceid,
 345                  'enable' => $enable,
 346              )
 347          );
 348  
 349          $context = context_system::instance();
 350          self::validate_context($context);
 351          require_capability('message/airnotifier:managedevice', $context);
 352  
 353          if (!message_airnotifier_manager::enable_device($params['deviceid'], $params['enable'])) {
 354              throw new moodle_exception('unknowndevice', 'message_airnotifier');
 355          }
 356  
 357          return array(
 358              'success' => true,
 359              'warnings' => array()
 360          );
 361      }
 362  
 363      /**
 364       * Returns description of method result value
 365       *
 366       * @return external_single_structure
 367       * @since Moodle 3.2
 368       */
 369      public static function enable_device_returns() {
 370          return new external_single_structure(
 371              array(
 372                  'success' => new external_value(PARAM_BOOL, 'True if success'),
 373                  'warnings' => new external_warnings()
 374              )
 375          );
 376      }
 377  }