$string['addcontact'] = 'Add contact';
$string['addsomecontacts'] = 'To send a message to someone, or to add a shortcut for them on this page, use the <a href=\"$a\">search tab</a> 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';
--- /dev/null
+<?php
+class file_cache{
+ private $dir = '';
+ public function __construct($dir='/dev/shm'){
+ $this->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));
+ }
+}
+?>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<?php
+require_once('../../../config.php');
+require_once('../lib.php');
+require_once('common.php');
+function microtime_float(){
+ list($usec, $sec) = explode(" ", microtime());
+ return ((float)$usec+(float)$sec);
+}
+$time_start = microtime_float();
+$id = required_param('id', PARAM_INT);
+$groupid = optional_param('groupid', 0, PARAM_INT); //only for teachers
+if (!$chat = $DB->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');
+}
+?>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title></title>
+<link rel="stylesheet" type="text/css" href="<?php echo $CFG->httpswwwroot;?>/lib/yui/reset-fonts-grids/reset-fonts-grids.css" />
+
+<link rel="stylesheet" type="text/css" href="<?php echo $CFG->httpswwwroot;?>/lib/yui/resize/assets/skins/sam/resize.css" />
+<link rel="stylesheet" type="text/css" href="<?php echo $CFG->httpswwwroot;?>/lib/yui/layout/assets/skins/sam/layout.css" />
+<link rel="stylesheet" type="text/css" href="<?php echo $CFG->httpswwwroot;?>/lib/yui/button/assets/skins/sam/button.css" />
+<?php
+print_js_config(array('sid'=>$chat_sid,'timer'=>5000, 'chat_lasttime'=>0,'chat_lastrow'=>null), 'chat_cfg');
+print_js_config(array('send'=>$str_send, 'sending'=>$str_sending), 'chat_lang');
+?>
+<script type="text/javascript" src="<?php echo $CFG->httpswwwroot;?>/lib/yui/yahoo-dom-event/yahoo-dom-event.js"></script>
+<script type="text/javascript" src="<?php echo $CFG->httpswwwroot;?>/lib/yui/element/element-beta-min.js"></script>
+<script type="text/javascript" src="<?php echo $CFG->httpswwwroot;?>/lib/yui/dragdrop/dragdrop-min.js"></script>
+<script type="text/javascript" src="<?php echo $CFG->httpswwwroot;?>/lib/yui/resize/resize-min.js"></script>
+<script type="text/javascript" src="<?php echo $CFG->httpswwwroot;?>/lib/yui/layout/layout-min.js"></script>
+<script type="text/javascript" src="<?php echo $CFG->httpswwwroot;?>/lib/yui/container/container.js"></script>
+<script type="text/javascript" src="<?php echo $CFG->httpswwwroot;?>/lib/yui/connection/connection-min.js"></script>
+<script type="text/javascript" src="<?php echo $CFG->httpswwwroot;?>/lib/yui/json/json-min.js"></script>
+<script type="text/javascript" src="<?php echo $CFG->httpswwwroot;?>/lib/yui/button/button-min.js"></script>
+<script type="text/javascript" src="<?php echo $CFG->httpswwwroot;?>/lib/yui/selector/selector-beta-min.js"></script>
+<script type="text/javascript" src="script.js"></script>
+</head>
+<body class=" yui-skin-sam">
+<div id="chat_header">
+<p>Moodle 2.0</p>
+</div>
+<div id="chat_input">
+ <input type="text" id="input_msgbox" value="" size="48" />
+ <input type="button" id="btn_send" value="<?php echo $str_send;?>" />
+</div>
+<div id="chat_user_list">
+<ul id="listing">
+</ul>
+</div>
+<div id="chat_options">
+</div>
+<div id="chat_panel">
+<ul id="msg_list">
+<ul>
+</div>
+</body>
+</html>
--- /dev/null
+<?php // $Id$
+include('../../../config.php');
+include('../lib.php');
+
+$chat_sid = required_param('chat_sid', PARAM_ALPHANUM);
+$chat_message = required_param('chat_message', PARAM_RAW);
+
+if (!$chatuser = $DB->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);
+}
+?>
--- /dev/null
+(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; i<t.length; i++){
+ if(f==t[i]){
+ a=true;
+ break;
+ }
+ }
+ return a;
+}
--- /dev/null
+<?php // $Id$
+
+// Produce update information (json)
+require('../../../config.php');
+require('../lib.php');
+require_once('common.php');
+
+
+function microtime_float(){
+ list($usec, $sec) = explode(" ", microtime());
+ return ((float)$usec+(float)$sec);
+}
+function format_user_list(&$data, $course) {
+ global $CFG, $DB;
+ $users = array();
+ foreach($data as $v){
+ $user['name'] = fullname($v);
+ $user['url'] = $CFG->wwwroot.'/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);
+?>
/// 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 (<!-- nix --> is used to get some browsers starting with output
$CHAT_HTMLHEAD = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\"><html><head></head>\n<body>\n\n".padding(200);
$CHAT_HTMLHEAD_MSGINPUT = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\"><html><head><title>Message Input</title></head><body>";
// The HTML code for the message input page, with JavaScript
-$CHAT_HTMLHEAD_MSGINPUT_JS = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\"><html><head><title>Message Input</title>\n<script type=\"text/javascript\">\n//<![CDATA[\nscroll_active = true;\nfunction empty_field_and_submit()\n{\ndocument.fdummy.arsc_message.value=document.f.arsc_message.value;\ndocument.fdummy.submit();\ndocument.f.arsc_message.focus();\ndocument.f.arsc_message.select();\nreturn false;\n}\n//]]>\n</script>\n</head><body bgcolor=\"#FFFFFF\" OnLoad=\"document.f.arsc_message.focus();document.f.arsc_message.select();\">";
+$CHAT_HTMLHEAD_MSGINPUT_JS = <<<EOD
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html>
+ <head><title>Message Input</title>
+ <script type="text/javascript">
+ //<![CDATA[
+ scroll_active = true;
+ function empty_field_and_submit(){
+ document.fdummy.arsc_message.value=document.f.arsc_message.value;
+ document.fdummy.submit();
+ document.f.arsc_message.focus();
+ document.f.arsc_message.select();
+ return false;
+ }
+ //]]>
+ </script>
+ </head><body OnLoad="document.f.arsc_message.focus();document.f.arsc_message.select();">;
+EOD;
// Dummy data that gets output to the browser as needed, in order to make it show output
$CHAT_DUMMY_DATA = padding(200);
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 = '*** <b>'.$sender->firstname.' '.substr($text, 4).'</b>';
+ break;
}
}
"chat$course->id$chat->id$groupparam", "$strenterchat", 500, 700, get_string('modulename', 'chat'));
echo '</p>';
+ if ($CFG->chat_enable_ajax) {
+ echo '<p>';
+ 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 '</p>';
+ }
// 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 '<p>(';
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'));