From 8e5ac0e34f89d76d35ccaae3db563e0cc6c2f82e Mon Sep 17 00:00:00 2001 From: Laurent David Date: Thu, 31 Oct 2024 10:45:58 +0100 Subject: [PATCH] MDL-82457 mod_chat: Remove mod_chat from Moodle 5.0 --- .upgradenotes/MDL-82457-2024103109453585.yml | 5 + lib/db/upgrade.php | 9 + mod/chat/README.txt | 34 - mod/chat/backup/moodle1/lib.php | 138 -- .../backup_chat_activity_task.class.php | 69 - .../backup/moodle2/backup_chat_stepslib.php | 67 - .../restore_chat_activity_task.class.php | 111 -- .../backup/moodle2/restore_chat_stepslib.php | 83 - mod/chat/beep.mp3 | Bin 969 -> 0 bytes mod/chat/chat_ajax.php | 162 -- mod/chat/chatd.php | 1093 ----------- .../analytics/indicator/activity_base.php | 111 -- .../analytics/indicator/cognitive_depth.php | 56 - .../analytics/indicator/social_breadth.php | 56 - mod/chat/classes/dates.php | 58 - .../course_module_instance_list_viewed.php | 38 - .../classes/event/course_module_viewed.php | 47 - mod/chat/classes/event/message_sent.php | 93 - mod/chat/classes/event/sessions_viewed.php | 108 -- mod/chat/classes/external.php | 833 --------- .../external/chat_message_exporter.php | 101 - mod/chat/classes/external/view_sessions.php | 121 -- mod/chat/classes/privacy/provider.php | 333 ---- mod/chat/classes/search/activity.php | 46 - mod/chat/classes/task/cron_task.php | 65 - mod/chat/db/access.php | 114 -- mod/chat/db/events.php | 34 - mod/chat/db/install.php | 33 - mod/chat/db/install.xml | 94 - mod/chat/db/log.php | 34 - mod/chat/db/services.php | 108 -- mod/chat/db/tasks.php | 36 - mod/chat/db/upgrade.php | 39 - mod/chat/empty.php | 9 - mod/chat/gui_ajax/index.php | 114 -- mod/chat/gui_ajax/module.js | 265 --- mod/chat/gui_ajax/theme/bubble/bubbles.png | Bin 1612 -> 0 bytes mod/chat/gui_ajax/theme/bubble/chat.css | 249 --- mod/chat/gui_ajax/theme/bubble/config.php | 50 - mod/chat/gui_ajax/theme/bubble/horizontal.png | Bin 282 -> 0 bytes mod/chat/gui_ajax/theme/bubble/input.png | Bin 95 -> 0 bytes mod/chat/gui_ajax/theme/bubble/vertical.png | Bin 191 -> 0 bytes mod/chat/gui_ajax/theme/compact/chat.css | 102 -- mod/chat/gui_ajax/theme/compact/config.php | 37 - mod/chat/gui_ajax/theme/compact/input.png | Bin 95 -> 0 bytes .../gui_ajax/theme/course_theme/config.php | 37 - mod/chat/gui_basic/index.php | 213 --- mod/chat/gui_header_js/chatinput.php | 80 - mod/chat/gui_header_js/chatmsg.php | 8 - mod/chat/gui_header_js/index.php | 100 - mod/chat/gui_header_js/insert.php | 78 - mod/chat/gui_header_js/jsupdate.php | 192 -- mod/chat/gui_header_js/jsupdated.php | 248 --- mod/chat/gui_header_js/module.js | 150 -- mod/chat/gui_header_js/users.php | 141 -- mod/chat/gui_sockets/chat_gui_sockets.js | 14 - mod/chat/gui_sockets/chatinput.php | 59 - mod/chat/gui_sockets/index.php | 92 - mod/chat/index.php | 105 -- mod/chat/lang/en/chat.php | 177 -- mod/chat/lib.php | 1630 ----------------- mod/chat/locallib.php | 254 --- mod/chat/mod_form.php | 80 - mod/chat/pix/monologo.svg | 6 - mod/chat/renderer.php | 106 -- mod/chat/report.php | 274 --- mod/chat/settings.php | 62 - mod/chat/styles.css | 114 -- mod/chat/tests/backup/restore_date_test.php | 64 - mod/chat/tests/behat/behat_mod_chat.php | 76 - .../behat/chat_activity_completion.feature | 56 - .../tests/behat/chat_calendar_events.feature | 36 - .../tests/behat/chat_course_reset.feature | 56 - mod/chat/tests/behat/chat_group_mode.feature | 61 - .../chat_no_calendar_capabilities.feature | 49 - .../behat/chat_view_past_session.feature | 48 - mod/chat/tests/dates_test.php | 138 -- mod/chat/tests/event/events_test.php | 185 -- .../tests/external/view_sessions_test.php | 139 -- mod/chat/tests/externallib_test.php | 502 ----- mod/chat/tests/format_message_test.php | 163 -- mod/chat/tests/generator/lib.php | 75 - mod/chat/tests/generator_test.php | 57 - mod/chat/tests/lib_test.php | 748 -------- mod/chat/tests/privacy/provider_test.php | 439 ----- mod/chat/upgrade.txt | 18 - mod/chat/version.php | 29 - mod/chat/view.php | 179 -- version.php | 2 +- 89 files changed, 15 insertions(+), 12480 deletions(-) create mode 100644 .upgradenotes/MDL-82457-2024103109453585.yml delete mode 100644 mod/chat/README.txt delete mode 100644 mod/chat/backup/moodle1/lib.php delete mode 100644 mod/chat/backup/moodle2/backup_chat_activity_task.class.php delete mode 100644 mod/chat/backup/moodle2/backup_chat_stepslib.php delete mode 100644 mod/chat/backup/moodle2/restore_chat_activity_task.class.php delete mode 100644 mod/chat/backup/moodle2/restore_chat_stepslib.php delete mode 100644 mod/chat/beep.mp3 delete mode 100644 mod/chat/chat_ajax.php delete mode 100644 mod/chat/chatd.php delete mode 100644 mod/chat/classes/analytics/indicator/activity_base.php delete mode 100644 mod/chat/classes/analytics/indicator/cognitive_depth.php delete mode 100644 mod/chat/classes/analytics/indicator/social_breadth.php delete mode 100644 mod/chat/classes/dates.php delete mode 100644 mod/chat/classes/event/course_module_instance_list_viewed.php delete mode 100644 mod/chat/classes/event/course_module_viewed.php delete mode 100644 mod/chat/classes/event/message_sent.php delete mode 100644 mod/chat/classes/event/sessions_viewed.php delete mode 100644 mod/chat/classes/external.php delete mode 100644 mod/chat/classes/external/chat_message_exporter.php delete mode 100644 mod/chat/classes/external/view_sessions.php delete mode 100644 mod/chat/classes/privacy/provider.php delete mode 100644 mod/chat/classes/search/activity.php delete mode 100644 mod/chat/classes/task/cron_task.php delete mode 100644 mod/chat/db/access.php delete mode 100644 mod/chat/db/events.php delete mode 100644 mod/chat/db/install.php delete mode 100644 mod/chat/db/install.xml delete mode 100644 mod/chat/db/log.php delete mode 100644 mod/chat/db/services.php delete mode 100644 mod/chat/db/tasks.php delete mode 100644 mod/chat/db/upgrade.php delete mode 100644 mod/chat/empty.php delete mode 100644 mod/chat/gui_ajax/index.php delete mode 100644 mod/chat/gui_ajax/module.js delete mode 100644 mod/chat/gui_ajax/theme/bubble/bubbles.png delete mode 100644 mod/chat/gui_ajax/theme/bubble/chat.css delete mode 100644 mod/chat/gui_ajax/theme/bubble/config.php delete mode 100644 mod/chat/gui_ajax/theme/bubble/horizontal.png delete mode 100644 mod/chat/gui_ajax/theme/bubble/input.png delete mode 100644 mod/chat/gui_ajax/theme/bubble/vertical.png delete mode 100644 mod/chat/gui_ajax/theme/compact/chat.css delete mode 100644 mod/chat/gui_ajax/theme/compact/config.php delete mode 100644 mod/chat/gui_ajax/theme/compact/input.png delete mode 100644 mod/chat/gui_ajax/theme/course_theme/config.php delete mode 100644 mod/chat/gui_basic/index.php delete mode 100644 mod/chat/gui_header_js/chatinput.php delete mode 100644 mod/chat/gui_header_js/chatmsg.php delete mode 100644 mod/chat/gui_header_js/index.php delete mode 100644 mod/chat/gui_header_js/insert.php delete mode 100644 mod/chat/gui_header_js/jsupdate.php delete mode 100644 mod/chat/gui_header_js/jsupdated.php delete mode 100644 mod/chat/gui_header_js/module.js delete mode 100644 mod/chat/gui_header_js/users.php delete mode 100644 mod/chat/gui_sockets/chat_gui_sockets.js delete mode 100644 mod/chat/gui_sockets/chatinput.php delete mode 100644 mod/chat/gui_sockets/index.php delete mode 100644 mod/chat/index.php delete mode 100644 mod/chat/lang/en/chat.php delete mode 100644 mod/chat/lib.php delete mode 100644 mod/chat/locallib.php delete mode 100644 mod/chat/mod_form.php delete mode 100644 mod/chat/pix/monologo.svg delete mode 100644 mod/chat/renderer.php delete mode 100644 mod/chat/report.php delete mode 100644 mod/chat/settings.php delete mode 100644 mod/chat/styles.css delete mode 100644 mod/chat/tests/backup/restore_date_test.php delete mode 100644 mod/chat/tests/behat/behat_mod_chat.php delete mode 100644 mod/chat/tests/behat/chat_activity_completion.feature delete mode 100644 mod/chat/tests/behat/chat_calendar_events.feature delete mode 100644 mod/chat/tests/behat/chat_course_reset.feature delete mode 100644 mod/chat/tests/behat/chat_group_mode.feature delete mode 100644 mod/chat/tests/behat/chat_no_calendar_capabilities.feature delete mode 100644 mod/chat/tests/behat/chat_view_past_session.feature delete mode 100644 mod/chat/tests/dates_test.php delete mode 100644 mod/chat/tests/event/events_test.php delete mode 100644 mod/chat/tests/external/view_sessions_test.php delete mode 100644 mod/chat/tests/externallib_test.php delete mode 100644 mod/chat/tests/format_message_test.php delete mode 100644 mod/chat/tests/generator/lib.php delete mode 100644 mod/chat/tests/generator_test.php delete mode 100644 mod/chat/tests/lib_test.php delete mode 100644 mod/chat/tests/privacy/provider_test.php delete mode 100644 mod/chat/upgrade.txt delete mode 100644 mod/chat/version.php delete mode 100644 mod/chat/view.php diff --git a/.upgradenotes/MDL-82457-2024103109453585.yml b/.upgradenotes/MDL-82457-2024103109453585.yml new file mode 100644 index 00000000000..75f62132fe8 --- /dev/null +++ b/.upgradenotes/MDL-82457-2024103109453585.yml @@ -0,0 +1,5 @@ +issueNumber: MDL-82457 +notes: + mod: + - message: Remove mod_chat from Moodle 5.0 + type: removed diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index c9032d23690..2b645c0ad73 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -1312,5 +1312,14 @@ function xmldb_main_upgrade($oldversion) { // Main savepoint reached. upgrade_main_savepoint(true, 2024120500.01); } + + // Remove chat. + if ($oldversion < 2024120500.02) { + if (!file_exists($CFG->dirroot . "/mod/chat/version.php")) { + uninstall_plugin('mod', 'chat'); + } + // Main savepoint reached. + upgrade_main_savepoint(true, 2024120500.02); + } return true; } diff --git a/mod/chat/README.txt b/mod/chat/README.txt deleted file mode 100644 index d495677cca0..00000000000 --- a/mod/chat/README.txt +++ /dev/null @@ -1,34 +0,0 @@ -Official Chat Module for Moodle ------------------------------- - -The chat module now supports a backend daemon for -more efficiency. - -It's still buggy and being worked on, but if you -want to test it and help out here are some quick -instructions: - -1) Admin -> Config -> Modules -> Chat -> Settings - -2) Set the method to "sockets" and set up the ports etc - -3) Start the server like this (from the Unix command line): - - cd moodle/mod/chat - php chatd.php --start & - -4) Go to a chat room in Moodle and open it as normal. - ------- - -KNOWN PROBLEMS - - - User list is not always working - - Some browsers (eg Safari) cause lines to be repeated - by 10 - 20 times - - Occasionally "Document was empty" messages - -Help solving these very welcome! - - -Martin, 31 July 2004 diff --git a/mod/chat/backup/moodle1/lib.php b/mod/chat/backup/moodle1/lib.php deleted file mode 100644 index 1e7d2a7dda8..00000000000 --- a/mod/chat/backup/moodle1/lib.php +++ /dev/null @@ -1,138 +0,0 @@ -. - -/** - * Provides support for the conversion of moodle1 backup to the moodle2 format - * Based off of a template @ http://docs.moodle.org/dev/Backup_1.9_conversion_for_developers - * - * @package mod_chat - * @copyright 2011 Aparup Banerjee - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -/** - * Chat conversion handler - */ -class moodle1_mod_chat_handler extends moodle1_mod_handler { - - /** @var moodle1_file_manager */ - protected $fileman = null; - - /** @var int cmid */ - protected $moduleid = null; - - /** - * Declare the paths in moodle.xml we are able to convert - * - * The method returns list of {@link convert_path} instances. - * For each path returned, the corresponding conversion method must be - * defined. - * - * Note that the path /MOODLE_BACKUP/COURSE/MODULES/MOD/CHAT does not - * actually exist in the file. The last element with the module name was - * appended by the moodle1_converter class. - * - * @return array of {@link convert_path} instances - */ - public function get_paths() { - return array( - new convert_path( - 'chat', '/MOODLE_BACKUP/COURSE/MODULES/MOD/CHAT', - array( - 'newfields' => array( - 'introformat' => 0 - ) - ) - ) - ); - } - - /** - * This is executed every time we have one /MOODLE_BACKUP/COURSE/MODULES/MOD/CHAT - * data available - */ - public function process_chat($data) { - global $CFG; - - // Get the course module id and context id. - $instanceid = $data['id']; - $cminfo = $this->get_cminfo($instanceid); - $this->moduleid = $cminfo['id']; - $contextid = $this->converter->get_contextid(CONTEXT_MODULE, $this->moduleid); - - // Replay the upgrade step 2010050101. - if ($CFG->texteditors !== 'textarea') { - $data['intro'] = text_to_html($data['intro'], false, false, true); - $data['introformat'] = FORMAT_HTML; - } - - // Get a fresh new file manager for this instance. - $this->fileman = $this->converter->get_file_manager($contextid, 'mod_chat'); - - // Convert course files embedded into the intro. - $this->fileman->filearea = 'intro'; - $this->fileman->itemid = 0; - $data['intro'] = moodle1_converter::migrate_referenced_files($data['intro'], $this->fileman); - - // Start writing chat.xml. - $this->open_xml_writer("activities/chat_{$this->moduleid}/chat.xml"); - $this->xmlwriter->begin_tag('activity', array('id' => $instanceid, 'moduleid' => $this->moduleid, - 'modulename' => 'chat', 'contextid' => $contextid)); - $this->xmlwriter->begin_tag('chat', array('id' => $instanceid)); - - foreach ($data as $field => $value) { - if ($field <> 'id') { - $this->xmlwriter->full_tag($field, $value); - } - } - - $this->xmlwriter->begin_tag('messages'); - - return $data; - } - - /** - * This is executed every time we have one /MOODLE_BACKUP/COURSE/MODULES/MOD/CHAT/MESSAGES/MESSAGE - * data available - */ - public function process_chat_message($data) { - // MDL-46466 - Should this be empty? - } - - /** - * This is executed when we reach the closing tag of our 'chat' path - */ - public function on_chat_end() { - // Close chat.xml. - $this->xmlwriter->end_tag('messages'); - $this->xmlwriter->end_tag('chat'); - $this->xmlwriter->end_tag('activity'); - $this->close_xml_writer(); - - // Write inforef.xml. - $this->open_xml_writer("activities/chat_{$this->moduleid}/inforef.xml"); - $this->xmlwriter->begin_tag('inforef'); - $this->xmlwriter->begin_tag('fileref'); - foreach ($this->fileman->get_fileids() as $fileid) { - $this->write_xml('file', array('id' => $fileid)); - } - $this->xmlwriter->end_tag('fileref'); - $this->xmlwriter->end_tag('inforef'); - $this->close_xml_writer(); - } -} diff --git a/mod/chat/backup/moodle2/backup_chat_activity_task.class.php b/mod/chat/backup/moodle2/backup_chat_activity_task.class.php deleted file mode 100644 index a546f01cc04..00000000000 --- a/mod/chat/backup/moodle2/backup_chat_activity_task.class.php +++ /dev/null @@ -1,69 +0,0 @@ -. - -/** - * Defines backup_chat_activity_task class - * - * @package mod_chat - * @category backup - * @copyright 2010 onwards Dongsheng Cai - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -require_once($CFG->dirroot . '/mod/chat/backup/moodle2/backup_chat_stepslib.php'); - -/** - * Provides the steps to perform one complete backup of the Chat instance - */ -class backup_chat_activity_task extends backup_activity_task { - - /** - * No specific settings for this activity - */ - protected function define_my_settings() { - } - - /** - * Defines a backup step to store the instance data in the chat.xml file - */ - protected function define_my_steps() { - $this->add_step(new backup_chat_activity_structure_step('chat_structure', 'chat.xml')); - } - - /** - * Encodes URLs to the index.php and view.php scripts - * - * @param string $content some HTML text that eventually contains URLs to the activity instance scripts - * @return string the content with the URLs encoded - */ - public static function encode_content_links($content) { - global $CFG; - - $base = preg_quote($CFG->wwwroot . '/mod/chat', '#'); - - // Link to the list of chats. - $pattern = "#(".$base."\/index.php\?id\=)([0-9]+)#"; - $content = preg_replace($pattern, '$@CHATINDEX*$2@$', $content); - - // Link to chat view by moduleid. - $pattern = "#(".$base."\/view.php\?id\=)([0-9]+)#"; - $content = preg_replace($pattern, '$@CHATVIEWBYID*$2@$', $content); - - return $content; - } -} diff --git a/mod/chat/backup/moodle2/backup_chat_stepslib.php b/mod/chat/backup/moodle2/backup_chat_stepslib.php deleted file mode 100644 index 0c791905067..00000000000 --- a/mod/chat/backup/moodle2/backup_chat_stepslib.php +++ /dev/null @@ -1,67 +0,0 @@ -. - -/** - * @package mod_chat - * @subpackage backup-moodle2 - * @copyright 2010 onwards Dongsheng Cai - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -/** - * Define all the backup steps that will be used by the backup_chat_activity_task - */ -class backup_chat_activity_structure_step extends backup_activity_structure_step { - protected function define_structure() { - $userinfo = $this->get_setting_value('userinfo'); - - // Define each element separated. - $chat = new backup_nested_element('chat', array('id'), array( - 'name', 'intro', 'introformat', 'keepdays', 'studentlogs', - 'chattime', 'schedule', 'timemodified')); - $messages = new backup_nested_element('messages'); - - $message = new backup_nested_element('message', array('id'), array( - 'userid', 'groupid', 'system', 'message_text', 'timestamp')); - - // It is not cool to have two tags with same name, so we need to rename message field to message_text. - $message->set_source_alias('message', 'message_text'); - // Renamed 'issystem' into 'system', for backward compatibility: 'system' is now a reserved word in MySQL 8.0.3+. - $message->set_source_alias('issystem', 'system'); - - // Build the tree. - $chat->add_child($messages); - $messages->add_child($message); - - // Define sources. - $chat->set_source_table('chat', array('id' => backup::VAR_ACTIVITYID)); - - // User related messages only happen if we are including user info. - if ($userinfo) { - $message->set_source_table('chat_messages', array('chatid' => backup::VAR_PARENTID)); - } - - // Define id annotations. - $message->annotate_ids('user', 'userid'); - $message->annotate_ids('group', 'groupid'); - - // Annotate the file areas in chat module. - $chat->annotate_files('mod_chat', 'intro', null); // The chat_intro area doesn't use itemid. - - // Return the root element (chat), wrapped into standard activity structure. - return $this->prepare_activity_structure($chat); - } -} diff --git a/mod/chat/backup/moodle2/restore_chat_activity_task.class.php b/mod/chat/backup/moodle2/restore_chat_activity_task.class.php deleted file mode 100644 index bb9b0cf712b..00000000000 --- a/mod/chat/backup/moodle2/restore_chat_activity_task.class.php +++ /dev/null @@ -1,111 +0,0 @@ -. - -/** - * @package mod_chat - * @subpackage backup-moodle2 - * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -require_once($CFG->dirroot . '/mod/chat/backup/moodle2/restore_chat_stepslib.php'); - -/** - * chat restore task that provides all the settings and steps to perform one - * complete restore of the activity - */ -class restore_chat_activity_task extends restore_activity_task { - - /** - * Define (add) particular settings this activity can have - */ - protected function define_my_settings() { - // No particular settings for this activity. - } - - /** - * Define (add) particular steps this activity can have - */ - protected function define_my_steps() { - // Chat only has one structure step. - $this->add_step(new restore_chat_activity_structure_step('chat_structure', 'chat.xml')); - } - - /** - * Define the contents in the activity that must be - * processed by the link decoder - */ - public static function define_decode_contents() { - $contents = array(); - - $contents[] = new restore_decode_content('chat', array('intro'), 'chat'); - $contents[] = new restore_decode_content('chat_messages', array('message'), 'chat_message'); - - return $contents; - } - - /** - * Define the decoding rules for links belonging - * to the activity to be executed by the link decoder - */ - public static function define_decode_rules() { - $rules = array(); - - $rules[] = new restore_decode_rule('CHATVIEWBYID', '/mod/chat/view.php?id=$1', 'course_module'); - $rules[] = new restore_decode_rule('CHATINDEX', '/mod/chat/index.php?id=$1', 'course'); - - return $rules; - - } - - /** - * Define the restore log rules that will be applied - * by the {@link restore_logs_processor} when restoring - * chat logs. It must return one array - * of {@link restore_log_rule} objects - */ - public static function define_restore_log_rules() { - $rules = array(); - - $rules[] = new restore_log_rule('chat', 'add', 'view.php?id={course_module}', '{chat}'); - $rules[] = new restore_log_rule('chat', 'update', 'view.php?id={course_module}', '{chat}'); - $rules[] = new restore_log_rule('chat', 'view', 'view.php?id={course_module}', '{chat}'); - $rules[] = new restore_log_rule('chat', 'talk', 'view.php?id={course_module}', '{chat}'); - $rules[] = new restore_log_rule('chat', 'report', 'report.php?id={course_module}', '{chat}'); - - return $rules; - } - - /** - * Define the restore log rules that will be applied - * by the {@link restore_logs_processor} when restoring - * course logs. It must return one array - * of {@link restore_log_rule} objects - * - * Note this rules are applied when restoring course logs - * by the restore final task, but are defined here at - * activity level. All them are rules not linked to any module instance (cmid = 0) - */ - public static function define_restore_log_rules_for_course() { - $rules = array(); - - $rules[] = new restore_log_rule('chat', 'view all', 'index.php?id={course}', null); - - return $rules; - } -} diff --git a/mod/chat/backup/moodle2/restore_chat_stepslib.php b/mod/chat/backup/moodle2/restore_chat_stepslib.php deleted file mode 100644 index c4c64dd5e61..00000000000 --- a/mod/chat/backup/moodle2/restore_chat_stepslib.php +++ /dev/null @@ -1,83 +0,0 @@ -. - -/** - * @package mod_chat - * @subpackage backup-moodle2 - * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -/** - * Define all the restore steps that will be used by the restore_chat_activity_task - */ - -/** - * Structure step to restore one chat activity - */ -class restore_chat_activity_structure_step extends restore_activity_structure_step { - - protected function define_structure() { - - $paths = array(); - $userinfo = $this->get_setting_value('userinfo'); - - $paths[] = new restore_path_element('chat', '/activity/chat'); - if ($userinfo) { - $paths[] = new restore_path_element('chat_message', '/activity/chat/messages/message'); - } - - // Return the paths wrapped into standard activity structure. - return $this->prepare_activity_structure($paths); - } - - protected function process_chat($data) { - global $DB; - - $data = (object)$data; - $oldid = $data->id; - $data->course = $this->get_courseid(); - - // Any changes to the list of dates that needs to be rolled should be same during course restore and course reset. - // See MDL-9367. - $data->chattime = $this->apply_date_offset($data->chattime); - - // Insert the chat record. - $newitemid = $DB->insert_record('chat', $data); - // Immediately after inserting "activity" record, call this. - $this->apply_activity_instance($newitemid); - } - - protected function process_chat_message($data) { - global $DB; - - $data = (object)$data; - $oldid = $data->id; - $data->chatid = $this->get_new_parentid('chat'); - $data->userid = $this->get_mappingid('user', $data->userid); - $data->groupid = $this->get_mappingid('group', $data->groupid); - $data->message = $data->message_text; - $data->issystem = $data->system; - - $newitemid = $DB->insert_record('chat_messages', $data); - $this->set_mapping('chat_message', $oldid, $newitemid); // Because of decode. - } - - protected function after_execute() { - // Add chat related files, no need to match by itemname (just internally handled context). - $this->add_related_files('mod_chat', 'intro', null); - } -} diff --git a/mod/chat/beep.mp3 b/mod/chat/beep.mp3 deleted file mode 100644 index 6cfa71d1ad7242993e10fa97de43714e66568adb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 969 zcmbW0YeoaBP+Y>N4H?bYAQI(AR!&c%F0npZ{|XCpkWhfsuHp zr==yJ=!RiVDOrW;RpHW=GHEylBVq$N{}0KB)p=-uiJB`~-+)C?q*ACT3Mncnu2M8p zm?#D)#wmc}uK^hGF=4J}=z{_|4-<=7q7FJ!_+_7zl?CF3<%BSTX(Sff7)}ED2HPBu z5gu#r0cfAQsfSL9EIuVlIoqsd~V!{IG2o1~pyi&fp`d*SW@_H;>+9)|jxuFU9x zFbYC-k^buJI0f*|!=1+do>VhY@2Fk_v*!TrPZ__a_F9JZrKZZ~`Z9)-L;pud;Xj=3 zkzR||J;+y9G@gRRb-q0-=yR(+hHa#>0Bxb;4$Bz*l2sz7Tk&u~IVYU-(8}-C4M_ywZ zfJIhJ|LRl&?h)A@Jo2Ffr0TVE( zeB?kEV=c&hc4rg6)wkR?C5EM9#cC@)+?~t``H9@T=!@R_Ij)V=@#7e7jM5Z5tYB;L zepO^i{f^9RzH{k4Yn}y&srQRL@6Jkalkv6il2@yP83`B0JEt zYrZa#XF*#7O)JMh%cYOhbg0*=>i}4Xk8Z9Hm|cxt@B6yGOYc-O`_1E=Yl?v(FPMHZ f_Hk!QtTG`?8WAB~rPJw1KjfcFq8Ts@_5YXOHs1i~ diff --git a/mod/chat/chat_ajax.php b/mod/chat/chat_ajax.php deleted file mode 100644 index b925808d657..00000000000 --- a/mod/chat/chat_ajax.php +++ /dev/null @@ -1,162 +0,0 @@ -. - -define('AJAX_SCRIPT', true); - -require(__DIR__.'/../../config.php'); -require_once(__DIR__ . '/lib.php'); - -$action = optional_param('action', '', PARAM_ALPHANUM); -$beepid = optional_param('beep', '', PARAM_RAW); -$chatsid = required_param('chat_sid', PARAM_ALPHANUM); -$theme = required_param('chat_theme', PARAM_ALPHANUMEXT); -$chatmessage = optional_param('chat_message', '', PARAM_RAW); -$chatlasttime = optional_param('chat_lasttime', 0, PARAM_INT); -$chatlastrow = optional_param('chat_lastrow', 1, PARAM_INT); - -if (!confirm_sesskey()) { - throw new moodle_exception('invalidsesskey', 'error'); -} - -if (!$chatuser = $DB->get_record('chat_users', array('sid' => $chatsid))) { - throw new moodle_exception('notlogged', 'chat'); -} -if (!$chat = $DB->get_record('chat', array('id' => $chatuser->chatid))) { - throw new moodle_exception('invaliduserid', 'error'); -} -if (!$course = $DB->get_record('course', array('id' => $chat->course))) { - throw new moodle_exception('invalidcourseid', 'error'); -} -if (!$cm = get_coursemodule_from_instance('chat', $chat->id, $course->id)) { - throw new moodle_exception('invalidcoursemodule', 'error'); -} - -if (!isloggedin()) { - throw new moodle_exception('notlogged', 'chat'); -} - -// Set up $PAGE so that format_text will work properly. -$PAGE->set_cm($cm, $course, $chat); -$PAGE->set_url('/mod/chat/chat_ajax.php', array('chat_sid' => $chatsid)); - -require_login($course, false, $cm); - -$context = context_module::instance($cm->id); -require_capability('mod/chat:chat', $context); - -ob_start(); -header('Expires: Sun, 28 Dec 1997 09:32:45 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); -header('Cache-Control: no-cache, must-revalidate'); -header('Pragma: no-cache'); -header('Content-Type: text/html; charset=utf-8'); - -switch ($action) { - case 'init': - $users = chat_get_users($chatuser->chatid, $chatuser->groupid, $cm->groupingid); - $users = chat_format_userlist($users, $course); - $response['users'] = $users; - echo json_encode($response); - break; - - case 'chat': - \core\session\manager::write_close(); - chat_delete_old_users(); - $chatmessage = clean_text($chatmessage, FORMAT_MOODLE); - - if (!empty($beepid)) { - $chatmessage = 'beep '.$beepid; - } - - if (!empty($chatmessage)) { - - chat_send_chatmessage($chatuser, $chatmessage, 0, $cm); - - $chatuser->lastmessageping = time() - 2; - $DB->update_record('chat_users', $chatuser); - - // Response OK message. - echo json_encode(true); - ob_end_flush(); - } - break; - - case 'update': - if ((time() - $chatlasttime) > $CFG->chat_old_ping) { - chat_delete_old_users(); - } - - if ($latestmessage = chat_get_latest_message($chatuser->chatid, $chatuser->groupid)) { - $chatnewlasttime = $latestmessage->timestamp; - } else { - $chatnewlasttime = 0; - } - - if ($chatlasttime == 0) { - $chatlasttime = time() - $CFG->chat_old_ping; - } - - $messages = chat_get_latest_messages($chatuser, $chatlasttime); - - if (!empty($messages)) { - $num = count($messages); - } else { - $num = 0; - } - $chatnewrow = ($chatlastrow + $num) % 2; - $senduserlist = false; - if ($messages && ($chatlasttime != $chatnewlasttime)) { - foreach ($messages as $n => &$message) { - $tmp = new stdClass(); - // When somebody enter room, user list will be updated. - if (!empty($message->issystem)) { - $senduserlist = true; - } - if ($html = chat_format_message_theme($message, $chatuser, $USER, $cm->groupingid, $theme)) { - $message->mymessage = ($USER->id == $message->userid); - $message->message = $html->html; - if (!empty($html->type)) { - $message->type = $html->type; - } - } else { - unset($messages[$n]); - } - } - } - - if ($senduserlist) { - // Return users when system message arrives. - $users = chat_format_userlist(chat_get_users($chatuser->chatid, $chatuser->groupid, $cm->groupingid), $course); - $response['users'] = $users; - } - - $DB->set_field('chat_users', 'lastping', time(), array('id' => $chatuser->id)); - - $response['lasttime'] = $chatnewlasttime; - $response['lastrow'] = $chatnewrow; - if ($messages) { - $response['msgs'] = $messages; - } - - echo json_encode($response); - header('Content-Length: ' . ob_get_length()); - - ob_end_flush(); - break; - - default: - break; -} diff --git a/mod/chat/chatd.php b/mod/chat/chatd.php deleted file mode 100644 index 3be05f6508f..00000000000 --- a/mod/chat/chatd.php +++ /dev/null @@ -1,1093 +0,0 @@ -. - -/** - * Chat daemon - * - * @package mod_chat - * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -define('CLI_SCRIPT', true); - -require(__DIR__.'/../../config.php'); -require_once($CFG->dirroot . '/mod/chat/lib.php'); - -// Browser quirks. -define('QUIRK_CHUNK_UPDATE', 0x0001); - -// Connection telltale. -define('CHAT_CONNECTION', 0x10); -// Connections: Incrementing sequence, 0x10 to 0x1f. -define('CHAT_CONNECTION_CHANNEL', 0x11); - -// Sidekick telltale. -define('CHAT_SIDEKICK', 0x20); -// Sidekicks: Incrementing sequence, 0x21 to 0x2f. -define('CHAT_SIDEKICK_USERS', 0x21); -define('CHAT_SIDEKICK_MESSAGE', 0x22); -define('CHAT_SIDEKICK_BEEP', 0x23); - -$phpversion = phpversion(); -echo 'Moodle chat daemon v1.0 on PHP '.$phpversion."\n\n"; - -// Set up all the variables we need. - -// The $CFG variables are now defined in database by chat/lib.php. - -$_SERVER['PHP_SELF'] = 'dummy'; -$_SERVER['SERVER_NAME'] = 'dummy'; -$_SERVER['HTTP_USER_AGENT'] = 'dummy'; - -$_SERVER['SERVER_NAME'] = $CFG->chat_serverhost; -$_SERVER['PHP_SELF'] = "http://$CFG->chat_serverhost:$CFG->chat_serverport/mod/chat/chatd.php"; - -core_php_time_limit::raise(0); -error_reporting(E_ALL); - -function chat_empty_connection() { - return array('sid' => null, 'handle' => null, 'ip' => null, 'port' => null, 'groupid' => null); -} - -class ChatConnection { - // Chat-related info. - public $sid = null; - public $type = null; - - // PHP-level info. - public $handle = null; - - // TCP/IP. - public $ip = null; - public $port = null; - - public function __construct($resource) { - $this->handle = $resource; - @socket_getpeername($this->handle, $this->ip, $this->port); - } -} - -class ChatDaemon { - public $_resetsocket = false; - public $_readytogo = false; - public $_logfile = false; - public $_trace_to_console = true; - public $_trace_to_stdout = true; - public $_logfile_name = 'chatd.log'; - public $_last_idle_poll = 0; - - public $connectionsunidentified = array(); // Connections not identified yet. - public $connectionsside = array(); // Sessions with sidekicks waiting for the main connection to be processed. - public $connectionshalf = array(); // Sessions that have valid connections but not all of them. - public $connectionssets = array(); // Sessions with complete connection sets. - public $setsinfo = array(); // Keyed by sessionid exactly like conn_sets, one of these for each of those. - public $chatrooms = array(); // Keyed by chatid, holding arrays of data. - - /** @var int error reporting level. */ - public $_trace_level; - - /** @var bool true if function_name exists and is a function, false otherwise. */ - public $_pcntl_exists; - - /** @var int */ - public $_time_rest_socket; - - /** @var string beep file location. */ - public $_beepsoundsrc; - - /** @var int update frequency records. */ - public $_freq_update_records; - - /** @var int upper limit value in seconds to detect a user has disconnected or not. */ - public $_freq_poll_idle_chat; - - /** @var resource|false a file pointer resource on success, or false on error. */ - public $_stdout; - - /** @var array user data with session ID as the key. */ - public $sets_info = []; - - /** @var array connection data with session ID as the key. */ - public $conn_sets = []; - - /** @var array connection data. */ - public $conn_side = []; - - /** @var array connection data. */ - public $conn_half = []; - - /** @var array connection data. */ - public $conn_ufo = []; - - /** @var resource|Socket socket resource. */ - public $listen_socket; - - // IMPORTANT: $connectionssets, $setsinfo and $chatrooms must remain synchronized! - // Pay extra attention when you write code that affects any of them! - - public function __construct() { - $this->_trace_level = E_ALL ^ E_USER_NOTICE; - $this->_pcntl_exists = function_exists('pcntl_fork'); - $this->_time_rest_socket = 20; - $this->_beepsoundsrc = $GLOBALS['CFG']->wwwroot.'/mod/chat/beep.mp3'; - $this->_freq_update_records = 20; - $this->_freq_poll_idle_chat = $GLOBALS['CFG']->chat_old_ping; - $this->_stdout = fopen('php://stdout', 'w'); - if ($this->_stdout) { - // Avoid double traces for everything. - $this->_trace_to_console = false; - } - } - - public function error_handler($errno, $errmsg, $filename, $linenum, $vars) { - // Checks if an error needs to be suppressed due to @. - if (error_reporting() != 0) { - $this->trace($errmsg.' on line '.$linenum, $errno); - } - return true; - } - - public function poll_idle_chats($now) { - $this->trace('Polling chats to detect disconnected users'); - if (!empty($this->chatrooms)) { - foreach ($this->chatrooms as $chatid => $chatroom) { - if (!empty($chatroom['users'])) { - foreach ($chatroom['users'] as $sessionid => $userid) { - // We will be polling each user as required. - $this->trace('...shall we poll '.$sessionid.'?'); - if (!empty($this->sets_info[$sessionid]) && isset($this->sets_info[$sessionid]['chatuser']) && - // Having tried to exclude race conditions as already done in user_lazy_update() - // please do the real job by checking the last poll. - ($this->sets_info[$sessionid]['chatuser']->lastmessageping < $this->_last_idle_poll)) { - $this->trace('YES!'); - // This user hasn't been polled since his last message. - $result = $this->write_data($this->conn_sets[$sessionid][CHAT_CONNECTION_CHANNEL], ''); - if ($result === false) { - // User appears to have disconnected. - $this->disconnect_session($sessionid); - } - } - } - } - } - } - $this->_last_idle_poll = $now; - } - - public function query_start() { - return $this->_readytogo; - } - - public function trace($message, $level = E_USER_NOTICE) { - $severity = ''; - - switch($level) { - case E_USER_WARNING: - $severity = '*IMPORTANT* '; - break; - case E_USER_ERROR: - $severity = ' *CRITICAL* '; - break; - case E_NOTICE: - case E_WARNING: - $severity = ' *CRITICAL* [php] '; - break; - } - - $date = date('[Y-m-d H:i:s] '); - $message = $date.$severity.$message."\n"; - - if ($this->_trace_level & $level) { - // It is accepted for output. - - // Error-class traces go to STDERR too. - if ($level & E_USER_ERROR) { - fwrite(STDERR, $message); - } - - // Emit the message to wherever we should. - if ($this->_trace_to_stdout) { - fwrite($this->_stdout, $message); - fflush($this->_stdout); - } - if ($this->_trace_to_console) { - echo $message; - flush(); - } - if ($this->_logfile) { - fwrite($this->_logfile, $message); - fflush($this->_logfile); - } - } - } - - public function write_data($connection, $text) { - $written = @socket_write($connection, $text, strlen($text)); - if ($written === false) { - return false; - } - return true; - } - - public function user_lazy_update($sessionid) { - global $DB; - - if (empty($this->sets_info[$sessionid])) { - $this->trace('user_lazy_update() called for an invalid SID: '.$sessionid, E_USER_WARNING); - return false; - } - - // Does promote_final() already finish its job? - if (!isset($this->sets_info[$sessionid]['lastinfocommit'])) { - return false; - } - - $now = time(); - - // We 'll be cheating a little, and NOT updating the record data as - // often as we can, so that we save on DB queries (imagine MANY users). - if ($now - $this->sets_info[$sessionid]['lastinfocommit'] > $this->_freq_update_records) { - // Commit to permanent storage. - $this->sets_info[$sessionid]['lastinfocommit'] = $now; - $DB->update_record('chat_users', $this->sets_info[$sessionid]['chatuser']); - } - return true; - } - - public function get_user_window($sessionid) { - global $CFG, $OUTPUT; - - static $str; - - $info = &$this->sets_info[$sessionid]; - - $timenow = time(); - - if (empty($str)) { - $str = new stdClass(); - $str->idle = get_string("idle", "chat"); - $str->beep = get_string("beep", "chat"); - $str->day = get_string("day"); - $str->days = get_string("days"); - $str->hour = get_string("hour"); - $str->hours = get_string("hours"); - $str->min = get_string("min"); - $str->mins = get_string("mins"); - $str->sec = get_string("sec"); - $str->secs = get_string("secs"); - $str->years = get_string('years'); - } - - ob_start(); - $refreshinval = $CFG->chat_refresh_userlist * 1000; - echo << - - - -EOD; - - // Get the users from that chatroom. - $users = $this->chatrooms[$info['chatid']]['users']; - - foreach ($users as $usersessionid => $userid) { - // Fetch each user's sessionid and then the rest of his data from $this->sets_info. - $userinfo = $this->sets_info[$usersessionid]; - - $lastping = $timenow - $userinfo['chatuser']->lastmessageping; - - echo '"; - } - - echo '
'; - - $link = '/user/view.php?id='.$userinfo['user']->id.'&course='.$userinfo['courseid']; - $anchortagcontents = $OUTPUT->user_picture($userinfo['user'], array('courseid' => $userinfo['courseid'])); - - $action = new popup_action('click', $link, 'user'.$userinfo['chatuser']->id); - $anchortag = $OUTPUT->action_link($link, $anchortagcontents, $action); - - echo $anchortag; - echo ""; - echo "

"; - echo fullname($userinfo['user'])."
"; - echo "$str->idle: ".format_time($lastping, $str)." "; - echo ''.$str->beep."\n"; - echo "

"; - echo "
'; - echo "\n\n"; - - return ob_get_clean(); - - } - - public function new_ufo_id() { - static $id = 0; - if ($id++ === 0x1000000) { // Cycling very very slowly to prevent overflow. - $id = 0; - } - return $id; - } - - public function process_sidekicks($sessionid) { - if (empty($this->conn_side[$sessionid])) { - return true; - } - foreach ($this->conn_side[$sessionid] as $sideid => $sidekick) { - // TODO: is this late-dispatch working correctly? - $this->dispatch_sidekick($sidekick['handle'], $sidekick['type'], $sessionid, $sidekick['customdata']); - unset($this->conn_side[$sessionid][$sideid]); - } - return true; - } - - public function dispatch_sidekick($handle, $type, $sessionid, $customdata) { - global $CFG, $DB; - - switch($type) { - case CHAT_SIDEKICK_BEEP: - - // Incoming beep. - $msg = new stdClass; - $msg->chatid = $this->sets_info[$sessionid]['chatid']; - $msg->userid = $this->sets_info[$sessionid]['userid']; - $msg->groupid = $this->sets_info[$sessionid]['groupid']; - $msg->issystem = 0; - $msg->message = 'beep '.$customdata['beep']; - $msg->timestamp = time(); - - // Commit to DB. - chat_send_chatmessage($this->sets_info[$sessionid]['chatuser'], $msg->message, false, - $this->sets_info[$sessionid]['cm']); - - // OK, now push it out to all users. - $this->message_broadcast($msg, $this->sets_info[$sessionid]['user']); - - // Update that user's lastmessageping. - $this->sets_info[$sessionid]['chatuser']->lastping = $msg->timestamp; - $this->sets_info[$sessionid]['chatuser']->lastmessageping = $msg->timestamp; - $this->user_lazy_update($sessionid); - - // We did our work, but before slamming the door on the poor browser - // show the courtesy of responding to the HTTP request. Otherwise, some - // browsers decide to get vengeance by flooding us with repeat requests. - - $header = "HTTP/1.1 200 OK\n"; - $header .= "Connection: close\n"; - $header .= "Date: ".date('r')."\n"; - $header .= "Server: Moodle\n"; - $header .= "Content-Type: text/html; charset=utf-8\n"; - $header .= "Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT\n"; - $header .= "Cache-Control: no-cache, must-revalidate\n"; - $header .= "Expires: Wed, 4 Oct 1978 09:32:45 GMT\n"; - $header .= "\n"; - - // That's enough headers for one lousy dummy response. - $this->write_data($handle, $header); - // All done. - break; - - case CHAT_SIDEKICK_USERS: - // A request to paint a user window. - - $content = $this->get_user_window($sessionid); - - $header = "HTTP/1.1 200 OK\n"; - $header .= "Connection: close\n"; - $header .= "Date: ".date('r')."\n"; - $header .= "Server: Moodle\n"; - $header .= "Content-Type: text/html; charset=utf-8\n"; - $header .= "Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT\n"; - $header .= "Cache-Control: no-cache, must-revalidate\n"; - $header .= "Expires: Wed, 4 Oct 1978 09:32:45 GMT\n"; - $header .= "Content-Length: ".strlen($content)."\n"; - - // The refresh value is 2 seconds higher than the configuration variable. - // This is because we are doing JS refreshes all the time. - // However, if the JS doesn't work for some reason, we still want to refresh once in a while. - $header .= "Refresh: ".(intval($CFG->chat_refresh_userlist) + 2). - "; url=http://$CFG->chat_serverhost:$CFG->chat_serverport/?win=users&". - "chat_sid=".$sessionid."\n"; - $header .= "\n"; - - // That's enough headers for one lousy dummy response. - $this->trace('writing users http response to handle '.$handle); - $this->write_data($handle, $header . $content); - - // Update that user's lastping. - $this->sets_info[$sessionid]['chatuser']->lastping = time(); - $this->user_lazy_update($sessionid); - - break; - - case CHAT_SIDEKICK_MESSAGE: - // Incoming message. - - // Browser stupidity protection from duplicate messages. - $messageindex = intval($customdata['index']); - - if ($this->sets_info[$sessionid]['lastmessageindex'] >= $messageindex) { - // We have already broadcasted that! - break; - } else { - // Update our info. - $this->sets_info[$sessionid]['lastmessageindex'] = $messageindex; - } - - $msg = new stdClass; - $msg->chatid = $this->sets_info[$sessionid]['chatid']; - $msg->userid = $this->sets_info[$sessionid]['userid']; - $msg->groupid = $this->sets_info[$sessionid]['groupid']; - $msg->issystem = 0; - $msg->message = urldecode($customdata['message']); // Have to undo the browser's encoding. - $msg->timestamp = time(); - - if (empty($msg->message)) { - // Someone just hit ENTER, send them on their way. - break; - } - - // A slight hack to prevent malformed SQL inserts. - $origmsg = $msg->message; - $msg->message = $msg->message; - - // Commit to DB. - chat_send_chatmessage($this->sets_info[$sessionid]['chatuser'], $msg->message, false, - $this->sets_info[$sessionid]['cm']); - - // Undo the hack. - $msg->message = $origmsg; - - // OK, now push it out to all users. - $this->message_broadcast($msg, $this->sets_info[$sessionid]['user']); - - // Update that user's lastmessageping. - $this->sets_info[$sessionid]['chatuser']->lastping = $msg->timestamp; - $this->sets_info[$sessionid]['chatuser']->lastmessageping = $msg->timestamp; - $this->user_lazy_update($sessionid); - - // We did our work, but before slamming the door on the poor browser - // show the courtesy of responding to the HTTP request. Otherwise, some - // browsers decide to get vengeance by flooding us with repeat requests. - - $header = "HTTP/1.1 200 OK\n"; - $header .= "Connection: close\n"; - $header .= "Date: ".date('r')."\n"; - $header .= "Server: Moodle\n"; - $header .= "Content-Type: text/html; charset=utf-8\n"; - $header .= "Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT\n"; - $header .= "Cache-Control: no-cache, must-revalidate\n"; - $header .= "Expires: Wed, 4 Oct 1978 09:32:45 GMT\n"; - $header .= "\n"; - - // That's enough headers for one lousy dummy response. - $this->write_data($handle, $header); - - // All done. - break; - } - - socket_shutdown($handle); - socket_close($handle); - } - - public function promote_final($sessionid, $customdata) { - global $DB; - - if (isset($this->conn_sets[$sessionid])) { - $this->trace('Set cannot be finalized: Session '.$sessionid.' is already active'); - return false; - } - - $chatuser = $DB->get_record('chat_users', array('sid' => $sessionid)); - if ($chatuser === false) { - $this->dismiss_half($sessionid); - return false; - } - $chat = $DB->get_record('chat', array('id' => $chatuser->chatid)); - if ($chat === false) { - $this->dismiss_half($sessionid); - return false; - } - $user = $DB->get_record('user', array('id' => $chatuser->userid)); - if ($user === false) { - $this->dismiss_half($sessionid); - return false; - } - $course = $DB->get_record('course', array('id' => $chat->course)); - if ($course === false) { - $this->dismiss_half($sessionid); - return false; - } - if (!($cm = get_coursemodule_from_instance('chat', $chat->id, $course->id))) { - $this->dismiss_half($sessionid); - return false; - } - - global $CHAT_HTMLHEAD_JS; - - $this->conn_sets[$sessionid] = $this->conn_half[$sessionid]; - - // This whole thing needs to be purged of redundant info, and the - // code base to follow suit. But AFTER development is done. - $this->sets_info[$sessionid] = array( - 'lastinfocommit' => 0, - 'lastmessageindex' => 0, - 'course' => $course, - 'courseid' => $course->id, - 'chatuser' => $chatuser, - 'chatid' => $chat->id, - 'cm' => $cm, - 'user' => $user, - 'userid' => $user->id, - 'groupid' => $chatuser->groupid, - 'lang' => $chatuser->lang, - 'quirks' => $customdata['quirks'] - ); - - // If we know nothing about this chatroom, initialize it and add the user. - if (!isset($this->chatrooms[$chat->id]['users'])) { - $this->chatrooms[$chat->id]['users'] = array($sessionid => $user->id); - } else { - // Otherwise just add the user. - $this->chatrooms[$chat->id]['users'][$sessionid] = $user->id; - } - - $header = "HTTP/1.1 200 OK\n"; - $header .= "Connection: close\n"; - $header .= "Date: ".date('r')."\n"; - $header .= "Server: Moodle\n"; - $header .= "Content-Type: text/html; charset=utf-8\n"; - $header .= "Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT\n"; - $header .= "Cache-Control: no-cache, must-revalidate\n"; - $header .= "Expires: Wed, 4 Oct 1978 09:32:45 GMT\n"; - $header .= "\n"; - - $this->dismiss_half($sessionid, false); - $this->write_data($this->conn_sets[$sessionid][CHAT_CONNECTION_CHANNEL], $header . $CHAT_HTMLHEAD_JS); - $this->trace('Connection accepted: ' - .$this->conn_sets[$sessionid][CHAT_CONNECTION_CHANNEL] - .', SID: ' - .$sessionid - .' UID: ' - .$chatuser->userid - .' GID: ' - .$chatuser->groupid, E_USER_WARNING); - - // Finally, broadcast the "entered the chat" message. - - $msg = new stdClass; - $msg->chatid = $chatuser->chatid; - $msg->userid = $chatuser->userid; - $msg->groupid = $chatuser->groupid; - $msg->issystem = 1; - $msg->message = 'enter'; - $msg->timestamp = time(); - - chat_send_chatmessage($chatuser, $msg->message, true); - $this->message_broadcast($msg, $this->sets_info[$sessionid]['user']); - - return true; - } - - public function promote_ufo($handle, $type, $sessionid, $customdata) { - if (empty($this->conn_ufo)) { - return false; - } - foreach ($this->conn_ufo as $id => $ufo) { - if ($ufo->handle == $handle) { - // OK, got the id of the UFO, but what is it? - - if ($type & CHAT_SIDEKICK) { - // Is the main connection ready? - if (isset($this->conn_sets[$sessionid])) { - // Yes, so dispatch this sidekick now and be done with it. - $this->dispatch_sidekick($handle, $type, $sessionid, $customdata); - $this->dismiss_ufo($handle, false); - } else { - // No, so put it in the waiting list. - $this->trace('sidekick waiting'); - $this->conn_side[$sessionid][] = array('type' => $type, 'handle' => $handle, 'customdata' => $customdata); - } - return true; - } - - // If it's not a sidekick, at this point it can only be da man. - - if ($type & CHAT_CONNECTION) { - // This forces a new connection right now. - $this->trace('Incoming connection from '.$ufo->ip.':'.$ufo->port); - - // Do we have such a connection active? - if (isset($this->conn_sets[$sessionid])) { - // Yes, so regrettably we cannot promote you. - $this->trace('Connection rejected: session '.$sessionid.' is already final'); - $this->dismiss_ufo($handle, true, 'Your SID was rejected.'); - return false; - } - - // Join this with what we may have already. - $this->conn_half[$sessionid][$type] = $handle; - - // Do the bookkeeping. - $this->promote_final($sessionid, $customdata); - - // It's not a UFO anymore. - $this->dismiss_ufo($handle, false); - - // Dispatch waiting sidekicks. - $this->process_sidekicks($sessionid); - - return true; - } - } - } - return false; - } - - public function dismiss_half($sessionid, $disconnect = true) { - if (!isset($this->conn_half[$sessionid])) { - return false; - } - if ($disconnect) { - foreach ($this->conn_half[$sessionid] as $handle) { - @socket_shutdown($handle); - @socket_close($handle); - } - } - unset($this->conn_half[$sessionid]); - return true; - } - - public function dismiss_set($sessionid) { - if (!empty($this->conn_sets[$sessionid])) { - foreach ($this->conn_sets[$sessionid] as $handle) { - // Since we want to dismiss this, don't generate any errors if it's dead already. - @socket_shutdown($handle); - @socket_close($handle); - } - } - $chatroom = $this->sets_info[$sessionid]['chatid']; - $userid = $this->sets_info[$sessionid]['userid']; - unset($this->conn_sets[$sessionid]); - unset($this->sets_info[$sessionid]); - unset($this->chatrooms[$chatroom]['users'][$sessionid]); - $this->trace('Removed all traces of user with session '.$sessionid, E_USER_NOTICE); - return true; - } - - public function dismiss_ufo($handle, $disconnect = true, $message = null) { - if (empty($this->conn_ufo)) { - return false; - } - foreach ($this->conn_ufo as $id => $ufo) { - if ($ufo->handle == $handle) { - unset($this->conn_ufo[$id]); - if ($disconnect) { - if (!empty($message)) { - $this->write_data($handle, $message."\n\n"); - } - socket_shutdown($handle); - socket_close($handle); - } - return true; - } - } - return false; - } - - public function conn_accept() { - $readsocket = array($this->listen_socket); - $write = null; - $except = null; - $changed = socket_select($readsocket, $write, $except, 0, 0); - - if (!$changed) { - return false; - } - $handle = socket_accept($this->listen_socket); - if (!$handle) { - return false; - } - - $newconn = new ChatConnection($handle); - $id = $this->new_ufo_id(); - $this->conn_ufo[$id] = $newconn; - } - - public function conn_activity_ufo(&$handles) { - $monitor = array(); - if (!empty($this->conn_ufo)) { - foreach ($this->conn_ufo as $ufoid => $ufo) { - // Avoid socket_select() warnings by preventing the check over invalid resources. - if (is_resource($ufo->handle)) { - $monitor[$ufoid] = $ufo->handle; - } else { - $this->dismiss_ufo($ufo->handle, false); - } - } - } - - if (empty($monitor)) { - $handles = array(); - return 0; - } - - $a = null; - $b = null; - $retval = socket_select($monitor, $a, $b, null); - $handles = $monitor; - - return $retval; - } - - public function message_broadcast($message, $sender) { - - if (empty($this->conn_sets)) { - return true; - } - - $now = time(); - - // First of all, mark this chatroom as having had activity now. - $this->chatrooms[$message->chatid]['lastactivity'] = $now; - - foreach ($this->sets_info as $sessionid => $info) { - // We need to get handles from users that are in the same chatroom, same group. - if ($info['chatid'] == $message->chatid && - ($info['groupid'] == $message->groupid || $message->groupid == 0)) { - - // Simply give them the message. - $output = chat_format_message_manually($message, $info['courseid'], $sender, $info['user']); - if ($output !== false) { - $this->trace('Delivering message "'.$output->text.'" to ' . - $this->conn_sets[$sessionid][CHAT_CONNECTION_CHANNEL]); - - if ($output->beep) { - $playscript = '(function() { var audioElement = document.createElement("audio");' . "\n"; - $playscript .= 'audioElement.setAttribute("src", "'.$this->_beepsoundsrc.'");' . "\n"; - $playscript .= 'audioElement.play(); })();' . "\n"; - $this->write_data($this->conn_sets[$sessionid][CHAT_CONNECTION_CHANNEL], - ''); - } - - if ($info['quirks'] & QUIRK_CHUNK_UPDATE) { - $output->html .= $GLOBALS['CHAT_DUMMY_DATA']; - $output->html .= $GLOBALS['CHAT_DUMMY_DATA']; - $output->html .= $GLOBALS['CHAT_DUMMY_DATA']; - } - - if (!$this->write_data($this->conn_sets[$sessionid][CHAT_CONNECTION_CHANNEL], $output->html)) { - $this->disconnect_session($sessionid); - } - } - } - } - } - - public function disconnect_session($sessionid) { - global $DB; - - $info = $this->sets_info[$sessionid]; - - $DB->delete_records('chat_users', array('sid' => $sessionid)); - $msg = new stdClass; - $msg->chatid = $info['chatid']; - $msg->userid = $info['userid']; - $msg->groupid = $info['groupid']; - $msg->issystem = 1; - $msg->message = 'exit'; - $msg->timestamp = time(); - - $this->trace('User has disconnected, destroying uid '.$info['userid'].' with SID '.$sessionid, E_USER_WARNING); - chat_send_chatmessage($info['chatuser'], $msg->message, true); - - // IMPORTANT, kill him BEFORE broadcasting, otherwise we 'll get infinite recursion! - $latesender = $info['user']; - $this->dismiss_set($sessionid); - $this->message_broadcast($msg, $latesender); - } - - public function fatal($message) { - $message .= "\n"; - if ($this->_logfile) { - $this->trace($message, E_USER_ERROR); - } - echo "FATAL ERROR:: $message\n"; - die(); - } - - public function init_sockets() { - global $CFG; - - $this->trace('Setting up sockets'); - - if (false === ($this->listen_socket = socket_create(AF_INET, SOCK_STREAM, 0))) { - // Failed to create socket. - $lasterr = socket_last_error(); - $this->fatal('socket_create() failed: '. socket_strerror($lasterr).' ['.$lasterr.']'); - } - - if (!socket_bind($this->listen_socket, $CFG->chat_serverip, $CFG->chat_serverport)) { - // Failed to bind socket. - $lasterr = socket_last_error(); - $this->fatal('socket_bind() failed: '. socket_strerror($lasterr).' ['.$lasterr.']'); - } - - if (!socket_listen($this->listen_socket, $CFG->chat_servermax)) { - // Failed to get socket to listen. - $lasterr = socket_last_error(); - $this->fatal('socket_listen() failed: '. socket_strerror($lasterr).' ['.$lasterr.']'); - } - - // Socket has been initialized and is ready. - $this->trace('Socket opened on port '.$CFG->chat_serverport); - - // What exactly does this do? http://www.unixguide.net/network/socketfaq/4.5.shtml is still not enlightening enough for me. - socket_set_option($this->listen_socket, SOL_SOCKET, SO_REUSEADDR, 1); - socket_set_nonblock($this->listen_socket); - } - - public function cli_switch($switch, $param = null) { - switch($switch) { // LOL! - case 'reset': - // Reset sockets. - $this->_resetsocket = true; - return false; - case 'start': - // Start the daemon. - $this->_readytogo = true; - return false; - break; - case 'v': - // Verbose mode. - $this->_trace_level = E_ALL; - return false; - break; - case 'l': - // Use logfile. - if (!empty($param)) { - $this->_logfile_name = $param; - } - $this->_logfile = @fopen($this->_logfile_name, 'a+'); - if ($this->_logfile == false) { - $this->fatal('Failed to open '.$this->_logfile_name.' for writing'); - } - return false; - default: - // Unrecognized. - $this->fatal('Unrecognized command line switch: '.$switch); - break; - } - return false; - } - -} - -$daemon = new ChatDaemon; -set_error_handler(array($daemon, 'error_handler')); - -// Check the parameters. - -unset($argv[0]); -$commandline = implode(' ', $argv); -if (strpos($commandline, '-') === false) { - if (!empty($commandline)) { - // We cannot have received any meaningful parameters. - $daemon->fatal('Garbage in command line'); - } -} else { - // Parse command line. - $switches = preg_split('/(-{1,2}[a-zA-Z]+) */', $commandline, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); - - // Taking advantage of the fact that $switches is indexed with incrementing numeric keys. - // We will be using that to pass additional information to those switches who need it. - $numswitches = count($switches); - - // Fancy way to give a "hyphen" boolean flag to each "switch". - $switches = array_map(function($x) { - return array("str" => $x, "hyphen" => (substr($x, 0, 1) == "-")); - }, $switches); - - for ($i = 0; $i < $numswitches; ++$i) { - - $switch = $switches[$i]['str']; - $params = ($i == $numswitches - 1 ? null : - ($switches[$i + 1]['hyphen'] ? null : trim($switches[$i + 1]['str'])) - ); - - if (substr($switch, 0, 2) == '--') { - // Double-hyphen switch. - $daemon->cli_switch(strtolower(substr($switch, 2)), $params); - } else if (substr($switch, 0, 1) == '-') { - // Single-hyphen switch(es), may be more than one run together. - $switch = substr($switch, 1); // Get rid of the "-". - $len = strlen($switch); - for ($j = 0; $j < $len; ++$j) { - $daemon->cli_switch(strtolower(substr($switch, $j, 1)), $params); - } - } - } -} - -if (!$daemon->query_start()) { - // For some reason we didn't start, so print out some info. - echo 'Starts the Moodle chat socket server on port '.$CFG->chat_serverport; - echo "\n\n"; - echo "Usage: chatd.php [parameters]\n\n"; - echo "Parameters:\n"; - echo " --start Starts the daemon\n"; - echo " -v Verbose mode (prints trivial information messages)\n"; - echo " -l [logfile] Log all messages to logfile (if not specified, chatd.log)\n"; - echo "Example:\n"; - echo " chatd.php --start -l\n\n"; - die(); -} - -if (!function_exists('socket_set_option')) { - echo "Error: Function socket_set_option() does not exist.\n"; - echo "Possibly PHP has not been compiled with --enable-sockets.\n\n"; - die(); -} - -$daemon->init_sockets(); - -$daemon->trace('Started Moodle chatd on port '.$CFG->chat_serverport.', listening socket '.$daemon->listen_socket, E_USER_WARNING); - -// Clear the decks of old stuff. -$DB->delete_records('chat_users', array('version' => 'sockets')); - -while (true) { - $active = array(); - - // First of all, let's see if any of our UFOs have identified itself. - if ($daemon->conn_activity_ufo($active)) { - foreach ($active as $handle) { - $readsocket = array($handle); - $write = null; - $except = null; - $changed = socket_select($readsocket, $write, $except, 0, 0); - - if ($changed > 0) { - // Let's see what it has to say. - - $data = socket_read($handle, 2048); // Should be more than 512 to prevent empty pages and repeated messages! - if (empty($data)) { - continue; - } - - if (strlen($data) == 2048) { // If socket_read has more data, ignore all data. - $daemon->trace('UFO with '.$handle.': Data too long; connection closed', E_USER_WARNING); - $daemon->dismiss_ufo($handle, true, 'Data too long; connection closed'); - continue; - } - - // Ignore desktop browser fake "favorite icon" requests. - if (strpos($data, 'GET /favicon.ico HTTP') === 0) { - // Known malformed data, drop it without any further notice. - continue; - } - - if (!preg_match('/win=(chat|users|message|beep).*&chat_sid=([a-zA-Z0-9]*) HTTP/', $data, $info)) { - // Malformed data. - $daemon->trace('UFO with '.$handle.': Request with malformed data; connection closed', E_USER_WARNING); - $daemon->dismiss_ufo($handle, true, 'Request with malformed data; connection closed'); - continue; - } - - $type = $info[1]; - $sessionid = $info[2]; - - $customdata = array(); - - switch($type) { - case 'chat': - $type = CHAT_CONNECTION_CHANNEL; - $customdata['quirks'] = 0; - if (strpos($data, 'Safari')) { - $daemon->trace('Safari identified...', E_USER_WARNING); - $customdata['quirks'] += QUIRK_CHUNK_UPDATE; - } - break; - case 'users': - $type = CHAT_SIDEKICK_USERS; - break; - case 'beep': - $type = CHAT_SIDEKICK_BEEP; - if (!preg_match('/beep=([^&]*)[& ]/', $data, $info)) { - $daemon->trace('Beep sidekick did not contain a valid userid', E_USER_WARNING); - $daemon->dismiss_ufo($handle, true, 'Request with malformed data; connection closed'); - continue 2; - } else { - $customdata = array('beep' => intval($info[1])); - } - break; - case 'message': - $type = CHAT_SIDEKICK_MESSAGE; - if (!preg_match('/chat_message=([^&]*)[& ]chat_msgidnr=([^&]*)[& ]/', $data, $info)) { - $daemon->trace('Message sidekick did not contain a valid message', E_USER_WARNING); - $daemon->dismiss_ufo($handle, true, 'Request with malformed data; connection closed'); - continue 2; - } else { - $customdata = array('message' => $info[1], 'index' => $info[2]); - } - break; - default: - $daemon->trace('UFO with '.$handle.': Request with unknown type; connection closed', E_USER_WARNING); - $daemon->dismiss_ufo($handle, true, 'Request with unknown type; connection closed'); - continue 2; - break; - } - - // OK, now we know it's something good. Promote it and pass it all the data it needs. - $daemon->promote_ufo($handle, $type, $sessionid, $customdata); - continue; - } - } - } - - $now = time(); - - // Clean up chatrooms with no activity as required. - if ($now - $daemon->_last_idle_poll >= $daemon->_freq_poll_idle_chat) { - $daemon->poll_idle_chats($now); - } - - // Finally, accept new connections. - $daemon->conn_accept(); - - usleep($daemon->_time_rest_socket); -} - -@socket_shutdown($daemon->listen_socket, 0); -die("\n\n-- terminated --\n"); - diff --git a/mod/chat/classes/analytics/indicator/activity_base.php b/mod/chat/classes/analytics/indicator/activity_base.php deleted file mode 100644 index 1264e171755..00000000000 --- a/mod/chat/classes/analytics/indicator/activity_base.php +++ /dev/null @@ -1,111 +0,0 @@ -. - -/** - * Activity base class. - * - * @package mod_chat - * @copyright 2017 onwards Ankit Agarwal - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace mod_chat\analytics\indicator; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Activity base class. - * - * @package mod_chat - * @copyright 2017 onwards Ankit Agarwal - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -abstract class activity_base extends \core_analytics\local\indicator\community_of_inquiry_activity { - - /** - * feedback_viewed_events - * - * @return string[] - */ - protected function feedback_viewed_events() { - return array('\mod_chat\event\course_module_viewed', '\mod_chat\event\message_sent', - '\mod_chat\event\sessions_viewed'); - } - - /** - * feedback_replied_events - * - * @return string[] - */ - protected function feedback_replied_events() { - return array('\mod_chat\event\message_sent'); - } - - /** - * feedback_post_action - * - * @param \cm_info $cm - * @param int $contextid - * @param int $userid - * @param string[] $eventnames - * @param int $after - * @return bool - */ - protected function feedback_post_action(\cm_info $cm, $contextid, $userid, $eventnames, $after = false) { - - if (empty($this->activitylogs[$contextid][$userid])) { - return false; - } - - $logs = $this->activitylogs[$contextid][$userid]; - - if (empty($logs['\mod_chat\event\message_sent'])) { - // No feedback viewed if there is no submission. - return false; - } - - // First user message time. - $firstmessage = $logs['\mod_chat\event\message_sent']->timecreated[0]; - - // We consider feedback another user messages. - foreach ($this->activitylogs[$contextid] as $anotheruserid => $logs) { - if ($anotheruserid == $userid) { - continue; - } - if (empty($logs['\mod_chat\event\message_sent'])) { - continue; - } - $firstmessagesenttime = $logs['\mod_chat\event\message_sent']->timecreated[0]; - - if (parent::feedback_post_action($cm, $contextid, $userid, $eventnames, $firstmessagesenttime)) { - return true; - } - // Continue with the next user. - } - - return false; - } - - /** - * feedback_check_grades - * - * @return bool - */ - protected function feedback_check_grades() { - // Chat's feedback is not contained in grades. - return false; - } -} diff --git a/mod/chat/classes/analytics/indicator/cognitive_depth.php b/mod/chat/classes/analytics/indicator/cognitive_depth.php deleted file mode 100644 index 4343c3c2023..00000000000 --- a/mod/chat/classes/analytics/indicator/cognitive_depth.php +++ /dev/null @@ -1,56 +0,0 @@ -. - -/** - * Cognitive depth indicator - chat. - * - * @package mod_chat - * @copyright 2017 David Monllao {@link http://www.davidmonllao.com} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace mod_chat\analytics\indicator; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Cognitive depth indicator - chat. - * - * @package mod_chat - * @copyright 2017 David Monllao {@link http://www.davidmonllao.com} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class cognitive_depth extends activity_base { - - /** - * Returns the name. - * - * If there is a corresponding '_help' string this will be shown as well. - * - * @return \lang_string - */ - public static function get_name(): \lang_string { - return new \lang_string('indicator:cognitivedepth', 'mod_chat'); - } - - public function get_indicator_type() { - return self::INDICATOR_COGNITIVE; - } - - public function get_cognitive_depth_level(\cm_info $cm) { - return self::COGNITIVE_LEVEL_4; - } -} diff --git a/mod/chat/classes/analytics/indicator/social_breadth.php b/mod/chat/classes/analytics/indicator/social_breadth.php deleted file mode 100644 index f7b64e4c16a..00000000000 --- a/mod/chat/classes/analytics/indicator/social_breadth.php +++ /dev/null @@ -1,56 +0,0 @@ -. - -/** - * Social breadth indicator - chat. - * - * @package mod_chat - * @copyright 2017 David Monllao {@link http://www.davidmonllao.com} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace mod_chat\analytics\indicator; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Social breadth indicator - chat. - * - * @package mod_chat - * @copyright 2017 David Monllao {@link http://www.davidmonllao.com} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class social_breadth extends activity_base { - - /** - * Returns the name. - * - * If there is a corresponding '_help' string this will be shown as well. - * - * @return \lang_string - */ - public static function get_name(): \lang_string { - return new \lang_string('indicator:socialbreadth', 'mod_chat'); - } - - public function get_indicator_type() { - return self::INDICATOR_SOCIAL; - } - - public function get_social_breadth_level(\cm_info $cm) { - return self::SOCIAL_LEVEL_2; - } -} diff --git a/mod/chat/classes/dates.php b/mod/chat/classes/dates.php deleted file mode 100644 index cffdd87a092..00000000000 --- a/mod/chat/classes/dates.php +++ /dev/null @@ -1,58 +0,0 @@ -. - -/** - * Contains the class for fetching the important dates in mod_chat for a given module instance and a user. - * - * @package mod_chat - * @copyright 2021 Dongsheng Cai - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -declare(strict_types=1); - -namespace mod_chat; - -use core\activity_dates; - -/** - * Class for fetching the important dates in mod_chat for a given module instance and a user. - * - */ -class dates extends activity_dates { - /** - * Returns a list of important dates in mod_chat. - * - * @return array - */ - protected function get_dates(): array { - $customdata = $this->cm->customdata; - $chat = (object) $customdata; - $chattime = $chat->chattime ?? 0; - $now = time(); - if (!empty($chat->schedule) && $chattime > $now) { - return [ - [ - 'dataid' => 'chattime', - 'label' => get_string('nextchattime', 'mod_chat'), - 'timestamp' => (int) $chattime - ] - ]; - } - - return []; - } -} diff --git a/mod/chat/classes/event/course_module_instance_list_viewed.php b/mod/chat/classes/event/course_module_instance_list_viewed.php deleted file mode 100644 index b3df3382205..00000000000 --- a/mod/chat/classes/event/course_module_instance_list_viewed.php +++ /dev/null @@ -1,38 +0,0 @@ -. - -/** - * The mod_chat instance list viewed event. - * - * @package mod_chat - * @copyright 2013 onwards Ankit Agarwal - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace mod_chat\event; -defined('MOODLE_INTERNAL') || die(); - -/** - * The mod_chat instance list viewed event class. - * - * @package mod_chat - * @since Moodle 2.7 - * @copyright 2013 onwards Ankit Agarwal - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class course_module_instance_list_viewed extends \core\event\course_module_instance_list_viewed { -} - diff --git a/mod/chat/classes/event/course_module_viewed.php b/mod/chat/classes/event/course_module_viewed.php deleted file mode 100644 index 854699262a5..00000000000 --- a/mod/chat/classes/event/course_module_viewed.php +++ /dev/null @@ -1,47 +0,0 @@ -. - -/** - * The mod_chat course module viewed event. - * - * @package mod_chat - * @copyright 2014 Petr Skoda - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace mod_chat\event; - -defined('MOODLE_INTERNAL') || die(); - -/** - * The mod_chat course module viewed event class. - * - * @package mod_chat - * @since Moodle 2.7 - * @copyright 2014 Petr Skoda - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class course_module_viewed extends \core\event\course_module_viewed { - protected function init() { - $this->data['crud'] = 'r'; - $this->data['edulevel'] = self::LEVEL_PARTICIPATING; - $this->data['objecttable'] = 'chat'; - } - - public static function get_objectid_mapping() { - return array('db' => 'chat', 'restore' => 'chat'); - } -} diff --git a/mod/chat/classes/event/message_sent.php b/mod/chat/classes/event/message_sent.php deleted file mode 100644 index ab491a3bdd4..00000000000 --- a/mod/chat/classes/event/message_sent.php +++ /dev/null @@ -1,93 +0,0 @@ -. - -/** - * The mod_chat message sent event. - * - * @package mod_chat - * @copyright 2013 Frédéric Massart - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace mod_chat\event; -defined('MOODLE_INTERNAL') || die(); - -/** - * The mod_chat message sent event class. - * - * @package mod_chat - * @since Moodle 2.6 - * @copyright 2013 Frédéric Massart - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class message_sent extends \core\event\base { - - /** - * Returns description of what happened. - * - * @return string - */ - public function get_description() { - return "The user with id '$this->relateduserid' has sent a message in the chat with course module id - '$this->contextinstanceid'."; - } - - /** - * Return localised event name. - * - * @return string - */ - public static function get_name() { - return get_string('eventmessagesent', 'mod_chat'); - } - - /** - * Get URL related to the action - * - * @return \moodle_url - */ - public function get_url() { - return new \moodle_url('/mod/chat/view.php', array('id' => $this->contextinstanceid)); - } - - /** - * Init method. - * - * @return void - */ - protected function init() { - $this->data['crud'] = 'c'; - $this->data['edulevel'] = self::LEVEL_PARTICIPATING; - $this->data['objecttable'] = 'chat_messages'; - } - - /** - * Custom validation. - * - * @throws \coding_exception - * @return void - */ - protected function validate_data() { - parent::validate_data(); - if (!isset($this->relateduserid)) { - throw new \coding_exception('The \'relateduserid\' must be set.'); - } - } - - public static function get_objectid_mapping() { - return array('db' => 'chat_messages', 'restore' => 'chat_message'); - } -} diff --git a/mod/chat/classes/event/sessions_viewed.php b/mod/chat/classes/event/sessions_viewed.php deleted file mode 100644 index 77d2caafb47..00000000000 --- a/mod/chat/classes/event/sessions_viewed.php +++ /dev/null @@ -1,108 +0,0 @@ -. - -/** - * The mod_chat sessions viewed event. - * - * @package mod_chat - * @copyright 2013 Frédéric Massart - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace mod_chat\event; -defined('MOODLE_INTERNAL') || die(); - -/** - * The mod_chat sessions viewed event class. - * - * @property-read array $other { - * Extra information about the event. - * - * - int start: start of period. - * - int end: end of period. - * } - * - * @package mod_chat - * @since Moodle 2.6 - * @copyright 2013 Frédéric Massart - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class sessions_viewed extends \core\event\base { - - /** - * Returns description of what happened. - * - * @return string - */ - public function get_description() { - return "The user with id '$this->userid' has viewed the sessions of the chat with course module id - '$this->contextinstanceid'."; - } - - /** - * Return localised event name. - * - * @return string - */ - public static function get_name() { - return get_string('eventsessionsviewed', 'mod_chat'); - } - - /** - * Get URL related to the action - * - * @return \moodle_url - */ - public function get_url() { - return new \moodle_url('/mod/chat/report.php', array('id' => $this->contextinstanceid)); - } - - /** - * Init method. - * - * @return void - */ - protected function init() { - $this->data['crud'] = 'r'; - $this->data['edulevel'] = self::LEVEL_OTHER; - $this->data['objecttable'] = 'chat'; - } - - /** - * Custom validation. - * - * @throws \coding_exception - * @return void - */ - protected function validate_data() { - parent::validate_data(); - if (!isset($this->other['start'])) { - throw new \coding_exception('The \'start\' value must be set in other.'); - } - if (!isset($this->other['end'])) { - throw new \coding_exception('The \'end\' value must be set in other.'); - } - } - - public static function get_objectid_mapping() { - return array('db' => 'chat', 'restore' => 'chat'); - } - - public static function get_other_mapping() { - // Nothing to map. - return false; - } -} diff --git a/mod/chat/classes/external.php b/mod/chat/classes/external.php deleted file mode 100644 index 5f75d30b9e8..00000000000 --- a/mod/chat/classes/external.php +++ /dev/null @@ -1,833 +0,0 @@ -. - -/** - * Chat external API - * - * @package mod_chat - * @category external - * @copyright 2015 Juan Leyva - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @since Moodle 3.0 - */ - -defined('MOODLE_INTERNAL') || die; - -require_once($CFG->dirroot . '/mod/chat/lib.php'); - -use core_course\external\helper_for_get_mods_by_courses; -use core_external\external_api; -use core_external\external_function_parameters; -use core_external\external_multiple_structure; -use core_external\external_single_structure; -use core_external\external_value; -use core_external\external_warnings; -use core_external\util; -use mod_chat\external\chat_message_exporter; - -/** - * Chat external functions - * - * @package mod_chat - * @category external - * @copyright 2015 Juan Leyva - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @since Moodle 3.0 - */ -class mod_chat_external extends external_api { - - /** - * Returns description of method parameters - * - * @return external_function_parameters - * @since Moodle 3.0 - */ - public static function login_user_parameters() { - return new external_function_parameters( - array( - 'chatid' => new external_value(PARAM_INT, 'chat instance id'), - 'groupid' => new external_value(PARAM_INT, 'group id, 0 means that the function will determine the user group', - VALUE_DEFAULT, 0), - ) - ); - } - - /** - * Log the current user into a chat room in the given chat. - * - * @param int $chatid the chat instance id - * @param int $groupid the user group id - * @return array of warnings and the chat unique session id - * @since Moodle 3.0 - * @throws moodle_exception - */ - public static function login_user($chatid, $groupid = 0) { - global $DB; - - $params = self::validate_parameters(self::login_user_parameters(), - array( - 'chatid' => $chatid, - 'groupid' => $groupid - )); - $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); - - require_capability('mod/chat:chat', $context); - - 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; - } - } - - // Get the unique chat session id. - // Since we are going to use the chat via Web Service requests we set the ajax version (since it's the most similar). - if (!$chatsid = chat_login_user($chat->id, 'ajax', $groupid, $course)) { - throw new moodle_exception('cantlogin', 'chat'); - } - - $result = array(); - $result['chatsid'] = $chatsid; - $result['warnings'] = $warnings; - return $result; - } - - /** - * Returns description of method result value - * - * @return \core_external\external_description - * @since Moodle 3.0 - */ - public static function login_user_returns() { - return new external_single_structure( - array( - 'chatsid' => new external_value(PARAM_ALPHANUM, 'unique chat session id'), - 'warnings' => new external_warnings() - ) - ); - } - - /** - * Returns description of method parameters - * - * @return external_function_parameters - * @since Moodle 3.0 - */ - public static function get_chat_users_parameters() { - return new external_function_parameters( - array( - 'chatsid' => new external_value(PARAM_ALPHANUM, 'chat session id (obtained via mod_chat_login_user)') - ) - ); - } - - /** - * Get the list of users in the given chat session. - * - * @param int $chatsid the chat session id - * @return array of warnings and the user lists - * @since Moodle 3.0 - * @throws moodle_exception - */ - public static function get_chat_users($chatsid) { - global $DB, $PAGE; - - $params = self::validate_parameters(self::get_chat_users_parameters(), - array( - 'chatsid' => $chatsid - )); - $warnings = array(); - - // Request and permission validation. - if (!$chatuser = $DB->get_record('chat_users', array('sid' => $params['chatsid']))) { - throw new moodle_exception('notlogged', 'chat'); - } - $chat = $DB->get_record('chat', array('id' => $chatuser->chatid), '*', MUST_EXIST); - list($course, $cm) = get_course_and_cm_from_instance($chat, 'chat'); - - $context = context_module::instance($cm->id); - self::validate_context($context); - - require_capability('mod/chat:chat', $context); - - // First, delete old users from the chats. - chat_delete_old_users(); - - $users = chat_get_users($chatuser->chatid, $chatuser->groupid, $cm->groupingid); - $returnedusers = array(); - - foreach ($users as $user) { - - $userpicture = new user_picture($user); - $userpicture->size = 1; // Size f1. - $profileimageurl = $userpicture->get_url($PAGE)->out(false); - - $returnedusers[] = array( - 'id' => $user->id, - 'fullname' => fullname($user), - 'profileimageurl' => $profileimageurl - ); - } - - $result = array(); - $result['users'] = $returnedusers; - $result['warnings'] = $warnings; - return $result; - } - - /** - * Returns description of method result value - * - * @return \core_external\external_description - * @since Moodle 3.0 - */ - public static function get_chat_users_returns() { - return new external_single_structure( - array( - 'users' => new external_multiple_structure( - new external_single_structure( - array( - 'id' => new external_value(PARAM_INT, 'user id'), - 'fullname' => new external_value(PARAM_NOTAGS, 'user full name'), - 'profileimageurl' => new external_value(PARAM_URL, 'user picture URL'), - ) - ), - 'list of users' - ), - 'warnings' => new external_warnings() - ) - ); - } - - /** - * Returns description of method parameters - * - * @return external_function_parameters - * @since Moodle 3.0 - */ - public static function send_chat_message_parameters() { - return new external_function_parameters( - array( - 'chatsid' => new external_value(PARAM_ALPHANUM, 'chat session id (obtained via mod_chat_login_user)'), - 'messagetext' => new external_value(PARAM_RAW, 'the message text'), - 'beepid' => new external_value(PARAM_RAW, 'the beep id', VALUE_DEFAULT, ''), - - ) - ); - } - - /** - * Send a message on the given chat session. - * - * @param int $chatsid the chat session id - * @param string $messagetext the message text - * @param string $beepid the beep message id - * @return array of warnings and the new message id (0 if the message was empty) - * @since Moodle 3.0 - * @throws moodle_exception - */ - public static function send_chat_message($chatsid, $messagetext, $beepid = '') { - global $DB; - - $params = self::validate_parameters(self::send_chat_message_parameters(), - array( - 'chatsid' => $chatsid, - 'messagetext' => $messagetext, - 'beepid' => $beepid - )); - $warnings = array(); - - // Request and permission validation. - if (!$chatuser = $DB->get_record('chat_users', array('sid' => $params['chatsid']))) { - throw new moodle_exception('notlogged', 'chat'); - } - $chat = $DB->get_record('chat', array('id' => $chatuser->chatid), '*', MUST_EXIST); - list($course, $cm) = get_course_and_cm_from_instance($chat, 'chat'); - - $context = context_module::instance($cm->id); - self::validate_context($context); - - require_capability('mod/chat:chat', $context); - - $chatmessage = clean_text($params['messagetext'], FORMAT_MOODLE); - - if (!empty($params['beepid'])) { - $chatmessage = 'beep ' . $params['beepid']; - } - - if (!empty($chatmessage)) { - // Send the message. - $messageid = chat_send_chatmessage($chatuser, $chatmessage, 0, $cm); - // Update ping time. - $chatuser->lastmessageping = time() - 2; - $DB->update_record('chat_users', $chatuser); - } else { - $messageid = 0; - } - - $result = array(); - $result['messageid'] = $messageid; - $result['warnings'] = $warnings; - return $result; - } - - /** - * Returns description of method result value - * - * @return \core_external\external_description - * @since Moodle 3.0 - */ - public static function send_chat_message_returns() { - return new external_single_structure( - array( - 'messageid' => new external_value(PARAM_INT, 'message sent id'), - 'warnings' => new external_warnings() - ) - ); - } - - /** - * Returns description of method parameters - * - * @return external_function_parameters - * @since Moodle 3.0 - */ - public static function get_chat_latest_messages_parameters() { - return new external_function_parameters( - array( - 'chatsid' => new external_value(PARAM_ALPHANUM, 'chat session id (obtained via mod_chat_login_user)'), - 'chatlasttime' => new external_value(PARAM_INT, 'last time messages were retrieved (epoch time)', VALUE_DEFAULT, 0) - ) - ); - } - - /** - * Get the latest messages from the given chat session. - * - * @param int $chatsid the chat session id - * @param int $chatlasttime last time messages were retrieved (epoch time) - * @return array of warnings and the new message id (0 if the message was empty) - * @since Moodle 3.0 - * @throws moodle_exception - */ - public static function get_chat_latest_messages($chatsid, $chatlasttime = 0) { - global $DB, $CFG; - - $params = self::validate_parameters(self::get_chat_latest_messages_parameters(), - array( - 'chatsid' => $chatsid, - 'chatlasttime' => $chatlasttime - )); - $warnings = array(); - - // Request and permission validation. - if (!$chatuser = $DB->get_record('chat_users', array('sid' => $params['chatsid']))) { - throw new moodle_exception('notlogged', 'chat'); - } - $chat = $DB->get_record('chat', array('id' => $chatuser->chatid), '*', MUST_EXIST); - list($course, $cm) = get_course_and_cm_from_instance($chat, 'chat'); - - $context = context_module::instance($cm->id); - self::validate_context($context); - - require_capability('mod/chat:chat', $context); - - $chatlasttime = $params['chatlasttime']; - if ((time() - $chatlasttime) > $CFG->chat_old_ping) { - chat_delete_old_users(); - } - - // Set default chat last time (to not retrieve all the conversations). - if ($chatlasttime == 0) { - $chatlasttime = time() - $CFG->chat_old_ping; - } - - if ($latestmessage = chat_get_latest_message($chatuser->chatid, $chatuser->groupid)) { - $chatnewlasttime = $latestmessage->timestamp; - } else { - $chatnewlasttime = 0; - } - - $messages = chat_get_latest_messages($chatuser, $chatlasttime); - $returnedmessages = array(); - - foreach ($messages as $message) { - // FORMAT_MOODLE is mandatory in the chat plugin. - [$messageformatted] = \core_external\util::format_text( - $message->message, - FORMAT_MOODLE, - $context->id, - 'mod_chat', - '', - 0 - ); - - $returnedmessages[] = array( - 'id' => $message->id, - 'userid' => $message->userid, - 'system' => (bool) $message->issystem, - 'message' => $messageformatted, - 'timestamp' => $message->timestamp, - ); - } - - // Update our status since we are active in the chat. - $DB->set_field('chat_users', 'lastping', time(), array('id' => $chatuser->id)); - - $result = array(); - $result['messages'] = $returnedmessages; - $result['chatnewlasttime'] = $chatnewlasttime; - $result['warnings'] = $warnings; - return $result; - } - - /** - * Returns description of method result value - * - * @return \core_external\external_description - * @since Moodle 3.0 - */ - public static function get_chat_latest_messages_returns() { - return new external_single_structure( - array( - 'messages' => new external_multiple_structure( - new external_single_structure( - array( - 'id' => new external_value(PARAM_INT, 'message id'), - 'userid' => new external_value(PARAM_INT, 'user id'), - 'system' => new external_value(PARAM_BOOL, 'true if is a system message (like user joined)'), - 'message' => new external_value(PARAM_RAW, 'message text'), - 'timestamp' => new external_value(PARAM_INT, 'timestamp for the message'), - ) - ), - 'list of users' - ), - 'chatnewlasttime' => new external_value(PARAM_INT, 'new last time'), - 'warnings' => new external_warnings() - ) - ); - } - - /** - * Returns description of method parameters - * - * @return external_function_parameters - * @since Moodle 3.0 - */ - public static function view_chat_parameters() { - return new external_function_parameters( - array( - 'chatid' => new external_value(PARAM_INT, 'chat instance id') - ) - ); - } - - /** - * Trigger the course module viewed event and update the module completion status. - * - * @param int $chatid the chat instance id - * @return array of warnings and status result - * @since Moodle 3.0 - * @throws moodle_exception - */ - public static function view_chat($chatid) { - global $DB, $CFG; - - $params = self::validate_parameters(self::view_chat_parameters(), - array( - 'chatid' => $chatid - )); - $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); - - require_capability('mod/chat:chat', $context); - - // Call the url/lib API. - chat_view($chat, $course, $cm, $context); - - $result = array(); - $result['status'] = true; - $result['warnings'] = $warnings; - return $result; - } - - /** - * Returns description of method result value - * - * @return \core_external\external_description - * @since Moodle 3.0 - */ - public static function view_chat_returns() { - return new external_single_structure( - array( - 'status' => new external_value(PARAM_BOOL, 'status: true if success'), - 'warnings' => new external_warnings() - ) - ); - } - - - /** - * Describes the parameters for get_chats_by_courses. - * - * @return external_function_parameters - * @since Moodle 3.0 - */ - public static function get_chats_by_courses_parameters() { - return new external_function_parameters ( - array( - 'courseids' => new external_multiple_structure( - new external_value(PARAM_INT, 'course id'), 'Array of course ids', VALUE_DEFAULT, array() - ), - ) - ); - } - - /** - * Returns a list of chats in a provided list of courses, - * if no list is provided all chats that the user can view will be returned. - * - * @param array $courseids the course ids - * @return array of chats details - * @since Moodle 3.0 - */ - public static function get_chats_by_courses($courseids = array()) { - global $CFG; - - $returnedchats = array(); - $warnings = array(); - - $params = self::validate_parameters(self::get_chats_by_courses_parameters(), array('courseids' => $courseids)); - - $courses = array(); - if (empty($params['courseids'])) { - $courses = enrol_get_my_courses(); - $params['courseids'] = array_keys($courses); - } - - // Ensure there are courseids to loop through. - if (!empty($params['courseids'])) { - - list($courses, $warnings) = util::validate_courses($params['courseids'], $courses); - - // Get the chats in this course, this function checks users visibility permissions. - // We can avoid then additional validate_context calls. - $chats = get_all_instances_in_courses("chat", $courses); - foreach ($chats as $chat) { - $chatcontext = context_module::instance($chat->coursemodule); - - $chatdetails = helper_for_get_mods_by_courses::standard_coursemodule_element_values($chat, 'mod_chat'); - - if (has_capability('mod/chat:chat', $chatcontext)) { - $chatdetails['chatmethod'] = $CFG->chat_method; - $chatdetails['keepdays'] = $chat->keepdays; - $chatdetails['studentlogs'] = $chat->studentlogs; - $chatdetails['chattime'] = $chat->chattime; - $chatdetails['schedule'] = $chat->schedule; - } - - if (has_capability('moodle/course:manageactivities', $chatcontext)) { - $chatdetails['timemodified'] = $chat->timemodified; - } - $returnedchats[] = $chatdetails; - } - } - $result = array(); - $result['chats'] = $returnedchats; - $result['warnings'] = $warnings; - return $result; - } - - /** - * Describes the get_chats_by_courses return value. - * - * @return external_single_structure - * @since Moodle 3.0 - */ - public static function get_chats_by_courses_returns() { - return new external_single_structure( - array( - 'chats' => new external_multiple_structure( - new external_single_structure(array_merge( - helper_for_get_mods_by_courses::standard_coursemodule_elements_returns(), - [ - 'chatmethod' => new external_value(PARAM_PLUGIN, 'chat method (sockets, ajax, header_js)', - VALUE_OPTIONAL), - 'keepdays' => new external_value(PARAM_INT, 'keep days', VALUE_OPTIONAL), - 'studentlogs' => new external_value(PARAM_INT, 'student logs visible to everyone', VALUE_OPTIONAL), - 'chattime' => new external_value(PARAM_INT, 'chat time', VALUE_OPTIONAL), - 'schedule' => new external_value(PARAM_INT, 'schedule type', VALUE_OPTIONAL), - 'timemodified' => new external_value(PARAM_INT, 'time of last modification', VALUE_OPTIONAL), - ] - ), 'Chats') - ), - 'warnings' => new external_warnings(), - ) - ); - } - - /** - * Returns description of method parameters - * - * @return external_function_parameters - * @since Moodle 3.4 - */ - public static function get_sessions_parameters() { - return new external_function_parameters( - array( - 'chatid' => new external_value(PARAM_INT, 'Chat instance id.'), - '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), - 'showall' => new external_value(PARAM_BOOL, 'Whether to show completed sessions or not.', VALUE_DEFAULT, false), - ) - ); - } - - /** - * Retrieves chat sessions for a given chat. - * - * @param int $chatid the chat instance id - * @param int $groupid filter messages by this group. 0 to determine the group. - * @param bool $showall whether to include incomplete sessions or not - * @return array of warnings and the sessions - * @since Moodle 3.4 - * @throws moodle_exception - */ - public static function get_sessions($chatid, $groupid = 0, $showall = false) { - global $DB; - - $params = self::validate_parameters(self::get_sessions_parameters(), - array( - 'chatid' => $chatid, - 'groupid' => $groupid, - 'showall' => $showall, - )); - $sessions = $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, 0, 0, 'timestamp DESC'); - if ($messages) { - $chatsessions = chat_get_sessions($messages, $params['showall']); - // Format sessions for external. - foreach ($chatsessions as $session) { - $sessionusers = array(); - foreach ($session->sessionusers as $sessionuser => $usermessagecount) { - $sessionusers[] = array( - 'userid' => $sessionuser, - 'messagecount' => $usermessagecount - ); - } - $session->sessionusers = $sessionusers; - $sessions[] = $session; - } - } - - $result = array(); - $result['sessions'] = $sessions; - $result['warnings'] = $warnings; - return $result; - } - - /** - * Returns description of method result value - * - * @return \core_external\external_description - * @since Moodle 3.4 - */ - public static function get_sessions_returns() { - return new external_single_structure( - array( - 'sessions' => new external_multiple_structure( - new external_single_structure( - array( - 'sessionstart' => new external_value(PARAM_INT, 'Session start time.'), - 'sessionend' => new external_value(PARAM_INT, 'Session end time.'), - 'sessionusers' => new external_multiple_structure( - new external_single_structure( - array( - 'userid' => new external_value(PARAM_INT, 'User id.'), - 'messagecount' => new external_value(PARAM_INT, 'Number of messages in the session.'), - ) - ), 'Session users.' - ), - 'iscomplete' => new external_value(PARAM_BOOL, 'Whether the session is completed or not.'), - ) - ), - 'list of users' - ), - 'warnings' => new external_warnings() - ) - ); - } - - /** - * 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 \core_external\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 deleted file mode 100644 index 1f3cac48b67..00000000000 --- a/mod/chat/classes/external/chat_message_exporter.php +++ /dev/null @@ -1,101 +0,0 @@ -. - -/** - * 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/classes/external/view_sessions.php b/mod/chat/classes/external/view_sessions.php deleted file mode 100644 index 474cc11d60b..00000000000 --- a/mod/chat/classes/external/view_sessions.php +++ /dev/null @@ -1,121 +0,0 @@ -. - -namespace mod_chat\external; - -use core_external\external_api; -use core_external\external_function_parameters; -use core_external\external_single_structure; -use core_external\external_value; -use core_external\external_warnings; - -/** - * External service to log viewed previous chat sessions. - * - * @package mod_chat - * @category external - * @copyright 2023 Rodrigo Mady - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @since Moodle 4.3 - */ -class view_sessions extends external_api { - /** - * Returns description of method parameters - * - * @return external_function_parameters - */ - public static function execute_parameters(): external_function_parameters { - return new external_function_parameters([ - 'cmid' => new external_value(PARAM_INT, 'Course module id', VALUE_REQUIRED), - 'start' => new external_value(PARAM_INT, 'Session start time', VALUE_DEFAULT, 0), - 'end' => new external_value(PARAM_INT, 'Session end time', VALUE_DEFAULT, 0), - ]); - } - - /** - * Execute the chat view sessions event. - * - * @param int $cmid the chat course module id - * @param null|int $start - * @param null|int $end - * @return array - * @throws \restricted_context_exception - */ - public static function execute(int $cmid, ?int $start = 0, ?int $end = 0): array { - global $DB; - $warnings = []; - $status = false; - // Validate the cmid ID. - [ - 'cmid' => $cmid, - 'start' => $start, - 'end' => $end, - ] = self::validate_parameters(self::execute_parameters(), [ - 'cmid' => $cmid, - 'start' => $start, - 'end' => $end, - ]); - if (!$cm = get_coursemodule_from_id('chat', $cmid)) { - throw new \moodle_exception('invalidcoursemodule', 'error'); - } - if (!$chat = $DB->get_record('chat', ['id' => $cm->instance])) { - throw new \moodle_exception('invalidcoursemodule', 'error'); - } - - $context = \context_module::instance($cm->id); - self::validate_context($context); - - // Check capability. - if (has_capability('mod/chat:readlog', $context)) { - $params = [ - 'context' => $context, - 'objectid' => $chat->id, - 'other' => [ - 'start' => $start, - 'end' => $end - ] - ]; - $event = \mod_chat\event\sessions_viewed::create($params); - $status = true; - $event->add_record_snapshot('chat', $chat); - $event->trigger(); - } else { - $warnings[] = [ - 'item' => $cm->id, - 'warningcode' => 'nopermissiontoseethechatlog', - 'message' => get_string('nopermissiontoseethechatlog', 'chat') - ]; - } - - $result = [ - 'status' => $status, - 'warnings' => $warnings - ]; - return $result; - } - - /** - * Describe the return structure of the external service. - * - * @return external_single_structure - */ - public static function execute_returns(): external_single_structure { - return new external_single_structure([ - 'status' => new external_value(PARAM_BOOL, 'status: true if success'), - 'warnings' => new external_warnings() - ]); - } -} diff --git a/mod/chat/classes/privacy/provider.php b/mod/chat/classes/privacy/provider.php deleted file mode 100644 index d6f24a643ff..00000000000 --- a/mod/chat/classes/privacy/provider.php +++ /dev/null @@ -1,333 +0,0 @@ -. - -/** - * Data provider. - * - * @package mod_chat - * @copyright 2018 Frédéric Massart - * @author Frédéric Massart - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace mod_chat\privacy; -defined('MOODLE_INTERNAL') || die(); - -use context; -use context_helper; -use context_module; -use moodle_recordset; -use stdClass; -use core_privacy\local\metadata\collection; -use core_privacy\local\request\approved_contextlist; -use core_privacy\local\request\approved_userlist; -use core_privacy\local\request\contextlist; -use core_privacy\local\request\helper; -use core_privacy\local\request\transform; -use core_privacy\local\request\userlist; -use core_privacy\local\request\writer; - -/** - * Data provider class. - * - * @package mod_chat - * @copyright 2018 Frédéric Massart - * @author Frédéric Massart - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements - \core_privacy\local\metadata\provider, - \core_privacy\local\request\core_userlist_provider, - \core_privacy\local\request\plugin\provider { - - /** - * Returns metadata. - * - * @param collection $collection The initialised collection to add items to. - * @return collection A listing of user data stored through this system. - */ - public static function get_metadata(collection $collection): collection { - - $collection->add_database_table('chat_messages', [ - 'userid' => 'privacy:metadata:messages:userid', - 'message' => 'privacy:metadata:messages:message', - 'issystem' => 'privacy:metadata:messages:issystem', - 'timestamp' => 'privacy:metadata:messages:timestamp', - ], 'privacy:metadata:messages'); - - // The tables chat_messages_current and chat_users are not exported/deleted - // because they are considered as short-lived data and are deleted on a - // regular basis by cron, or during normal requests. TODO MDL-62006. - - $collection->add_database_table('chat_messages_current', [ - 'userid' => 'privacy:metadata:messages:userid', - 'message' => 'privacy:metadata:messages:message', - 'issystem' => 'privacy:metadata:messages:issystem', - 'timestamp' => 'privacy:metadata:messages:timestamp' - ], 'privacy:metadata:chat_messages_current'); - - $collection->add_database_table('chat_users', [ - 'userid' => 'privacy:metadata:chat_users:userid', - 'version' => 'privacy:metadata:chat_users:version', - 'ip' => 'privacy:metadata:chat_users:ip', - 'firstping' => 'privacy:metadata:chat_users:firstping', - 'lastping' => 'privacy:metadata:chat_users:lastping', - 'lastmessageping' => 'privacy:metadata:chat_users:lastmessageping', - 'lang' => 'privacy:metadata:chat_users:lang' - ], 'privacy:metadata:chat_users'); - - return $collection; - } - - /** - * Get the list of contexts that contain user information for the specified user. - * - * @param int $userid The user to search. - * @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin. - */ - public static function get_contexts_for_userid(int $userid): \core_privacy\local\request\contextlist { - $contextlist = new \core_privacy\local\request\contextlist(); - - $sql = " - SELECT DISTINCT ctx.id - FROM {chat} c - JOIN {modules} m - ON m.name = :chat - JOIN {course_modules} cm - ON cm.instance = c.id - AND cm.module = m.id - JOIN {context} ctx - ON ctx.instanceid = cm.id - AND ctx.contextlevel = :modulelevel - JOIN {chat_messages} chm - ON chm.chatid = c.id - WHERE chm.userid = :userid"; - - $params = [ - 'chat' => 'chat', - 'modulelevel' => CONTEXT_MODULE, - 'userid' => $userid, - ]; - $contextlist->add_from_sql($sql, $params); - - return $contextlist; - } - - /** - * Get the list of users who have data within a context. - * - * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination. - */ - public static function get_users_in_context(userlist $userlist) { - $context = $userlist->get_context(); - - if (!is_a($context, \context_module::class)) { - return; - } - - $params = [ - 'instanceid' => $context->instanceid, - 'modulename' => 'chat', - ]; - - $sql = "SELECT chm.userid - FROM {course_modules} cm - JOIN {modules} m ON m.id = cm.module AND m.name = :modulename - JOIN {chat} c ON c.id = cm.instance - JOIN {chat_messages} chm ON chm.chatid = c.id - WHERE cm.id = :instanceid"; - - $userlist->add_from_sql('userid', $sql, $params); - } - - /** - * Export all user data for the specified user, in the specified contexts. - * - * @param approved_contextlist $contextlist The approved contexts to export information for. - */ - public static function export_user_data(approved_contextlist $contextlist) { - global $DB; - - $user = $contextlist->get_user(); - $userid = $user->id; - $cmids = array_reduce($contextlist->get_contexts(), function($carry, $context) { - if ($context->contextlevel == CONTEXT_MODULE) { - $carry[] = $context->instanceid; - } - return $carry; - }, []); - if (empty($cmids)) { - return; - } - - $chatidstocmids = static::get_chat_ids_to_cmids_from_cmids($cmids); - $chatids = array_keys($chatidstocmids); - - // Export the messages. - list($insql, $inparams) = $DB->get_in_or_equal($chatids, SQL_PARAMS_NAMED); - $params = array_merge($inparams, ['userid' => $userid]); - $recordset = $DB->get_recordset_select('chat_messages', "chatid $insql AND userid = :userid", $params, 'timestamp, id'); - static::recordset_loop_and_export($recordset, 'chatid', [], function($carry, $record) use ($user, $chatidstocmids) { - $message = $record->message; - if ($record->issystem) { - $message = get_string('message' . $record->message, 'mod_chat', fullname($user)); - } - $carry[] = [ - 'message' => $message, - 'sent_at' => transform::datetime($record->timestamp), - 'is_system_generated' => transform::yesno($record->issystem), - ]; - return $carry; - - }, function($chatid, $data) use ($user, $chatidstocmids) { - $context = context_module::instance($chatidstocmids[$chatid]); - $contextdata = helper::get_context_data($context, $user); - $finaldata = (object) array_merge((array) $contextdata, ['messages' => $data]); - helper::export_context_files($context, $user); - writer::with_context($context)->export_data([], $finaldata); - }); - } - - /** - * Delete all data for all users in the specified context. - * - * @param context $context The specific context to delete data for. - */ - public static function delete_data_for_all_users_in_context(context $context) { - global $DB; - - if ($context->contextlevel != CONTEXT_MODULE) { - return; - } - - $cm = get_coursemodule_from_id('chat', $context->instanceid); - if (!$cm) { - return; - } - - $chatid = $cm->instance; - $DB->delete_records_select('chat_messages', 'chatid = :chatid', ['chatid' => $chatid]); - $DB->delete_records_select('chat_messages_current', 'chatid = :chatid', ['chatid' => $chatid]); - $DB->delete_records_select('chat_users', 'chatid = :chatid', ['chatid' => $chatid]); - } - - /** - * Delete all user data for the specified user, in the specified contexts. - * - * @param approved_contextlist $contextlist The approved contexts and user information to delete information for. - */ - public static function delete_data_for_user(approved_contextlist $contextlist) { - global $DB; - - $userid = $contextlist->get_user()->id; - $cmids = array_reduce($contextlist->get_contexts(), function($carry, $context) { - if ($context->contextlevel == CONTEXT_MODULE) { - $carry[] = $context->instanceid; - } - return $carry; - }, []); - if (empty($cmids)) { - return; - } - - $chatidstocmids = static::get_chat_ids_to_cmids_from_cmids($cmids); - $chatids = array_keys($chatidstocmids); - - list($insql, $inparams) = $DB->get_in_or_equal($chatids, SQL_PARAMS_NAMED); - $sql = "chatid $insql AND userid = :userid"; - $params = array_merge($inparams, ['userid' => $userid]); - - $DB->delete_records_select('chat_messages', $sql, $params); - $DB->delete_records_select('chat_messages_current', $sql, $params); - $DB->delete_records_select('chat_users', $sql, $params); - } - - - /** - * Delete multiple users within a single context. - * - * @param approved_userlist $userlist The approved context and user information to delete information for. - */ - public static function delete_data_for_users(approved_userlist $userlist) { - global $DB; - - $context = $userlist->get_context(); - $cm = $DB->get_record('course_modules', ['id' => $context->instanceid]); - $chat = $DB->get_record('chat', ['id' => $cm->instance]); - - list($userinsql, $userinparams) = $DB->get_in_or_equal($userlist->get_userids(), SQL_PARAMS_NAMED); - $params = array_merge(['chatid' => $chat->id], $userinparams); - $sql = "chatid = :chatid AND userid {$userinsql}"; - - $DB->delete_records_select('chat_messages', $sql, $params); - $DB->delete_records_select('chat_messages_current', $sql, $params); - $DB->delete_records_select('chat_users', $sql, $params); - } - - /** - * Return a dict of chat IDs mapped to their course module ID. - * - * @param array $cmids The course module IDs. - * @return array In the form of [$chatid => $cmid]. - */ - protected static function get_chat_ids_to_cmids_from_cmids(array $cmids) { - global $DB; - list($insql, $inparams) = $DB->get_in_or_equal($cmids, SQL_PARAMS_NAMED); - $sql = " - SELECT c.id, cm.id AS cmid - FROM {chat} c - JOIN {modules} m - ON m.name = :chat - JOIN {course_modules} cm - ON cm.instance = c.id - AND cm.module = m.id - WHERE cm.id $insql"; - $params = array_merge($inparams, ['chat' => 'chat']); - return $DB->get_records_sql_menu($sql, $params); - } - - /** - * Loop and export from a recordset. - * - * @param moodle_recordset $recordset The recordset. - * @param string $splitkey The record key to determine when to export. - * @param mixed $initial The initial data to reduce from. - * @param callable $reducer The function to return the dataset, receives current dataset, and the current record. - * @param callable $export The function to export the dataset, receives the last value from $splitkey and the dataset. - * @return void - */ - protected static function recordset_loop_and_export(moodle_recordset $recordset, $splitkey, $initial, - callable $reducer, callable $export) { - - $data = $initial; - $lastid = null; - - foreach ($recordset as $record) { - if ($lastid && $record->{$splitkey} != $lastid) { - $export($lastid, $data); - $data = $initial; - } - $data = $reducer($data, $record); - $lastid = $record->{$splitkey}; - } - $recordset->close(); - - if (!empty($lastid)) { - $export($lastid, $data); - } - } - -} diff --git a/mod/chat/classes/search/activity.php b/mod/chat/classes/search/activity.php deleted file mode 100644 index 98bed370926..00000000000 --- a/mod/chat/classes/search/activity.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Search area for mod_chat activities. - * - * @package mod_chat - * @copyright 2015 David Monllao {@link http://www.davidmonllao.com} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace mod_chat\search; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Search area for mod_chat activities. - * - * @package mod_chat - * @copyright 2015 David Monllao {@link http://www.davidmonllao.com} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class activity extends \core_search\base_activity { - - /** - * Returns true if this area uses file indexing. - * - * @return bool - */ - public function uses_file_indexing() { - return true; - } -} diff --git a/mod/chat/classes/task/cron_task.php b/mod/chat/classes/task/cron_task.php deleted file mode 100644 index f933c83dabc..00000000000 --- a/mod/chat/classes/task/cron_task.php +++ /dev/null @@ -1,65 +0,0 @@ -. - -/** - * A scheduled task for chat cron. - * - * @package mod_chat - * @copyright 2019 Simey Lameze - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -namespace mod_chat\task; - -defined('MOODLE_INTERNAL') || die(); - -/** - * The main schedule task for the chat module. - * - * @package mod_chat - * @copyright 2019 Simey Lameze - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class cron_task extends \core\task\scheduled_task { - - /** - * Get a descriptive name for this task (shown to admins). - * - * @return string - */ - public function get_name() { - return get_string('crontask', 'mod_chat'); - } - - /** - * Run chat cron. - */ - public function execute() { - global $CFG, $DB; - require_once($CFG->dirroot . '/mod/chat/lib.php'); - - chat_update_chat_times(); - chat_delete_old_users(); - - $timenow = time(); - $subselect = "SELECT c.keepdays - FROM {chat} c - WHERE c.id = {chat_messages}.chatid"; - $DB->delete_records_select('chat_messages', "($subselect) > 0 AND timestamp < (? - ($subselect) * ?)", - [$timenow, DAYSECS]); - - $DB->delete_records_select('chat_messages_current', "timestamp < ?", [$timenow - 8 * HOURSECS]); - } -} diff --git a/mod/chat/db/access.php b/mod/chat/db/access.php deleted file mode 100644 index 9c4e6801dbd..00000000000 --- a/mod/chat/db/access.php +++ /dev/null @@ -1,114 +0,0 @@ -. - -/** - * Plugin capabilities - * - * @package mod_chat - * @copyright 2006 Martin Dougiamas - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -$capabilities = array( - - 'mod/chat:addinstance' => array( - 'riskbitmask' => RISK_XSS, - - 'captype' => 'write', - 'contextlevel' => CONTEXT_COURSE, - 'archetypes' => array( - 'editingteacher' => CAP_ALLOW, - 'manager' => CAP_ALLOW - ), - 'clonepermissionsfrom' => 'moodle/course:manageactivities' - ), - - 'mod/chat:chat' => array( - - 'riskbitmask' => RISK_SPAM, - - 'captype' => 'write', - 'contextlevel' => CONTEXT_MODULE, - 'archetypes' => array( - 'student' => CAP_ALLOW, - 'teacher' => CAP_ALLOW, - 'editingteacher' => CAP_ALLOW, - 'manager' => CAP_ALLOW - ) - ), - - 'mod/chat:readlog' => array( - - 'captype' => 'read', - 'contextlevel' => CONTEXT_MODULE, - 'archetypes' => array( - 'student' => CAP_ALLOW, - 'teacher' => CAP_ALLOW, - 'editingteacher' => CAP_ALLOW, - 'manager' => CAP_ALLOW - ) - ), - - 'mod/chat:deletelog' => array( - - 'captype' => 'write', - 'contextlevel' => CONTEXT_MODULE, - 'archetypes' => array( - 'teacher' => CAP_ALLOW, - 'editingteacher' => CAP_ALLOW, - 'manager' => CAP_ALLOW - ) - ), - - 'mod/chat:exportparticipatedsession' => array( - - 'riskbitmask' => RISK_PERSONAL, - - 'captype' => 'read', - 'contextlevel' => CONTEXT_MODULE, - 'archetypes' => array( - 'teacher' => CAP_ALLOW, - 'editingteacher' => CAP_ALLOW, - 'manager' => CAP_ALLOW, - // Not student - nervous about allowing this by default. - ), - - ), - - 'mod/chat:exportsession' => array( - - 'riskbitmask' => RISK_PERSONAL, - - 'captype' => 'read', - 'contextlevel' => CONTEXT_MODULE, - 'archetypes' => array( - 'teacher' => CAP_ALLOW, - 'editingteacher' => CAP_ALLOW, - 'manager' => CAP_ALLOW, - ), - ), - - 'mod/chat:view' => array( - 'captype' => 'read', - 'contextlevel' => CONTEXT_MODULE, - 'archetypes' => array( - 'user' => CAP_ALLOW, - 'guest' => CAP_ALLOW - ) - ) -); diff --git a/mod/chat/db/events.php b/mod/chat/db/events.php deleted file mode 100644 index 85b9d9bc69c..00000000000 --- a/mod/chat/db/events.php +++ /dev/null @@ -1,34 +0,0 @@ -. - -/** - * Event observers definition. - * - * @package mod_chat - * @category event - * @copyright 2010 Dongsheng Cai - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$observers = array( - - // User logging out. - array( - 'eventname' => '\core\event\user_loggedout', - 'callback' => 'chat_user_logout', - 'includefile' => '/mod/chat/lib.php' - ) -); diff --git a/mod/chat/db/install.php b/mod/chat/db/install.php deleted file mode 100644 index a05ae06e445..00000000000 --- a/mod/chat/db/install.php +++ /dev/null @@ -1,33 +0,0 @@ -. - -/** - * Chat module installation. - * - * @package mod_chat - * @copyright 2024 Sara Arjona - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -/** - * Perform the post-install procedures. - */ -function xmldb_chat_install() { - global $DB; - - // Disable the chat activity module on new installs by default. - $DB->set_field('modules', 'visible', 0, ['name' => 'chat']); -} diff --git a/mod/chat/db/install.xml b/mod/chat/db/install.xml deleted file mode 100644 index dfc44d0257a..00000000000 --- a/mod/chat/db/install.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
diff --git a/mod/chat/db/log.php b/mod/chat/db/log.php deleted file mode 100644 index 5cde13bf2e8..00000000000 --- a/mod/chat/db/log.php +++ /dev/null @@ -1,34 +0,0 @@ -. - -/** - * Definition of log events - * - * @package mod_chat - * @category log - * @copyright 2010 Petr Skoda (http://skodak.org) - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -$logs = array( - array('module' => 'chat', 'action' => 'view', 'mtable' => 'chat', 'field' => 'name'), - array('module' => 'chat', 'action' => 'add', 'mtable' => 'chat', 'field' => 'name'), - array('module' => 'chat', 'action' => 'update', 'mtable' => 'chat', 'field' => 'name'), - array('module' => 'chat', 'action' => 'report', 'mtable' => 'chat', 'field' => 'name'), - array('module' => 'chat', 'action' => 'talk', 'mtable' => 'chat', 'field' => 'name'), -); diff --git a/mod/chat/db/services.php b/mod/chat/db/services.php deleted file mode 100644 index 6cc8a0ffe3e..00000000000 --- a/mod/chat/db/services.php +++ /dev/null @@ -1,108 +0,0 @@ -. - -/** - * Chat external functions and service definitions. - * - * @package mod_chat - * @category external - * @copyright 2015 Juan Leyva - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @since Moodle 3.0 - */ - -defined('MOODLE_INTERNAL') || die; - -$functions = array( - - 'mod_chat_login_user' => array( - 'classname' => 'mod_chat_external', - 'methodname' => 'login_user', - 'description' => 'Log a user into a chat room in the given chat.', - 'type' => 'write', - 'capabilities' => 'mod/chat:chat', - 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) - ), - - 'mod_chat_get_chat_users' => array( - 'classname' => 'mod_chat_external', - 'methodname' => 'get_chat_users', - 'description' => 'Get the list of users in the given chat session.', - 'type' => 'read', - 'capabilities' => 'mod/chat:chat', - 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) - ), - - 'mod_chat_send_chat_message' => array( - 'classname' => 'mod_chat_external', - 'methodname' => 'send_chat_message', - 'description' => 'Send a message on the given chat session.', - 'type' => 'write', - 'capabilities' => 'mod/chat:chat', - 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) - ), - - 'mod_chat_get_chat_latest_messages' => array( - 'classname' => 'mod_chat_external', - 'methodname' => 'get_chat_latest_messages', - 'description' => 'Get the latest messages from the given chat session.', - 'type' => 'read', - 'capabilities' => 'mod/chat:chat', - 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) - ), - - 'mod_chat_view_chat' => array( - 'classname' => 'mod_chat_external', - 'methodname' => 'view_chat', - 'description' => 'Trigger the course module viewed event and update the module completion status.', - 'type' => 'write', - 'capabilities' => 'mod/chat:chat', - 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) - ), - - 'mod_chat_get_chats_by_courses' => array( - 'classname' => 'mod_chat_external', - 'methodname' => 'get_chats_by_courses', - 'description' => 'Returns a list of chat instances in a provided set of courses, - if no courses are provided then all the chat instances the user has access to will be returned.', - 'type' => 'read', - 'capabilities' => '', - 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) - ), - 'mod_chat_get_sessions' => array( - 'classname' => 'mod_chat_external', - 'methodname' => 'get_sessions', - '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) - ), - - 'mod_chat_view_sessions' => [ - 'classname' => 'mod_chat\external\view_sessions', - 'methodname' => 'execute', - 'description' => 'Trigger the chat session viewed event.', - 'type' => 'write', - 'capabilities' => 'mod/chat:readlog', - 'services' => [MOODLE_OFFICIAL_MOBILE_SERVICE] - ], -); diff --git a/mod/chat/db/tasks.php b/mod/chat/db/tasks.php deleted file mode 100644 index a49ca7ebc25..00000000000 --- a/mod/chat/db/tasks.php +++ /dev/null @@ -1,36 +0,0 @@ -. - -/** - * Definition of chat scheduled tasks. - * - * @package mod_chat - * @copyright 2019 Simey Lameze - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); -$tasks = array( - array( - 'classname' => '\mod_chat\task\cron_task', - 'blocking' => 0, - 'minute' => '*/5', - 'hour' => '*', - 'day' => '*', - 'month' => '*', - 'dayofweek' => '*' - ) -); diff --git a/mod/chat/db/upgrade.php b/mod/chat/db/upgrade.php deleted file mode 100644 index c17577f43b1..00000000000 --- a/mod/chat/db/upgrade.php +++ /dev/null @@ -1,39 +0,0 @@ -. - -/** - * Upgrade code for the chat activity - * - * @package mod_chat - * @copyright 2006 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -function xmldb_chat_upgrade($oldversion) { - // Automatically generated Moodle v4.2.0 release upgrade line. - // Put any upgrade step following this. - - // Automatically generated Moodle v4.3.0 release upgrade line. - // Put any upgrade step following this. - - // Automatically generated Moodle v4.4.0 release upgrade line. - // Put any upgrade step following this. - - // Automatically generated Moodle v4.5.0 release upgrade line. - // Put any upgrade step following this. - - return true; -} diff --git a/mod/chat/empty.php b/mod/chat/empty.php deleted file mode 100644 index c06c35e0d51..00000000000 --- a/mod/chat/empty.php +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/mod/chat/gui_ajax/index.php b/mod/chat/gui_ajax/index.php deleted file mode 100644 index 42d5cd18c3c..00000000000 --- a/mod/chat/gui_ajax/index.php +++ /dev/null @@ -1,114 +0,0 @@ -. - -require_once('../../../config.php'); -require_once('../lib.php'); - -$id = required_param('id', PARAM_INT); -$groupid = optional_param('groupid', 0, PARAM_INT); // Only for teachers. -$theme = optional_param('chat_theme', 'course_theme', PARAM_SAFEDIR); // The value course_theme == the current theme. - -$url = new moodle_url('/mod/chat/gui_ajax/index.php', array('id' => $id)); -if ($groupid !== 0) { - $url->param('groupid', $groupid); -} -$PAGE->set_url($url); -$PAGE->set_popup_notification_allowed(false); // No popup notifications in the chat window. -$PAGE->requires->strings_for_js(array('coursetheme', 'bubble', 'compact'), 'mod_chat'); - -$chat = $DB->get_record('chat', array('id' => $id), '*', MUST_EXIST); -$course = $DB->get_record('course', array('id' => $chat->course), '*', MUST_EXIST); -$cm = get_coursemodule_from_instance('chat', $chat->id, $course->id, false, MUST_EXIST); - -$context = context_module::instance($cm->id); -require_login($course, false, $cm); -require_capability('mod/chat:chat', $context); - -// Check to see if groups are being used here. -if ($groupmode = groups_get_activity_groupmode($cm)) { // Groups are being used. - if ($groupid = groups_get_activity_group($cm)) { - if (!$group = groups_get_group($groupid)) { - throw new \moodle_exception('invalidgroupid'); - } - $groupname = ': '.$group->name; - } else { - $groupname = ': '.get_string('allparticipants'); - } -} else { - $groupid = 0; - $groupname = ''; -} -// If requested theme doesn't exist, use default 'bubble' theme. -if ($theme != 'course_theme' and !file_exists(__DIR__ . '/theme/'.$theme.'/chat.css')) { - $theme = 'compact'; -} - -// Log into the chat room. -if (!$chatsid = chat_login_user($chat->id, 'ajax', $groupid, $course)) { - throw new \moodle_exception('cantlogin', 'chat'); -} -$courseshortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id))); -$module = array( - 'name' => 'mod_chat_ajax', // Chat gui's are not real plugins, we have to break the naming standards for JS modules here. - 'fullpath' => '/mod/chat/gui_ajax/module.js', - 'requires' => array('base', 'dom', 'event', 'event-mouseenter', 'event-key', 'json-parse', 'io', 'overlay', 'yui2-resize', - 'yui2-layout', 'yui2-menu'), - 'strings' => array(array('send', 'chat'), array('sending', 'chat'), array('inputarea', 'chat'), array('userlist', 'chat'), - array('modulename', 'chat'), array('beep', 'chat'), array('talk', 'chat')) -); -$modulecfg = array( - 'home' => $CFG->wwwroot.'/mod/chat/view.php?id='.$cm->id, - 'chaturl' => $CFG->wwwroot.'/mod/chat/gui_ajax/index.php?id='.$id, - 'theme' => $theme, - 'userid' => $USER->id, - 'sid' => $chatsid, - 'timer' => 3000, - 'chat_lasttime' => 0, - 'chat_lastrow' => null, - 'chatroom_name' => $courseshortname . ": " . format_string($chat->name, true) . $groupname -); -$PAGE->requires->js_init_call('M.mod_chat_ajax.init', array($modulecfg), false, $module); - -$PAGE->set_title(get_string('modulename', 'chat').": $courseshortname: ".format_string($chat->name, true)."$groupname"); -$PAGE->add_body_class('yui-skin-sam'); -$PAGE->activityheader->disable(); -$PAGE->set_pagelayout('embedded'); -if ( $theme != 'course_theme') { - $PAGE->requires->css('/mod/chat/gui_ajax/theme/'.$theme.'/chat.css'); -} - -echo $OUTPUT->header(); -echo $OUTPUT->box(html_writer::tag('h2', get_string('participants'), array('class' => 'accesshide')) . - '
    ', '', 'chat-userlist'); -echo $OUTPUT->box('', '', 'chat-options'); -echo $OUTPUT->box(html_writer::tag('h2', get_string('messages', 'chat'), array('class' => 'accesshide')) . - '
      ', '', 'chat-messages'); -$table = new html_table(); -$table->data = [[ - '
      '. - ''. - '' .$OUTPUT->help_icon('usingchat', 'chat'). '
      ' . - '
      ', -]]; -echo $OUTPUT->box(html_writer::tag('h2', get_string('composemessage', 'chat'), array('class' => 'accesshide')) . - html_writer::table($table), '', 'chat-input-area'); -echo $OUTPUT->box('', '', 'chat-notify'); -echo $OUTPUT->footer(); diff --git a/mod/chat/gui_ajax/module.js b/mod/chat/gui_ajax/module.js deleted file mode 100644 index 231392f4a15..00000000000 --- a/mod/chat/gui_ajax/module.js +++ /dev/null @@ -1,265 +0,0 @@ -/* - * NOTE: the /mod/chat/gui_header_js/ is not a real plugin, - * ideally this code should be in /mod/chat/module.js - */ - -/** - * @namespace M.mod_chat_ajax - */ -M.mod_chat_ajax = M.mod_chat_ajax || {}; - -/** - * Init ajax based Chat UI. - * @namespace M.mod_chat_ajax - * @function - * @param {YUI} Y - * @param {Object} cfg configuration data - */ -M.mod_chat_ajax.init = function(Y, cfg) { - - var gui_ajax = { - - // Properties. - api : M.cfg.wwwroot + '/mod/chat/chat_ajax.php?sesskey=' + M.cfg.sesskey, // The path to the ajax callback script. - cfg : {}, // A configuration variable. - interval : null, // The interval object for refreshes. - layout : null, // A reference to the layout used in this module. - messages : [], // An array of messages. - scrollable : true, // True is scrolling should occur. - thememenu : null, // A reference to the menu for changing themes. - - // Elements - messageinput : null, - sendbutton : null, - messagebox : null, - - init : function(cfg) { - this.cfg = cfg; - this.cfg.req_count = this.cfg.req_count || 0; - participantswidth = 180; - if (Y.one('#input-message').get('docWidth') < 640) { - participantswidth = 120; - } - this.layout = new Y.YUI2.widget.Layout({ - units : [ - {position: 'right', width: participantswidth, resize: true, gutter: '1px', scroll: true, body: 'chat-userlist', animate: false}, - {position: 'bottom', height: 42, resize: false, body: 'chat-input-area', gutter: '1px', collapse: false, resize: false}, - {position: 'center', body: 'chat-messages', gutter: '0px', scroll: true} - ] - }); - - this.layout.on('render', function() { - var unit = this.getUnitByPosition('right'); - if (unit) { - unit.on('close', function() { - closeLeft(); - }); - } - }, this.layout); - this.layout.render(); - - // Gather the general elements. - this.messageinput = Y.one('#input-message'); - this.sendbutton = Y.one('#button-send'); - this.messagebox = Y.one('#chat-messages'); - - // Set aria attributes to messagebox and chat-userlist. - this.messagebox.set('role', 'log'); - this.messagebox.set('aria-live', 'polite'); - var userlist = Y.one('#chat-userlist'); - userlist.set('aria-live', 'polite'); - userlist.set('aria-relevant', 'all'); - - // Attach the default events for this module. - this.sendbutton.on('click', this.send, this); - this.messagebox.on('mouseenter', function() { - this.scrollable = false; - }, this); - this.messagebox.on('mouseleave', function() { - this.scrollable = true; - }, this); - - // Send the message when the enter key is pressed. - Y.on('key', this.send, this.messageinput, 'press:13', this); - - document.title = this.cfg.chatroom_name; - - // Prepare and execute the first AJAX request of information. - Y.io(this.api,{ - method : 'POST', - data : build_querystring({ - action : 'init', - chat_init : 1, - chat_sid : this.cfg.sid, - chat_theme : this.cfg.theme - }), - on : { - success : function(tid, outcome) { - this.messageinput.removeAttribute('disabled'); - this.messageinput.set('value', ''); - this.messageinput.focus(); - try { - var data = Y.JSON.parse(outcome.responseText); - } catch (ex) { - return; - } - this.update_users(data.users); - } - }, - context : this - }); - - var scope = this; - this.interval = setInterval(function() { - scope.update_messages(); - }, this.cfg.timer, this); - - // Create and initalise theme changing menu. - this.thememenu = new Y.YUI2.widget.Menu('basicmenu', {xy:[0,0]}); - this.thememenu.addItems([ - {text: M.util.get_string('bubble', 'mod_chat'), url: this.cfg.chaturl + '&chat_theme=bubble'}, - {text: M.util.get_string('compact', 'mod_chat'), url: this.cfg.chaturl + '&chat_theme=compact'}, - {text: M.util.get_string('coursetheme', 'mod_chat'), url: this.cfg.chaturl + '&chat_theme=course_theme'} - ]); - this.thememenu.render(document.body); - Y.one('#choosetheme').on('click', function(e) { - this.moveTo((e.pageX - 20), (e.pageY - 20)); - this.show(); - }, this.thememenu); - - // Set the data-placement for the help-icon to display all the content. - this.helpicon = Y.one('#button-send + a'); - this.dataset = this.helpicon.get('dataset'); - this.dataset.placement = 'top'; - this.helpicon.set('dataset', this.dataset); - }, - - append_message : function(key, message, row) { - var item = Y.Node.create('
    • ' + message.message + '
    • '); - item.addClass((message.mymessage) ? 'mdl-chat-my-entry' : 'mdl-chat-entry'); - Y.one('#messages-list').append(item); - if (message.type && message.type == 'beep') { - var audioElement = document.createElement('audio'); - audioElement.setAttribute('src', '../beep.mp3'); - audioElement.play(); - } - }, - - send : function(e, beep) { - if((this.messageinput.get('value') != '') || (typeof beep != 'undefined')) { - this.sendbutton.set('value', M.util.get_string('sending', 'chat')); - var data = { - chat_message : (!beep) ? this.messageinput.get('value') : '', - chat_sid : this.cfg.sid, - chat_theme : this.cfg.theme - }; - if (beep) { - data.beep = beep - } - data.action = 'chat'; - - Y.io(this.api, { - method : 'POST', - data : build_querystring(data), - on : { - success : this.send_callback - }, - context : this - }); - } - }, - - send_callback : function(tid, outcome, args) { - try { - var data = Y.JSON.parse(outcome.responseText); - } catch (ex) { - return; - } - this.sendbutton.set('value', M.util.get_string('send', 'chat')); - this.messageinput.set('value', ''); - clearInterval(this.interval); - this.update_messages(); - var scope = this; - this.interval = setInterval(function() { - scope.update_messages(); - }, this.cfg.timer, this); - }, - - talkto: function (e, name) { - this.messageinput.set('value', "To " + name + ": "); - this.messageinput.focus(); - }, - - update_messages : function() { - this.cfg.req_count++; - Y.io(this.api, { - method : 'POST', - data : build_querystring({ - action: 'update', - chat_lastrow : this.cfg.chat_lastrow || false, - chat_lasttime : this.cfg.chat_lasttime, - chat_sid : this.cfg.sid, - chat_theme : this.cfg.theme - }), - on : { - success : this.update_messages_callback - }, - context : this - }); - }, - - update_messages_callback : function(tid, outcome) { - try { - var data = Y.JSON.parse(outcome.responseText); - } catch (ex) { - return; - } - if (data.error) { - clearInterval(this.interval); - alert(data.error); - window.location = this.cfg.home; - } - this.cfg.chat_lasttime = data.lasttime; - this.cfg.chat_lastrow = data.lastrow; - // Update messages. - for (var key in data.msgs){ - if (!M.util.in_array(key, this.messages)) { - this.messages.push(key); - this.append_message(key, data.msgs[key], data.lastrow); - } - } - // Update users. - this.update_users(data.users); - // Scroll to the bottom of the message list - if (this.scrollable) { - Y.Node.getDOMNode(this.messagebox).parentNode.scrollTop += 500; - } - this.messageinput.focus(); - }, - - update_users : function(users) { - if (!users) { - return; - } - var list = Y.one('#users-list'); - list.get('children').remove(); - for (var i in users) { - var li = Y.Node.create('
    • ' + users[i].picture + '
    • '); - if (users[i].id == this.cfg.userid) { - li.all('td').item(1).append(Y.Node.create('' + users[i].name + '')); - } else { - li.all('td').item(1).append(Y.Node.create('')); - var talk = Y.Node.create('' + M.util.get_string('talk', 'chat') + ''); - talk.on('click', this.talkto, this, users[i].name); - var beep = Y.Node.create('' + M.util.get_string('beep', 'chat') + ''); - beep.on('click', this.send, this, users[i].id); - li.all('td').item(1).append(Y.Node.create('
      ').append(talk).append(' ').append(beep)); - } - list.append(li); - } - } - - }; - - gui_ajax.init(cfg); -}; diff --git a/mod/chat/gui_ajax/theme/bubble/bubbles.png b/mod/chat/gui_ajax/theme/bubble/bubbles.png deleted file mode 100644 index 208dcfd86c70238ce3fe3a53eb9f79fccb87033a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1612 zcmV-S2DABzP)FM9!-~0Rf{r&y%@$vZh_`~UJ^z`)Z z?(XdD?DzNgyW(Tyd)tw$L4|KkrA$?xy)($dn)@Oa3`$k^D}^YioV?d_}3R^9)Q;o;%T%*>9kLEhfp z&+>oZ;NZ>8&E4t3!otFvuWs4d*`29@$=;XW{*=zxL+Wd~gU(b2l$W7E^q zs=0%epM9LXQK!pU=Kq}8{EMT;QQ-8Qz1M!MwUnBybHL$t;r*fX^z+#JiKe%K%6v31PpiPQFi#_4se%w@CJV7<|e&D6Z6$yTV$RI}M&(ej1b`jXuH zl+NXr%Uq}rh?Syt zmY{vR;#`-haFw@6;QXGJxk%0NeU6cb$K;2m!Dgw%ZQJgd)7Z$@+{@wnrsDjiuE=xI zfujkjv$ceSLkPyJF<{p#T5>4hNvi0009ANkl*~u+C?(Dl7&$dz9n$^y>ZFKJ3*|xpBxcbKVee}m7Vz%-cvAw7$ zULYkHvnyCo>{pY|V0LkQ-TW#jwp$5CpxB;0w-%Nbc;y5Gve}CSvukEis@NmrXo|#Q z+f4Puf0dUPRI`FuD#^oFM{2g;y;noQsmm`Y%sa~0nrvHtz8R(%$jj`t9Tgb4sx{j3 zK~_I~&+l~zv~0b{n^G>FqkLn2706bwE-HbSx@ZQPxzbvd!qz&eM5DzeG?=#3km7*Z znqp8WJep8Q%fpvex>2^8e?WBVAciS;9vqAjOvN?i>>;R9spFi)LJkR2LmKKXCqXPk zskUVjRFy9Ui1`4S*Dt54)Ee++#{6z$NnrrxDqiJAm^D%|(7nB>HQuF4Ie}GX7H;HM zp9e)_dEx?bUaSKk7S`GL3P5P{y*o3~)6+9*Cz??Rm|X#xIU!@ycu#e8bmL7c-zx?=z*O|a2L}!uym`avtPROy2fsLhvNd|!M`PE8CoL9BnuRhM4u^;8qYzUa zJFoq0@#5Vklj&^}Wp_)<;^A5c0?;*n{NwA7_vuNG>KT2-3u-x4F>(DZM;^N1G|uR*T{r#o^JVvU zE2*7>2DV(d>d=Y^>+s><*8g&z@Wp>_B{Q%{u6BPiaO3(f6FJ+rKk<@q&z`sLyXJfu zxkd`(^38wcjGRGReaFM^KGNR)&Z}=E{5|nJwZ015#ZPa(f=&S|pjJNziNde|0000< KMNUMnLSTY;B+Zln diff --git a/mod/chat/gui_ajax/theme/bubble/chat.css b/mod/chat/gui_ajax/theme/bubble/chat.css deleted file mode 100644 index 0c4a55f7c0e..00000000000 --- a/mod/chat/gui_ajax/theme/bubble/chat.css +++ /dev/null @@ -1,249 +0,0 @@ -.yui-skin-sam .yui-layout .yui-layout-hd { - border: 0; -} - -.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd-nohd { - border: 0; -} - -.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd { - border: 0; -} - -.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-unit-right { - background: white; -} - -.yui-skin-sam .yui-layout-unit-bottom { - background: #f2f2f2; -} - -.yui-skin-sam .yui-layout-unit-right { - background: #eef2f8; -} - -.yui-skin-sam .yui-layout-unit-center { - background: white; -} - -.yui-skin-sam .yui-layout-unit-top { - background: #ffe39d; -} - -.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd { - background: transparent; -} - -#chat-messages { - padding-top: 15px; -} - -#input-message { - background: #fff url(input.png) repeat-x scroll 0 0; - padding: 0 9px; - border: 1px solid #999; - border-radius: 9px; - -moz-border-radius: 9px; -} - -.mdl-chat-entry, -.mdl-chat-my-entry { - clear: both; -} - -.mdl-chat-entry .chat-event { - padding-bottom: 15px; -} - -.chat-message .chat-message-meta { - padding-top: 15px; - padding-bottom: 15px; -} - -.chat-message .chat-message-meta .user { - white-space: nowrap; -} - -.chat-message .picture { - vertical-align: middle; -} - -.chat-message .right { - text-align: right; -} - -.chat-message .left { - text-align: left; -} -/*rtl:ignore*/ -.chat-message .right, -.chat-message .left { - direction: ltr; -} - -#chat-input-area, -#chat-input-area table.generaltable, -#chat-input-area table.generaltable td.cell { - background: #92b3e8; - border: 0; - height: 100%; -} - -#chat-userlist { - background: #e3e8f0; - height: 100%; -} - -/** - * The following CSS is a cut down version of PURE CSS SPEECH BUBBLES. - * Moodle only uses a small subset of the original. - * The original version is available at http://nicolasgallagher.com/pure-css-speech-bubbles/ - */ - -/* ------------------------------------------ -PURE CSS SPEECH BUBBLES -by Nicolas Gallagher -- http://nicolasgallagher.com/pure-css-speech-bubbles/ - -http://nicolasgallagher.com -http://twitter.com/necolas - -Created: 02 March 2010 -Version: 1.2 (03 March 2011) - -Dual licensed under MIT and GNU GPLv2 © Nicolas Gallagher ------------------------------------------- */ - -.triangle-border { - position: relative; - padding: 10px; - margin: 1em 0 3em; - border: 2px solid #5a8f00; - color: #333; - background: #fff; - /* css3 */ - -webkit-border-radius: 10px; - -moz-border-radius: 10px; - border-radius: 10px; - - /* moodle specific */ - margin-top: 0; - /* end moodle specific */ -} - -/* moodle specific */ - -@media all and (max-device-width: 320px) { - .triangle-border { - width: 50%; - } -} - -@media all and (min-device-width: 321px) and (max-device-width: 640px) { - .triangle-border { - width: 60%; - } -} - -@media all and (min-device-width: 641px) { - .triangle-border { - width: 65%; - } -} -/* end moodle specific */ - -/* Variant : for left positioned triangle ------------------------------------------- */ - -.triangle-border.left { - margin-left: 30px; - /* moodle specific */ - float: right; - /* end moodle specific */ -} - -/* Variant : for right positioned triangle ------------------------------------------- */ - -.triangle-border.right { - margin-right: 30px; - /* moodle specific */ - float: left; - /* end moodle specific */ -} - -.triangle-border:before { - content: ""; - position: absolute; - bottom: -20px; /* value = - border-top-width - border-bottom-width */ - left: 40px; /* controls horizontal position */ - border-width: 20px 20px 0; - border-style: solid; - border-color: #5a8f00 transparent; - /* reduce the damage in FF3.0 */ - display: block; - width: 0; -} - -/* creates the smaller triangle */ -.triangle-border:after { - content: ""; - position: absolute; - bottom: -13px; /* value = - border-top-width - border-bottom-width */ - left: 47px; /* value = (:before left) + (:before border-left) - (:after border-left) */ - border-width: 13px 13px 0; - border-style: solid; - border-color: #fff transparent; - /* reduce the damage in FF3.0 */ - display: block; - width: 0; -} - -/* Variant : left ------------------------------------------- */ - -/* creates the larger triangle */ -.triangle-border.left:before { - top: 7px; /* controls vertical position */ - bottom: auto; - left: -24px; /* value = - border-left-width - border-right-width */ - border-width: 10px 24px 10px 0; - border-color: transparent #5a8f00; -} - -/* creates the smaller triangle */ -.triangle-border.left:after { - top: 8px; /* value = (:before top) + (:before border-top) - (:after border-top) */ - bottom: auto; - left: -21px; /* value = - border-left-width - border-right-width */ - border-width: 9px 21px 9px 0; - border-color: transparent #fff; -} - -/* Variant : right ------------------------------------------- */ - -/* creates the larger triangle */ -.triangle-border.right:before { - top: 7px; /* controls vertical position */ - bottom: auto; - left: auto; - right: -24px; /* value = - border-left-width - border-right-width */ - border-width: 10px 0 10px 24px; - border-color: transparent #5a8f00; -} - -/* creates the smaller triangle */ -.triangle-border.right:after { - top: 8px; /* value = (:before top) + (:before border-top) - (:after border-top) */ - bottom: auto; - left: auto; - right: -21px; /* value = - border-left-width - border-right-width */ - border-width: 9px 0 9px 21px; - border-color: transparent #fff; -} - -#button-send + a > i.text-info { - /* stylelint-disable-next-line declaration-no-important */ - color: black !important; -} diff --git a/mod/chat/gui_ajax/theme/bubble/config.php b/mod/chat/gui_ajax/theme/bubble/config.php deleted file mode 100644 index b1eb941e1e6..00000000000 --- a/mod/chat/gui_ajax/theme/bubble/config.php +++ /dev/null @@ -1,50 +0,0 @@ -. - -$chattheme_cfg = new stdClass(); -$chattheme_cfg->avatar = true; -$chattheme_cfg->align = true; -$chattheme_cfg->event_message = <<