From 1d5071868fe385f9a27582ddd0a4c6c8bf8ededd Mon Sep 17 00:00:00 2001
From: dongsheng
Date: Tue, 18 Nov 2008 05:21:57 +0000
Subject: [PATCH] MDL-14651 1. identify IRC commands 2. commiting ajax chat
room, I lost my half finished source code, so I have to start again :-(
---
lang/en_utf8/message.php | 1 +
mod/chat/gui_ajax/common.php | 41 +++++++++
mod/chat/gui_ajax/index.php | 100 +++++++++++++++++++++
mod/chat/gui_ajax/post.php | 52 +++++++++++
mod/chat/gui_ajax/script.js | 137 ++++++++++++++++++++++++++++
mod/chat/gui_ajax/update.php | 169 +++++++++++++++++++++++++++++++++++
mod/chat/lib.php | 33 ++++++-
mod/chat/view.php | 7 ++
8 files changed, 537 insertions(+), 3 deletions(-)
create mode 100755 mod/chat/gui_ajax/common.php
create mode 100644 mod/chat/gui_ajax/index.php
create mode 100755 mod/chat/gui_ajax/post.php
create mode 100644 mod/chat/gui_ajax/script.js
create mode 100755 mod/chat/gui_ajax/update.php
diff --git a/lang/en_utf8/message.php b/lang/en_utf8/message.php
index ce5b35b100..ac53bc719b 100644
--- a/lang/en_utf8/message.php
+++ b/lang/en_utf8/message.php
@@ -5,6 +5,7 @@
$string['addcontact'] = 'Add contact';
$string['addsomecontacts'] = 'To send a message to someone, or to add a shortcut for them on this page, use the search tab above.';
$string['addsomecontactsincoming'] = 'These messages are from people who are not in your contact list. To add them to your contacts, click the \"Add contact\" icon next to their name.';
+$string['ajax_gui'] = 'Ajax chat room';
$string['ago'] = '$a ago';
$string['allmine'] = 'All messages to me or from me';
$string['allstudents'] = 'All messages between students in course';
diff --git a/mod/chat/gui_ajax/common.php b/mod/chat/gui_ajax/common.php
new file mode 100755
index 0000000000..e0f50c9125
--- /dev/null
+++ b/mod/chat/gui_ajax/common.php
@@ -0,0 +1,41 @@
+dir = $dir.'/chat_cache';
+ if(!is_dir($this->dir)) {
+ // create cache folder
+ if(mkdir($this->dir, 777)) {
+ $this->write('test', 'Deny from all');
+ }
+ }
+ }
+ private function write($name, $content){
+ $name = $this->dir.'/'.$name.'.data';
+ if (file_exists($name)) {
+ unlink($name);
+ }
+
+ $fp = fopen($name, 'w');
+ if($fp) {
+ fputs($fp, $content);
+ fclose($fp);
+ }
+ }
+ public function get($name){
+ $content = '';
+ $fp = fopen($this->dir.'/'.$name.'.data', 'r');
+ if ($fp){
+ while(!feof($fp))
+ $content .= fread($fp, 4096);
+ fclose($fp);
+ return unserialize($content);
+ } else {
+ return false;
+ }
+ }
+ public function set($name, $content){
+ $this->write($name, serialize($content));
+ }
+}
+?>
diff --git a/mod/chat/gui_ajax/index.php b/mod/chat/gui_ajax/index.php
new file mode 100644
index 0000000000..cd9d6536e8
--- /dev/null
+++ b/mod/chat/gui_ajax/index.php
@@ -0,0 +1,100 @@
+
+get_record('chat', array('id'=>$id))) {
+ print_error('invalidid', 'chat');
+}
+
+if (!$course = $DB->get_record('course', array('id'=>$chat->course))) {
+ print_error('invalidcourseid');
+}
+
+if (!$cm = get_coursemodule_from_instance('chat', $chat->id, $course->id)) {
+ print_error('invalidcoursemodule');
+}
+
+$context = get_context_instance(CONTEXT_MODULE, $cm->id);
+require_login($course->id, false, $cm);
+require_capability('mod/chat:chat',$context);
+
+if (!$cm->visible and !has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_MODULE, $cm->id))) {
+ print_header();
+ notice(get_string("activityiscurrentlyhidden"));
+}
+
+/// 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, false)) {
+ print_error('invalidgroupid');
+ }
+ $groupname = ': '.$group->name;
+ } else {
+ $groupname = ': '.get_string('allparticipants');
+ }
+} else {
+ $groupid = 0;
+ $groupname = '';
+}
+
+$strchat = get_string('modulename', 'chat'); // must be before current_language() in chat_login_user() to force course language!!!
+$str_send = get_string('send', 'chat');
+$str_sending = get_string('sending', 'chat');
+if (!$chat_sid = chat_login_user($chat->id, 'ajax', $groupid, $course)) {
+ print_error('cantlogin', 'chat');
+}
+?>
+
+
+
+
+
+
+
+
+
+$chat_sid,'timer'=>5000, 'chat_lasttime'=>0,'chat_lastrow'=>null), 'chat_cfg');
+print_js_config(array('send'=>$str_send, 'sending'=>$str_sending), 'chat_lang');
+?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mod/chat/gui_ajax/post.php b/mod/chat/gui_ajax/post.php
new file mode 100755
index 0000000000..6c0015a74f
--- /dev/null
+++ b/mod/chat/gui_ajax/post.php
@@ -0,0 +1,52 @@
+get_record('chat_users', array('sid'=>$chat_sid))) {
+ echo 'invalid sid';
+}
+if (!$chat = $DB->get_record('chat', array('id'=>$chatuser->chatid))) {
+ echo 'invalid chat id';
+}
+if (!$course = $DB->get_record('course', array('id'=>$chat->course))) {
+ echo 'invalid course id';
+}
+if (!$cm = get_coursemodule_from_instance('chat', $chat->id, $course->id)) {
+ echo 'invalid course module';
+}
+if (isguest()) {
+ echo 'Guest does not have access to chat rooms';
+}
+session_write_close();
+chat_delete_old_users();
+$chat_message = clean_text($chat_message, FORMAT_MOODLE);
+
+//TODO: Before insert the chat message into database, we should push the
+//message into a global object (which can hold 100 messages), when user request
+//the lastest messages, we compare the oldest messsage's timestamp $a to user's
+//timestamp $b, if $a<$b, directly return messages in global object, otherwise,
+//fetch the message from database.
+
+if (!empty($chat_message)) {
+ $message = new object();
+ $message->chatid = $chatuser->chatid;
+ $message->userid = $chatuser->userid;
+ $message->groupid = $chatuser->groupid;
+ $message->message = $chat_message;
+ $message->timestamp = time();
+
+ if (!($DB->insert_record('chat_messages', $message) && $DB->insert_record('chat_messages_current', $message))) {
+ echo get_string('cantlogin', 'chat');
+ } else {
+ echo 200;
+ }
+
+ $chatuser->lastmessageping = time() - 2;
+ $DB->update_record('chat_users', $chatuser);
+
+ add_to_log($course->id, 'chat', 'talk', "view.php?id=$cm->id", $chat->id, $cm->id);
+}
+?>
diff --git a/mod/chat/gui_ajax/script.js b/mod/chat/gui_ajax/script.js
new file mode 100644
index 0000000000..6601052696
--- /dev/null
+++ b/mod/chat/gui_ajax/script.js
@@ -0,0 +1,137 @@
+(function() {
+var Dom = YAHOO.util.Dom,
+// record msg IDs
+Event = YAHOO.util.Event;
+// window.onload
+Event.onDOMReady(function() {
+ // build layout
+ var layout = new YAHOO.widget.Layout({
+ units: [
+ { position: 'top', height: 50, body: 'chat_header', header: 'Chat Room', gutter: '5px', collapse: true, resize: false },
+ { position: 'right', header: 'User List', width: 300, resize: true, gutter: '5px', footer: null, collapse: true, scroll: true, body: 'chat_user_list', animate: false },
+ { position: 'bottom', header: 'Input Area', height: 100, resize: true, body: 'chat_input', gutter: '5px', collapse: true },
+ { position: 'left', header: 'Options', width: 200, resize: true, body: 'chat_options', gutter: '5px', collapse: true, close: true, collapseSize: 50, scroll: true, animate: false },
+ { position: 'center', body: 'chat_panel' }
+ ]
+ });
+ layout.on('render', function() {
+ layout.getUnitByPosition('left').on('close', function() {
+ closeLeft();
+ });
+ });
+ layout.render();
+ Event.on('btn_send', 'click', function(ev) {
+ var msg = document.getElementById('input_msgbox').value;
+ if (!msg) {
+ alert('null?');
+ return;
+ }
+ var url = 'post.php?chat_sid='+chat_cfg.sid;
+ Event.stopEvent(ev);
+ this.value = chat_lang.sending;
+ var a = YAHOO.util.Connect.asyncRequest('POST', url, send_cb, "chat_message="+msg);
+ });
+ // done build layout
+ var transaction = YAHOO.util.Connect.asyncRequest('POST', "update.php?chat_sid="+chat_cfg.sid+"&chat_init=1", init_cb, null);
+ var interval = setInterval(function(){
+ update_info();
+ }, chat_cfg.timer);
+});
+})();
+var msgs = [];
+
+function update_users(users) {
+ if(!users){
+ return;
+ }
+ var list = document.getElementById('listing');
+ list.innerHTML = '';
+ for(i in users){
+ var el = document.createElement('li');
+ el.innerHTML = users[i].firstname;
+ console.info(users[i]);
+ list.appendChild(el);
+ }
+}
+function update_info() {
+ if(!chat_cfg.req_count){
+ chat_cfg.req_count = 1;
+ } else {
+ chat_cfg.req_count++;
+ }
+ console.info(chat_cfg.req_count);
+ var url = "update.php?chat_sid="+chat_cfg.sid+"&chat_lasttime="+chat_cfg.chat_lasttime;
+ if(chat_cfg.chat_lastrow != null){
+ url += "&chat_lastrow="+chat_cfg.chat_lastrow;
+ }
+ var a = YAHOO.util.Connect.asyncRequest('POST', url, update_cb, null);
+}
+function append_msg(msg) {
+ var list = document.getElementById('msg_list');
+ var el = document.createElement('li');
+ el.innerHTML = msg;
+ list.appendChild(el);
+}
+
+var send_cb = {
+success: function(o) {
+ if(o.responseText == 200){
+ document.getElementById('btn_send').value = chat_lang.send;
+ document.getElementById('input_msgbox').value = '';
+ }
+ }
+}
+var update_cb = {
+success: function(o){
+ try {
+ if(o.responseText){
+ var data = YAHOO.lang.JSON.parse(o.responseText);
+ } else {
+ return;
+ }
+ } catch(e) {
+ alert('json invalid');
+ alert(o.responseText);
+ return;
+ }
+ if(!data)
+ return false;
+ chat_cfg.chat_lasttime = data['lasttime'];
+ chat_cfg.chat_lastrow = data['lastrow'];
+ // update messages
+ for (key in data['msgs']){
+ if(!in_array(key, msgs)){
+ msgs.push(key);
+ append_msg(data['msgs'][key]);
+ console.log(data['msgs'][key]);
+ }
+ }
+ // update users
+ update_users(data['users']);
+ // scroll to the bottom of the message list
+ //$('#msgpanel').scrollTop(20000);
+}
+}
+var init_cb = {
+ success: function(o){
+ if(o.responseText){
+ var data = YAHOO.lang.JSON.parse(o.responseText);
+ } else {
+ return;
+ }
+ if (data.users) {
+ console.info(data);
+ update_users(data.users);
+ }
+ }
+}
+function in_array(f, t){
+ var a = false;
+ for( var i = 0; iwwwroot.'/user/view.php?id='.$v->id.'&course='.$course->id;
+ $user['picture'] = print_user_picture($v->id, 0, $v->picture, false, true, false);
+ $users[] = $user;
+ }
+ //return json_encode($users);
+}
+
+$time_start = microtime_float();
+
+$chat_sid = required_param('chat_sid', PARAM_ALPHANUM);
+$chat_lasttime = optional_param('chat_lasttime', 0, PARAM_INT);
+$chat_init = optional_param('chat_init', 0, PARAM_INT);
+$chat_lastrow = optional_param('chat_lastrow', 1, PARAM_INT);
+$response = array();
+
+if (!$chatuser = $DB->get_record('chat_users', array('sid'=>$chat_sid))) {
+ $response['error'] = get_string('notlogged', 'chat');
+}
+
+//Get the minimal course
+if (!$course = $DB->get_record('course', array('id'=>$chatuser->course), 'id,theme,lang')) {
+ $response['error'] = get_string('invalidcourseid', 'error');
+}
+//Get the user theme and enough info to be used in chat_format_message() which passes it along to
+if (!$USER = $DB->get_record('user', array('id'=>$chatuser->userid))) { // no optimisation here, it would break again in future!
+ $response['error'] = get_string('invaliduserid', 'error');
+}
+
+if (!$cm = get_coursemodule_from_instance('chat', $chatuser->chatid, $course->id)) {
+ $response['error'] = get_string('invalidcoursemodule', 'error');
+}
+
+$users = new stdclass;
+
+if($CFG->chat_use_cache){
+ $cache = new file_cache();
+ $users = $cache->get('user');
+ if(empty($users)) {
+ $users = chat_get_users($chatuser->chatid, $chatuser->groupid, $cm->groupingid);
+ $cache->set('user', $users);
+ }
+ if($CFG->chat_ajax_debug)
+ $response['cache'] = 'yes';
+} else {
+ $users = chat_get_users($chatuser->chatid, $chatuser->groupid, $cm->groupingid);
+ if($CFG->chat_ajax_debug)
+ $response['cache'] = 'no';
+}
+
+if (!$users) {
+ $response['error'] = get_string('nousers', 'error');
+}
+
+format_user_list($users, $course);
+
+if(!empty($chat_init)) {
+ $response['users'] = $users;
+ echo json_encode($response);
+ die;
+}
+
+//Setup course, lang and theme
+course_setup($course);
+
+// force deleting of timed out users if there is a silence in room or just entering
+if ((time() - $chat_lasttime) > $CFG->chat_old_ping) {
+ // must be done before chat_get_latest_message!!!
+ chat_delete_old_users();
+}
+if ($message = chat_get_latest_message($chatuser->chatid, $chatuser->groupid)) {
+ $chat_newlasttime = $message->timestamp;
+} else {
+ $chat_newlasttime = 0;
+}
+
+if ($chat_lasttime == 0) { //display some previous messages
+ $chat_lasttime = time() - $CFG->chat_old_ping; //TODO - any better value??
+}
+
+$params = array('groupid'=>$chatuser->groupid, 'chatid'=>$chatuser->chatid, 'lasttime'=>$chat_lasttime);
+
+$groupselect = $chatuser->groupid ? " AND (groupid=".$chatuser->groupid." OR groupid=0) " : "";
+
+$messages = $DB->get_records_select("chat_messages_current",
+ "chatid = :chatid AND timestamp > :lasttime $groupselect", $params,
+ "timestamp ASC");
+if ($messages) {
+ $num = count($messages);
+ if($CFG->chat_ajax_debug)
+ $response['count'] = $num;
+} else {
+ $num = 0;
+}
+
+$chat_newrow = ($chat_lastrow + $num) % 2;
+
+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');
+
+ob_start();
+
+$beep = false;
+$us = array ();
+$sendlist = false;
+if ($messages && ($chat_lasttime != $chat_newlasttime)) {
+ foreach ($messages as $n => &$message) {
+ if($message->system == 1){
+ $sendlist = true;
+ $users = chat_get_users($chatuser->chatid, $chatuser->groupid, $cm->groupingid);
+ if($CFG->chat_use_cache){
+ $cache = new file_cache();
+ $cache->set('user', $users);
+ }
+ format_user_list($users, $course);
+ }
+ $html = chat_format_message($message, $chatuser->course, $USER, $chat_lastrow);
+ if ($html->beep) {
+ $beep = true;
+ }
+ $message = $html->html;
+ }
+}
+
+if($users && $sendlist){
+ $response['users'] = $users;
+}
+if ($beep) {
+ $response['beep'] = true;
+}
+$response['lasttime'] = $chat_newlasttime;
+$response['lastrow'] = $chat_newrow;
+if($messages){
+ $response['msgs'] = $messages;
+}
+
+// set user's last active time
+$chatuser->lastping = time();
+$DB->set_field('chat_users', 'lastping', $chatuser->lastping, array('id'=>$chatuser->id));
+header("Content-Length: " . ob_get_length() );
+header("X-Powered-By: MOODLE-Chat-MOD");
+ob_end_flush();
+
+$time_end = microtime_float();
+$time = $time_end-$time_start;
+if($CFG->chat_ajax_debug)
+ $response['time']=$time;
+
+echo json_encode($response);
+?>
diff --git a/mod/chat/lib.php b/mod/chat/lib.php
index 9891ff83b2..d89d94cca6 100644
--- a/mod/chat/lib.php
+++ b/mod/chat/lib.php
@@ -3,6 +3,10 @@
/// Library of functions and constants for module chat
require_once($CFG->libdir.'/pagelib.php');
+$CFG->chat_enable_ajax = true;
+$CFG->chat_ajax_debug = false;
+$CFG->chat_use_cache = false;
+
// The HTML head for the message window to start with ( is used to get some browsers starting with output
$CHAT_HTMLHEAD = "\n\n\n".padding(200);
@@ -32,7 +36,24 @@ $CHAT_HTMLHEAD_OUT = "Message Input ";
// The HTML code for the message input page, with JavaScript
-$CHAT_HTMLHEAD_MSGINPUT_JS = "Message Input \n\n";
+$CHAT_HTMLHEAD_MSGINPUT_JS = <<
+
+ Message Input
+
+ ;
+EOD;
// Dummy data that gets output to the browser as needed, in order to make it show output
$CHAT_DUMMY_DATA = padding(200);
@@ -692,10 +713,16 @@ function chat_format_message_manually($message, $courseid, $sender, $currentuser
return false;
}
} else if (substr($text, 0, 1) == '/') { /// It's a user command
- if (trim(substr($text, 0, 4)) == '/me') {
+ // support some IRC commands
+ $pattern = '#(^\/)(\w+).*#';
+ preg_match($pattern, trim($text), $matches);
+ $command = $matches[2];
+ switch ($command){
+ case 'me':
$special = true;
$outinfo = $message->strtime;
- $outmain = $sender->firstname.' '.substr($text, 4);
+ $outmain = '*** '.$sender->firstname.' '.substr($text, 4).' ';
+ break;
}
}
diff --git a/mod/chat/view.php b/mod/chat/view.php
index 4d1dfdf972..b6e9577c06 100644
--- a/mod/chat/view.php
+++ b/mod/chat/view.php
@@ -147,9 +147,16 @@
"chat$course->id$chat->id$groupparam", "$strenterchat", 500, 700, get_string('modulename', 'chat'));
echo '
';
+ if ($CFG->chat_enable_ajax) {
+ echo '';
+ link_to_popup_window ("/mod/chat/gui_ajax/index.php?id=$chat->id$groupparam",
+ "chat$course->id$chat->id$groupparam", get_string('ajax_gui', 'message'), 500, 700, get_string('modulename', 'chat'));
+ echo '
';
+ }
// if user is using screen reader, then there is no need to display this link again
if ($CFG->chat_method == 'header_js' && empty($USER->screenreader)) {
// show frame/js-less alternative
+
echo '(';
link_to_popup_window ("/mod/chat/gui_basic/index.php?id=$chat->id$groupparam",
"chat$course->id$chat->id$groupparam", get_string('noframesjs', 'message'), 500, 700, get_string('modulename', 'chat'));
--
2.39.5