From: dongsheng Date: Tue, 18 Nov 2008 05:21:57 +0000 (+0000) Subject: MDL-14651 X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=1d5071868fe385f9a27582ddd0a4c6c8bf8ededd;p=moodle.git MDL-14651 1. identify IRC commands 2. commiting ajax chat room, I lost my half finished source code, so I have to start again :-( --- 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'); +?> + + + + + + + + + + + + + +
+

Moodle 2.0

+
+
+ + +
+
+ +
+
+
+
+
+ + 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'));