diff --git a/mod/chat/classes/external.php b/mod/chat/classes/external.php index 8bb4b15a979..0ef65660cd3 100644 --- a/mod/chat/classes/external.php +++ b/mod/chat/classes/external.php @@ -29,6 +29,8 @@ defined('MOODLE_INTERNAL') || die; require_once($CFG->libdir . '/externallib.php'); require_once($CFG->dirroot . '/mod/chat/lib.php'); +use mod_chat\external\chat_message_exporter; + /** * Chat external functions * @@ -735,4 +737,108 @@ class mod_chat_external extends external_api { ) ); } + + /** + * Returns description of method parameters + * + * @return external_function_parameters + * @since Moodle 3.4 + */ + public static function get_session_messages_parameters() { + return new external_function_parameters( + array( + 'chatid' => new external_value(PARAM_INT, 'Chat instance id.'), + 'sessionstart' => new external_value(PARAM_INT, 'The session start time (timestamp).'), + 'sessionend' => new external_value(PARAM_INT, 'The session end time (timestamp).'), + 'groupid' => new external_value(PARAM_INT, 'Get messages from users in this group. + 0 means that the function will determine the user group', VALUE_DEFAULT, 0), + ) + ); + } + + /** + * Retrieves messages of the given chat session. + * + * @param int $chatid the chat instance id + * @param int $sessionstart the session start time (timestamp) + * @param int $sessionend the session end time (timestamp) + * @param int $groupid filter messages by this group. 0 to determine the group. + * @return array of warnings and the messages + * @since Moodle 3.4 + * @throws moodle_exception + */ + public static function get_session_messages($chatid, $sessionstart, $sessionend, $groupid = 0) { + global $DB, $PAGE; + + $params = self::validate_parameters(self::get_session_messages_parameters(), + array( + 'chatid' => $chatid, + 'sessionstart' => $sessionstart, + 'sessionend' => $sessionend, + 'groupid' => $groupid, + )); + $messages = $warnings = array(); + + // Request and permission validation. + $chat = $DB->get_record('chat', array('id' => $params['chatid']), '*', MUST_EXIST); + list($course, $cm) = get_course_and_cm_from_instance($chat, 'chat'); + + $context = context_module::instance($cm->id); + self::validate_context($context); + + if (empty($chat->studentlogs) && !has_capability('mod/chat:readlog', $context)) { + throw new moodle_exception('nopermissiontoseethechatlog', 'chat'); + } + + if (!empty($params['groupid'])) { + $groupid = $params['groupid']; + // Determine is the group is visible to user. + if (!groups_group_visible($groupid, $course, $cm)) { + throw new moodle_exception('notingroup'); + } + } else { + // Check to see if groups are being used here. + if ($groupmode = groups_get_activity_groupmode($cm)) { + $groupid = groups_get_activity_group($cm); + // Determine is the group is visible to user (this is particullary for the group 0). + if (!groups_group_visible($groupid, $course, $cm)) { + throw new moodle_exception('notingroup'); + } + } else { + $groupid = 0; + } + } + + $messages = chat_get_session_messages($chat->id, $groupid, $params['sessionstart'], $params['sessionend'], + 'timestamp ASC'); + if ($messages) { + foreach ($messages as $message) { + $exporter = new chat_message_exporter($message, array('context' => $context)); + $returneditems[] = $exporter->export($PAGE->get_renderer('core')); + } + } + + $result = array( + 'messages' => $messages, + 'warnings' => $warnings, + ); + return $result; + } + + /** + * Returns description of method result value + * + * @return external_description + * @since Moodle 3.4 + */ + public static function get_session_messages_returns() { + return new external_single_structure( + array( + 'messages' => new external_multiple_structure( + chat_message_exporter::get_read_structure() + ), + 'warnings' => new external_warnings() + ) + ); + } } diff --git a/mod/chat/classes/external/chat_message_exporter.php b/mod/chat/classes/external/chat_message_exporter.php new file mode 100644 index 00000000000..1f3cac48b67 --- /dev/null +++ b/mod/chat/classes/external/chat_message_exporter.php @@ -0,0 +1,101 @@ +. + +/** + * Class for exporting a chat message. + * + * @package mod_chat + * @copyright 2017 Juan Leyva + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace mod_chat\external; +defined('MOODLE_INTERNAL') || die(); + +use core\external\exporter; + +/** + * Class for exporting a chat message. + * + * @copyright 2017 Juan Leyva + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class chat_message_exporter extends exporter { + + /** + * Defines exporter properties. + * + * @return array + */ + protected static function define_properties() { + return array( + 'id' => array( + 'type' => PARAM_INT, + 'description' => 'The message record id.', + ), + 'chatid' => array( + 'type' => PARAM_INT, + 'description' => 'The chat id.', + 'default' => 0, + ), + 'userid' => array( + 'type' => PARAM_INT, + 'description' => 'The user who wrote the message.', + 'default' => 0, + ), + 'groupid' => array( + 'type' => PARAM_INT, + 'description' => 'The group this message belongs to.', + 'default' => 0, + ), + 'issystem' => array( + 'type' => PARAM_BOOL, + 'description' => 'Whether is a system message or not.', + 'default' => false, + ), + 'message' => array( + 'type' => PARAM_RAW, + 'description' => 'The message text.', + ), + 'timestamp' => array( + 'type' => PARAM_INT, + 'description' => 'The message timestamp (indicates when the message was sent).', + 'default' => 0, + ), + ); + } + + /** + * Defines related information. + * + * @return array + */ + protected static function define_related() { + return array( + 'context' => 'context', + ); + } + + /** + * Get the formatting parameters for the name. + * + * @return array + */ + protected function get_format_parameters_for_message() { + return [ + 'component' => 'mod_chat', + ]; + } +} diff --git a/mod/chat/db/services.php b/mod/chat/db/services.php index dcc0897b8f5..6bbd9289600 100644 --- a/mod/chat/db/services.php +++ b/mod/chat/db/services.php @@ -88,5 +88,12 @@ $functions = array( 'description' => 'Retrieves chat sessions for a given chat.', 'type' => 'read', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) - ) + ), + 'mod_chat_get_session_messages' => array( + 'classname' => 'mod_chat_external', + 'methodname' => 'get_session_messages', + 'description' => 'Retrieves messages of the given chat session.', + 'type' => 'read', + 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) + ), ); diff --git a/mod/chat/tests/externallib_test.php b/mod/chat/tests/externallib_test.php index cf86bb896db..2443f71d6b1 100644 --- a/mod/chat/tests/externallib_test.php +++ b/mod/chat/tests/externallib_test.php @@ -431,4 +431,65 @@ class mod_chat_external_testcase extends externallib_advanced_testcase { $this->assertEquals($timenow - HOURSECS + 70, $result['sessions'][0]['sessionstart']); // First not system message time. $this->assertEmpty($result['warnings']); } + + /** + * Test get_session_messages + */ + public function test_get_session_messages() { + global $DB; + + $this->resetAfterTest(true); + + // Setup test data. + $this->setAdminUser(); + $course = $this->getDataGenerator()->create_course(); + $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id)); + + $user1 = self::getDataGenerator()->create_user(); + $user2 = self::getDataGenerator()->create_user(); + $studentrole = $DB->get_record('role', array('shortname' => 'student')); + $this->getDataGenerator()->enrol_user($user1->id, $course->id, $studentrole->id); + $this->getDataGenerator()->enrol_user($user2->id, $course->id, $studentrole->id); + + // Start a chat and send a few messages. + $this->setUser($user1); + $result = mod_chat_external::login_user($chat->id); + $result = external_api::clean_returnvalue(mod_chat_external::login_user_returns(), $result); + $chatsid = $result['chatsid']; + mod_chat_external::send_chat_message($chatsid, 'hello!'); + mod_chat_external::send_chat_message($chatsid, 'bye bye!'); + + $this->setUser($user2); + $result = mod_chat_external::login_user($chat->id); + $result = external_api::clean_returnvalue(mod_chat_external::login_user_returns(), $result); + $chatsid = $result['chatsid']; + mod_chat_external::send_chat_message($chatsid, 'greetings!'); + + // Pass showall parameter to indicate that we want not completed sessions. + $result = mod_chat_external::get_sessions($chat->id, 0, true); + $result = external_api::clean_returnvalue(mod_chat_external::get_sessions_returns(), $result); + $this->assertCount(1, $result['sessions']); // One session. + + $sessionstart = $result['sessions'][0]['sessionstart']; + $sessionend = $result['sessions'][0]['sessionend']; + $result = mod_chat_external::get_session_messages($chat->id, $sessionstart, $sessionend); + $result = external_api::clean_returnvalue(mod_chat_external::get_session_messages_returns(), $result); + $this->assertCount(5, $result['messages']); // 2 system + 3 personal messages. + $found = 0; + foreach ($result['messages'] as $message) { + if (!$message['issystem']) { + if ($message['userid'] == $user1->id) { + if ($message['message'] != 'hello!') { + $this->assertEquals('bye bye!', $message['message']); + $found++; + } + } else { + $this->assertEquals($user2->id, $message['userid']); + $this->assertEquals('greetings!', $message['message']); + $found++; + } + } + } + $this->assertEquals(2, $found); + } } diff --git a/mod/chat/version.php b/mod/chat/version.php index 0486c4031f7..c313d4adde0 100644 --- a/mod/chat/version.php +++ b/mod/chat/version.php @@ -24,7 +24,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2017111302; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2017111303; // The current module version (Date: YYYYMMDDXX). $plugin->requires = 2017110800; // Requires this Moodle version. $plugin->component = 'mod_chat'; // Full name of the plugin (used for diagnostics). $plugin->cron = 300;