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  /**
  18   * Chat external API
  19   *
  20   * @package    mod_chat
  21   * @category   external
  22   * @copyright  2015 Juan Leyva <juan@moodle.com>
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   * @since      Moodle 3.0
  25   */
  26  
  27  defined('MOODLE_INTERNAL') || die;
  28  
  29  require_once($CFG->dirroot . '/mod/chat/lib.php');
  30  
  31  use core_course\external\helper_for_get_mods_by_courses;
  32  use core_external\external_api;
  33  use core_external\external_function_parameters;
  34  use core_external\external_multiple_structure;
  35  use core_external\external_single_structure;
  36  use core_external\external_value;
  37  use core_external\external_warnings;
  38  use core_external\util;
  39  use mod_chat\external\chat_message_exporter;
  40  
  41  /**
  42   * Chat external functions
  43   *
  44   * @package    mod_chat
  45   * @category   external
  46   * @copyright  2015 Juan Leyva <juan@moodle.com>
  47   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  48   * @since      Moodle 3.0
  49   */
  50  class mod_chat_external extends external_api {
  51  
  52      /**
  53       * Returns description of method parameters
  54       *
  55       * @return external_function_parameters
  56       * @since Moodle 3.0
  57       */
  58      public static function login_user_parameters() {
  59          return new external_function_parameters(
  60              array(
  61                  'chatid' => new external_value(PARAM_INT, 'chat instance id'),
  62                  'groupid' => new external_value(PARAM_INT, 'group id, 0 means that the function will determine the user group',
  63                                                  VALUE_DEFAULT, 0),
  64              )
  65          );
  66      }
  67  
  68      /**
  69       * Log the current user into a chat room in the given chat.
  70       *
  71       * @param int $chatid the chat instance id
  72       * @param int $groupid the user group id
  73       * @return array of warnings and the chat unique session id
  74       * @since Moodle 3.0
  75       * @throws moodle_exception
  76       */
  77      public static function login_user($chatid, $groupid = 0) {
  78          global $DB;
  79  
  80          $params = self::validate_parameters(self::login_user_parameters(),
  81                                              array(
  82                                                  'chatid' => $chatid,
  83                                                  'groupid' => $groupid
  84                                              ));
  85          $warnings = array();
  86  
  87          // Request and permission validation.
  88          $chat = $DB->get_record('chat', array('id' => $params['chatid']), '*', MUST_EXIST);
  89          list($course, $cm) = get_course_and_cm_from_instance($chat, 'chat');
  90  
  91          $context = context_module::instance($cm->id);
  92          self::validate_context($context);
  93  
  94          require_capability('mod/chat:chat', $context);
  95  
  96          if (!empty($params['groupid'])) {
  97              $groupid = $params['groupid'];
  98              // Determine is the group is visible to user.
  99              if (!groups_group_visible($groupid, $course, $cm)) {
 100                  throw new moodle_exception('notingroup');
 101              }
 102          } else {
 103              // Check to see if groups are being used here.
 104              if ($groupmode = groups_get_activity_groupmode($cm)) {
 105                  $groupid = groups_get_activity_group($cm);
 106                  // Determine is the group is visible to user (this is particullary for the group 0).
 107                  if (!groups_group_visible($groupid, $course, $cm)) {
 108                      throw new moodle_exception('notingroup');
 109                  }
 110              } else {
 111                  $groupid = 0;
 112              }
 113          }
 114  
 115          // Get the unique chat session id.
 116          // Since we are going to use the chat via Web Service requests we set the ajax version (since it's the most similar).
 117          if (!$chatsid = chat_login_user($chat->id, 'ajax', $groupid, $course)) {
 118              throw new moodle_exception('cantlogin', 'chat');
 119          }
 120  
 121          $result = array();
 122          $result['chatsid'] = $chatsid;
 123          $result['warnings'] = $warnings;
 124          return $result;
 125      }
 126  
 127      /**
 128       * Returns description of method result value
 129       *
 130       * @return \core_external\external_description
 131       * @since Moodle 3.0
 132       */
 133      public static function login_user_returns() {
 134          return new external_single_structure(
 135              array(
 136                  'chatsid' => new external_value(PARAM_ALPHANUM, 'unique chat session id'),
 137                  'warnings' => new external_warnings()
 138              )
 139          );
 140      }
 141  
 142      /**
 143       * Returns description of method parameters
 144       *
 145       * @return external_function_parameters
 146       * @since Moodle 3.0
 147       */
 148      public static function get_chat_users_parameters() {
 149          return new external_function_parameters(
 150              array(
 151                  'chatsid' => new external_value(PARAM_ALPHANUM, 'chat session id (obtained via mod_chat_login_user)')
 152              )
 153          );
 154      }
 155  
 156      /**
 157       * Get the list of users in the given chat session.
 158       *
 159       * @param int $chatsid the chat session id
 160       * @return array of warnings and the user lists
 161       * @since Moodle 3.0
 162       * @throws moodle_exception
 163       */
 164      public static function get_chat_users($chatsid) {
 165          global $DB, $PAGE;
 166  
 167          $params = self::validate_parameters(self::get_chat_users_parameters(),
 168                                              array(
 169                                                  'chatsid' => $chatsid
 170                                              ));
 171          $warnings = array();
 172  
 173          // Request and permission validation.
 174          if (!$chatuser = $DB->get_record('chat_users', array('sid' => $params['chatsid']))) {
 175              throw new moodle_exception('notlogged', 'chat');
 176          }
 177          $chat = $DB->get_record('chat', array('id' => $chatuser->chatid), '*', MUST_EXIST);
 178          list($course, $cm) = get_course_and_cm_from_instance($chat, 'chat');
 179  
 180          $context = context_module::instance($cm->id);
 181          self::validate_context($context);
 182  
 183          require_capability('mod/chat:chat', $context);
 184  
 185          // First, delete old users from the chats.
 186          chat_delete_old_users();
 187  
 188          $users = chat_get_users($chatuser->chatid, $chatuser->groupid, $cm->groupingid);
 189          $returnedusers = array();
 190  
 191          foreach ($users as $user) {
 192  
 193              $userpicture = new user_picture($user);
 194              $userpicture->size = 1; // Size f1.
 195              $profileimageurl = $userpicture->get_url($PAGE)->out(false);
 196  
 197              $returnedusers[] = array(
 198                  'id' => $user->id,
 199                  'fullname' => fullname($user),
 200                  'profileimageurl' => $profileimageurl
 201              );
 202          }
 203  
 204          $result = array();
 205          $result['users'] = $returnedusers;
 206          $result['warnings'] = $warnings;
 207          return $result;
 208      }
 209  
 210      /**
 211       * Returns description of method result value
 212       *
 213       * @return \core_external\external_description
 214       * @since Moodle 3.0
 215       */
 216      public static function get_chat_users_returns() {
 217          return new external_single_structure(
 218              array(
 219                  'users' => new external_multiple_structure(
 220                      new external_single_structure(
 221                          array(
 222                              'id' => new external_value(PARAM_INT, 'user id'),
 223                              'fullname' => new external_value(PARAM_NOTAGS, 'user full name'),
 224                              'profileimageurl' => new external_value(PARAM_URL, 'user picture URL'),
 225                          )
 226                      ),
 227                      'list of users'
 228                  ),
 229                  'warnings' => new external_warnings()
 230              )
 231          );
 232      }
 233  
 234      /**
 235       * Returns description of method parameters
 236       *
 237       * @return external_function_parameters
 238       * @since Moodle 3.0
 239       */
 240      public static function send_chat_message_parameters() {
 241          return new external_function_parameters(
 242              array(
 243                  'chatsid' => new external_value(PARAM_ALPHANUM, 'chat session id (obtained via mod_chat_login_user)'),
 244                  'messagetext' => new external_value(PARAM_RAW, 'the message text'),
 245                  'beepid' => new external_value(PARAM_RAW, 'the beep id', VALUE_DEFAULT, ''),
 246  
 247              )
 248          );
 249      }
 250  
 251      /**
 252       * Send a message on the given chat session.
 253       *
 254       * @param int $chatsid the chat session id
 255       * @param string $messagetext the message text
 256       * @param string $beepid the beep message id
 257       * @return array of warnings and the new message id (0 if the message was empty)
 258       * @since Moodle 3.0
 259       * @throws moodle_exception
 260       */
 261      public static function send_chat_message($chatsid, $messagetext, $beepid = '') {
 262          global $DB;
 263  
 264          $params = self::validate_parameters(self::send_chat_message_parameters(),
 265                                              array(
 266                                                  'chatsid' => $chatsid,
 267                                                  'messagetext' => $messagetext,
 268                                                  'beepid' => $beepid
 269                                              ));
 270          $warnings = array();
 271  
 272          // Request and permission validation.
 273          if (!$chatuser = $DB->get_record('chat_users', array('sid' => $params['chatsid']))) {
 274              throw new moodle_exception('notlogged', 'chat');
 275          }
 276          $chat = $DB->get_record('chat', array('id' => $chatuser->chatid), '*', MUST_EXIST);
 277          list($course, $cm) = get_course_and_cm_from_instance($chat, 'chat');
 278  
 279          $context = context_module::instance($cm->id);
 280          self::validate_context($context);
 281  
 282          require_capability('mod/chat:chat', $context);
 283  
 284          $chatmessage = clean_text($params['messagetext'], FORMAT_MOODLE);
 285  
 286          if (!empty($params['beepid'])) {
 287              $chatmessage = 'beep ' . $params['beepid'];
 288          }
 289  
 290          if (!empty($chatmessage)) {
 291              // Send the message.
 292              $messageid = chat_send_chatmessage($chatuser, $chatmessage, 0, $cm);
 293              // Update ping time.
 294              $chatuser->lastmessageping = time() - 2;
 295              $DB->update_record('chat_users', $chatuser);
 296          } else {
 297              $messageid = 0;
 298          }
 299  
 300          $result = array();
 301          $result['messageid'] = $messageid;
 302          $result['warnings'] = $warnings;
 303          return $result;
 304      }
 305  
 306      /**
 307       * Returns description of method result value
 308       *
 309       * @return \core_external\external_description
 310       * @since Moodle 3.0
 311       */
 312      public static function send_chat_message_returns() {
 313          return new external_single_structure(
 314              array(
 315                  'messageid' => new external_value(PARAM_INT, 'message sent id'),
 316                  'warnings' => new external_warnings()
 317              )
 318          );
 319      }
 320  
 321      /**
 322       * Returns description of method parameters
 323       *
 324       * @return external_function_parameters
 325       * @since Moodle 3.0
 326       */
 327      public static function get_chat_latest_messages_parameters() {
 328          return new external_function_parameters(
 329              array(
 330                  'chatsid' => new external_value(PARAM_ALPHANUM, 'chat session id (obtained via mod_chat_login_user)'),
 331                  'chatlasttime' => new external_value(PARAM_INT, 'last time messages were retrieved (epoch time)', VALUE_DEFAULT, 0)
 332              )
 333          );
 334      }
 335  
 336      /**
 337       * Get the latest messages from the given chat session.
 338       *
 339       * @param int $chatsid the chat session id
 340       * @param int $chatlasttime last time messages were retrieved (epoch time)
 341       * @return array of warnings and the new message id (0 if the message was empty)
 342       * @since Moodle 3.0
 343       * @throws moodle_exception
 344       */
 345      public static function get_chat_latest_messages($chatsid, $chatlasttime = 0) {
 346          global $DB, $CFG;
 347  
 348          $params = self::validate_parameters(self::get_chat_latest_messages_parameters(),
 349                                              array(
 350                                                  'chatsid' => $chatsid,
 351                                                  'chatlasttime' => $chatlasttime
 352                                              ));
 353          $warnings = array();
 354  
 355          // Request and permission validation.
 356          if (!$chatuser = $DB->get_record('chat_users', array('sid' => $params['chatsid']))) {
 357              throw new moodle_exception('notlogged', 'chat');
 358          }
 359          $chat = $DB->get_record('chat', array('id' => $chatuser->chatid), '*', MUST_EXIST);
 360          list($course, $cm) = get_course_and_cm_from_instance($chat, 'chat');
 361  
 362          $context = context_module::instance($cm->id);
 363          self::validate_context($context);
 364  
 365          require_capability('mod/chat:chat', $context);
 366  
 367          $chatlasttime = $params['chatlasttime'];
 368          if ((time() - $chatlasttime) > $CFG->chat_old_ping) {
 369              chat_delete_old_users();
 370          }
 371  
 372          // Set default chat last time (to not retrieve all the conversations).
 373          if ($chatlasttime == 0) {
 374              $chatlasttime = time() - $CFG->chat_old_ping;
 375          }
 376  
 377          if ($latestmessage = chat_get_latest_message($chatuser->chatid, $chatuser->groupid)) {
 378              $chatnewlasttime = $latestmessage->timestamp;
 379          } else {
 380              $chatnewlasttime = 0;
 381          }
 382  
 383          $messages = chat_get_latest_messages($chatuser, $chatlasttime);
 384          $returnedmessages = array();
 385  
 386          foreach ($messages as $message) {
 387              // FORMAT_MOODLE is mandatory in the chat plugin.
 388              [$messageformatted] = \core_external\util::format_text(
 389                  $message->message,
 390                  FORMAT_MOODLE,
 391                  $context->id,
 392                  'mod_chat',
 393                  '',
 394                  0
 395              );
 396  
 397              $returnedmessages[] = array(
 398                  'id' => $message->id,
 399                  'userid' => $message->userid,
 400                  'system' => (bool) $message->issystem,
 401                  'message' => $messageformatted,
 402                  'timestamp' => $message->timestamp,
 403              );
 404          }
 405  
 406          // Update our status since we are active in the chat.
 407          $DB->set_field('chat_users', 'lastping', time(), array('id' => $chatuser->id));
 408  
 409          $result = array();
 410          $result['messages'] = $returnedmessages;
 411          $result['chatnewlasttime'] = $chatnewlasttime;
 412          $result['warnings'] = $warnings;
 413          return $result;
 414      }
 415  
 416      /**
 417       * Returns description of method result value
 418       *
 419       * @return \core_external\external_description
 420       * @since Moodle 3.0
 421       */
 422      public static function get_chat_latest_messages_returns() {
 423          return new external_single_structure(
 424              array(
 425                  'messages' => new external_multiple_structure(
 426                      new external_single_structure(
 427                          array(
 428                              'id' => new external_value(PARAM_INT, 'message id'),
 429                              'userid' => new external_value(PARAM_INT, 'user id'),
 430                              'system' => new external_value(PARAM_BOOL, 'true if is a system message (like user joined)'),
 431                              'message' => new external_value(PARAM_RAW, 'message text'),
 432                              'timestamp' => new external_value(PARAM_INT, 'timestamp for the message'),
 433                          )
 434                      ),
 435                      'list of users'
 436                  ),
 437                  'chatnewlasttime' => new external_value(PARAM_INT, 'new last time'),
 438                  'warnings' => new external_warnings()
 439              )
 440          );
 441      }
 442  
 443      /**
 444       * Returns description of method parameters
 445       *
 446       * @return external_function_parameters
 447       * @since Moodle 3.0
 448       */
 449      public static function view_chat_parameters() {
 450          return new external_function_parameters(
 451              array(
 452                  'chatid' => new external_value(PARAM_INT, 'chat instance id')
 453              )
 454          );
 455      }
 456  
 457      /**
 458       * Trigger the course module viewed event and update the module completion status.
 459       *
 460       * @param int $chatid the chat instance id
 461       * @return array of warnings and status result
 462       * @since Moodle 3.0
 463       * @throws moodle_exception
 464       */
 465      public static function view_chat($chatid) {
 466          global $DB, $CFG;
 467  
 468          $params = self::validate_parameters(self::view_chat_parameters(),
 469                                              array(
 470                                                  'chatid' => $chatid
 471                                              ));
 472          $warnings = array();
 473  
 474          // Request and permission validation.
 475          $chat = $DB->get_record('chat', array('id' => $params['chatid']), '*', MUST_EXIST);
 476          list($course, $cm) = get_course_and_cm_from_instance($chat, 'chat');
 477  
 478          $context = context_module::instance($cm->id);
 479          self::validate_context($context);
 480  
 481          require_capability('mod/chat:chat', $context);
 482  
 483          // Call the url/lib API.
 484          chat_view($chat, $course, $cm, $context);
 485  
 486          $result = array();
 487          $result['status'] = true;
 488          $result['warnings'] = $warnings;
 489          return $result;
 490      }
 491  
 492      /**
 493       * Returns description of method result value
 494       *
 495       * @return \core_external\external_description
 496       * @since Moodle 3.0
 497       */
 498      public static function view_chat_returns() {
 499          return new external_single_structure(
 500              array(
 501                  'status' => new external_value(PARAM_BOOL, 'status: true if success'),
 502                  'warnings' => new external_warnings()
 503              )
 504          );
 505      }
 506  
 507  
 508      /**
 509       * Describes the parameters for get_chats_by_courses.
 510       *
 511       * @return external_function_parameters
 512       * @since Moodle 3.0
 513       */
 514      public static function get_chats_by_courses_parameters() {
 515          return new external_function_parameters (
 516              array(
 517                  'courseids' => new external_multiple_structure(
 518                      new external_value(PARAM_INT, 'course id'), 'Array of course ids', VALUE_DEFAULT, array()
 519                  ),
 520              )
 521          );
 522      }
 523  
 524      /**
 525       * Returns a list of chats in a provided list of courses,
 526       * if no list is provided all chats that the user can view will be returned.
 527       *
 528       * @param array $courseids the course ids
 529       * @return array of chats details
 530       * @since Moodle 3.0
 531       */
 532      public static function get_chats_by_courses($courseids = array()) {
 533          global $CFG;
 534  
 535          $returnedchats = array();
 536          $warnings = array();
 537  
 538          $params = self::validate_parameters(self::get_chats_by_courses_parameters(), array('courseids' => $courseids));
 539  
 540          $courses = array();
 541          if (empty($params['courseids'])) {
 542              $courses = enrol_get_my_courses();
 543              $params['courseids'] = array_keys($courses);
 544          }
 545  
 546          // Ensure there are courseids to loop through.
 547          if (!empty($params['courseids'])) {
 548  
 549              list($courses, $warnings) = util::validate_courses($params['courseids'], $courses);
 550  
 551              // Get the chats in this course, this function checks users visibility permissions.
 552              // We can avoid then additional validate_context calls.
 553              $chats = get_all_instances_in_courses("chat", $courses);
 554              foreach ($chats as $chat) {
 555                  $chatcontext = context_module::instance($chat->coursemodule);
 556  
 557                  $chatdetails = helper_for_get_mods_by_courses::standard_coursemodule_element_values($chat, 'mod_chat');
 558  
 559                  if (has_capability('mod/chat:chat', $chatcontext)) {
 560                      $chatdetails['chatmethod']    = $CFG->chat_method;
 561                      $chatdetails['keepdays']      = $chat->keepdays;
 562                      $chatdetails['studentlogs']   = $chat->studentlogs;
 563                      $chatdetails['chattime']      = $chat->chattime;
 564                      $chatdetails['schedule']      = $chat->schedule;
 565                  }
 566  
 567                  if (has_capability('moodle/course:manageactivities', $chatcontext)) {
 568                      $chatdetails['timemodified']  = $chat->timemodified;
 569                  }
 570                  $returnedchats[] = $chatdetails;
 571              }
 572          }
 573          $result = array();
 574          $result['chats'] = $returnedchats;
 575          $result['warnings'] = $warnings;
 576          return $result;
 577      }
 578  
 579      /**
 580       * Describes the get_chats_by_courses return value.
 581       *
 582       * @return external_single_structure
 583       * @since Moodle 3.0
 584       */
 585      public static function get_chats_by_courses_returns() {
 586          return new external_single_structure(
 587              array(
 588                  'chats' => new external_multiple_structure(
 589                      new external_single_structure(array_merge(
 590                          helper_for_get_mods_by_courses::standard_coursemodule_elements_returns(),
 591                          [
 592                              'chatmethod' => new external_value(PARAM_PLUGIN, 'chat method (sockets, ajax, header_js)',
 593                                  VALUE_OPTIONAL),
 594                              'keepdays' => new external_value(PARAM_INT, 'keep days', VALUE_OPTIONAL),
 595                              'studentlogs' => new external_value(PARAM_INT, 'student logs visible to everyone', VALUE_OPTIONAL),
 596                              'chattime' => new external_value(PARAM_INT, 'chat time', VALUE_OPTIONAL),
 597                              'schedule' => new external_value(PARAM_INT, 'schedule type', VALUE_OPTIONAL),
 598                              'timemodified' => new external_value(PARAM_INT, 'time of last modification', VALUE_OPTIONAL),
 599                          ]
 600                      ), 'Chats')
 601                  ),
 602                  'warnings' => new external_warnings(),
 603              )
 604          );
 605      }
 606  
 607      /**
 608       * Returns description of method parameters
 609       *
 610       * @return external_function_parameters
 611       * @since Moodle 3.4
 612       */
 613      public static function get_sessions_parameters() {
 614          return new external_function_parameters(
 615              array(
 616                  'chatid' => new external_value(PARAM_INT, 'Chat instance id.'),
 617                  'groupid' => new external_value(PARAM_INT, 'Get messages from users in this group.
 618                                                  0 means that the function will determine the user group', VALUE_DEFAULT, 0),
 619                  'showall' => new external_value(PARAM_BOOL, 'Whether to show completed sessions or not.', VALUE_DEFAULT, false),
 620              )
 621          );
 622      }
 623  
 624      /**
 625       * Retrieves chat sessions for a given chat.
 626       *
 627       * @param int $chatid the chat instance id
 628       * @param int $groupid filter messages by this group. 0 to determine the group.
 629       * @param bool $showall whether to include incomplete sessions or not
 630       * @return array of warnings and the sessions
 631       * @since Moodle 3.4
 632       * @throws moodle_exception
 633       */
 634      public static function get_sessions($chatid, $groupid = 0, $showall = false) {
 635          global $DB;
 636  
 637          $params = self::validate_parameters(self::get_sessions_parameters(),
 638                                              array(
 639                                                  'chatid' => $chatid,
 640                                                  'groupid' => $groupid,
 641                                                  'showall' => $showall,
 642                                              ));
 643          $sessions = $warnings = array();
 644  
 645          // Request and permission validation.
 646          $chat = $DB->get_record('chat', array('id' => $params['chatid']), '*', MUST_EXIST);
 647          list($course, $cm) = get_course_and_cm_from_instance($chat, 'chat');
 648  
 649          $context = context_module::instance($cm->id);
 650          self::validate_context($context);
 651  
 652          if (empty($chat->studentlogs) && !has_capability('mod/chat:readlog', $context)) {
 653              throw new moodle_exception('nopermissiontoseethechatlog', 'chat');
 654          }
 655  
 656          if (!empty($params['groupid'])) {
 657              $groupid = $params['groupid'];
 658              // Determine is the group is visible to user.
 659              if (!groups_group_visible($groupid, $course, $cm)) {
 660                  throw new moodle_exception('notingroup');
 661              }
 662          } else {
 663              // Check to see if groups are being used here.
 664              if ($groupmode = groups_get_activity_groupmode($cm)) {
 665                  $groupid = groups_get_activity_group($cm);
 666                  // Determine is the group is visible to user (this is particullary for the group 0).
 667                  if (!groups_group_visible($groupid, $course, $cm)) {
 668                      throw new moodle_exception('notingroup');
 669                  }
 670              } else {
 671                  $groupid = 0;
 672              }
 673          }
 674  
 675          $messages = chat_get_session_messages($chat->id, $groupid, 0, 0, 'timestamp DESC');
 676          if ($messages) {
 677              $chatsessions = chat_get_sessions($messages, $params['showall']);
 678              // Format sessions for external.
 679              foreach ($chatsessions as $session) {
 680                  $sessionusers = array();
 681                  foreach ($session->sessionusers as $sessionuser => $usermessagecount) {
 682                      $sessionusers[] = array(
 683                          'userid' => $sessionuser,
 684                          'messagecount' => $usermessagecount
 685                      );
 686                  }
 687                  $session->sessionusers = $sessionusers;
 688                  $sessions[] = $session;
 689              }
 690          }
 691  
 692          $result = array();
 693          $result['sessions'] = $sessions;
 694          $result['warnings'] = $warnings;
 695          return $result;
 696      }
 697  
 698      /**
 699       * Returns description of method result value
 700       *
 701       * @return \core_external\external_description
 702       * @since Moodle 3.4
 703       */
 704      public static function get_sessions_returns() {
 705          return new external_single_structure(
 706              array(
 707                  'sessions' => new external_multiple_structure(
 708                      new external_single_structure(
 709                          array(
 710                              'sessionstart' => new external_value(PARAM_INT, 'Session start time.'),
 711                              'sessionend' => new external_value(PARAM_INT, 'Session end time.'),
 712                              'sessionusers' => new external_multiple_structure(
 713                                  new external_single_structure(
 714                                      array(
 715                                          'userid' => new external_value(PARAM_INT, 'User id.'),
 716                                          'messagecount' => new external_value(PARAM_INT, 'Number of messages in the session.'),
 717                                      )
 718                                  ), 'Session users.'
 719                              ),
 720                              'iscomplete' => new external_value(PARAM_BOOL, 'Whether the session is completed or not.'),
 721                          )
 722                      ),
 723                      'list of users'
 724                  ),
 725                  'warnings' => new external_warnings()
 726              )
 727          );
 728      }
 729  
 730      /**
 731       * Returns description of method parameters
 732       *
 733       * @return external_function_parameters
 734       * @since Moodle 3.4
 735       */
 736      public static function get_session_messages_parameters() {
 737          return new external_function_parameters(
 738              array(
 739                  'chatid' => new external_value(PARAM_INT, 'Chat instance id.'),
 740                  'sessionstart' => new external_value(PARAM_INT, 'The session start time (timestamp).'),
 741                  'sessionend' => new external_value(PARAM_INT, 'The session end time (timestamp).'),
 742                  'groupid' => new external_value(PARAM_INT, 'Get messages from users in this group.
 743                                                  0 means that the function will determine the user group', VALUE_DEFAULT, 0),
 744              )
 745          );
 746      }
 747  
 748      /**
 749       * Retrieves messages of the given chat session.
 750       *
 751       * @param int $chatid the chat instance id
 752       * @param int $sessionstart the session start time (timestamp)
 753       * @param int $sessionend the session end time (timestamp)
 754       * @param int $groupid filter messages by this group. 0 to determine the group.
 755       * @return array of warnings and the messages
 756       * @since Moodle 3.4
 757       * @throws moodle_exception
 758       */
 759      public static function get_session_messages($chatid, $sessionstart, $sessionend, $groupid = 0) {
 760          global $DB, $PAGE;
 761  
 762          $params = self::validate_parameters(self::get_session_messages_parameters(),
 763                                              array(
 764                                                  'chatid' => $chatid,
 765                                                  'sessionstart' => $sessionstart,
 766                                                  'sessionend' => $sessionend,
 767                                                  'groupid' => $groupid,
 768                                              ));
 769          $messages = $warnings = array();
 770  
 771          // Request and permission validation.
 772          $chat = $DB->get_record('chat', array('id' => $params['chatid']), '*', MUST_EXIST);
 773          list($course, $cm) = get_course_and_cm_from_instance($chat, 'chat');
 774  
 775          $context = context_module::instance($cm->id);
 776          self::validate_context($context);
 777  
 778          if (empty($chat->studentlogs) && !has_capability('mod/chat:readlog', $context)) {
 779              throw new moodle_exception('nopermissiontoseethechatlog', 'chat');
 780          }
 781  
 782          if (!empty($params['groupid'])) {
 783              $groupid = $params['groupid'];
 784              // Determine is the group is visible to user.
 785              if (!groups_group_visible($groupid, $course, $cm)) {
 786                  throw new moodle_exception('notingroup');
 787              }
 788          } else {
 789              // Check to see if groups are being used here.
 790              if ($groupmode = groups_get_activity_groupmode($cm)) {
 791                  $groupid = groups_get_activity_group($cm);
 792                  // Determine is the group is visible to user (this is particullary for the group 0).
 793                  if (!groups_group_visible($groupid, $course, $cm)) {
 794                      throw new moodle_exception('notingroup');
 795                  }
 796              } else {
 797                  $groupid = 0;
 798              }
 799          }
 800  
 801          $messages = chat_get_session_messages($chat->id, $groupid, $params['sessionstart'], $params['sessionend'],
 802              'timestamp ASC');
 803          if ($messages) {
 804              foreach ($messages as $message) {
 805                  $exporter = new chat_message_exporter($message, array('context' => $context));
 806                  $returneditems[] = $exporter->export($PAGE->get_renderer('core'));
 807              }
 808          }
 809  
 810          $result = array(
 811              'messages' => $messages,
 812              'warnings' => $warnings,
 813          );
 814          return $result;
 815      }
 816  
 817      /**
 818       * Returns description of method result value
 819       *
 820       * @return \core_external\external_description
 821       * @since Moodle 3.4
 822       */
 823      public static function get_session_messages_returns() {
 824          return new external_single_structure(
 825              array(
 826                  'messages' => new external_multiple_structure(
 827                      chat_message_exporter::get_read_structure()
 828                  ),
 829                  'warnings' => new external_warnings()
 830              )
 831          );
 832      }
 833  }