瀏覽代碼

Adding global chat code. Now is working, new table need to be created and some code need revision see #3565

Julio Montoya 13 年之前
父節點
當前提交
effe444c56

+ 1 - 1
main/inc/ajax/chat.ajax.php

@@ -35,7 +35,7 @@ switch ($action) {
 		$chat->close();
 		break;		
 	case 'sendchat':		
-		$chat->send();
+		$chat->send(api_get_user_id(), $_POST['to'], $_POST['message']);
 		break;		
 	case 'startchatsession':
 		$chat->start_session();

+ 3 - 0
main/inc/header.inc.php

@@ -165,6 +165,9 @@ if ( ( navigator.userAgent.toLowerCase().indexOf('msie') != -1 ) && ( navigator.
 }
 
 var ajax_url = '<?php echo api_get_path(WEB_AJAX_PATH).'chat.ajax.php'; ?>';
+var online_button = '<?php  echo Security::remove_XSS(Display::return_icon('online.png')); ?>';
+var offline_button = '<?php echo Security::remove_XSS(Display::return_icon('offline.png')); ?>';
+
 
 //]]>
 </script>

+ 77 - 61
main/inc/lib/chat.lib.php

@@ -7,73 +7,83 @@
 *	@package chamilo.library
 */
 
-class Chat {
-	function __construct() {
-		
-	}
+class Chat extends Model {
 	
-	function heartbeat() {
-		$to_user_id = api_get_user_id();
+	var $table;
+    var $columns = array('id', 'from_user','to_user','message','sent','recd');
+    
+	public function __construct() {
+        $this->table =  Database::get_main_table(TABLE_MAIN_CHAT);
+	}    
 	
-		$sql = "select * from chat where (chat.to = '".intval($to_user_id)."' AND recd = 0) order by id ASC";
+	function heartbeat() {		
+		$to_user_id = api_get_user_id();
+		$my_user_info  = api_get_user_info();
+		
+		$sql = "SELECT * FROM ".$this->table." WHERE (to_user = '".intval($to_user_id)."' AND recd = 0) ORDER BY id ASC";
 		$result = Database::query($sql);
-		$items = '';
-
-		$chatBoxes = array();
+		
+		$chatBoxes = array();		
 		$items = array();
+		$_SESSION['chatHistory'] = null;
+		
 		while ($chat = Database::fetch_array($result,'ASSOC')) {
-			if (!isset($_SESSION['openChatBoxes'][$chat['from']]) && isset($_SESSION['chatHistory'][$chat['from']])) {
-				$items = $_SESSION['chatHistory'][$chat['from']];
+			if (!isset($_SESSION['openChatBoxes'][$chat['from_user']]) && isset($_SESSION['chatHistory'][$chat['from_user']])) {				
+				$items = $_SESSION['chatHistory'][$chat['from_user']];				
 			}
-			$chat['message'] = sanitize($chat['message']);
-			$item = array('s' => '0', 'f' => $chat['from'], 'm' => $chat['message'] );
-			$items[] = $item;
-
-			if (!isset($_SESSION['chatHistory'][$chat['from']])) {
-				$_SESSION['chatHistory'][$chat['from']] = '';
+			$user_info = api_get_user_info($chat['from_user'], true);			
+			
+			//$chat['message'] = self::sanitize($chat['message']);
+			$chat['message'] = Security::remove_XSS($chat['message']);
+			$item = array('s' => '0', 'f' => $chat['from_user'], 'm' => $chat['message'], 'online' => $user_info['user_is_online'], 'username' => $user_info['complete_name']);
+			$items []= $item;
+			
+			
+			if (!isset($_SESSION['chatHistory'][$chat['from_user']])) {
+				$_SESSION['chatHistory'][$chat['from_user']] = array();				
 			}
+			$_SESSION['chatHistory'][$chat['from_user']][] = $item;
 
-			$_SESSION['chatHistory'][$chat['from']] .= json_encode($item);
-
-
-			unset($_SESSION['tsChatBoxes'][$chat['from']]);
-			$_SESSION['openChatBoxes'][$chat['from']] = $chat['sent'];
+			unset($_SESSION['tsChatBoxes'][$chat['from_user']]);
+			$_SESSION['openChatBoxes'][$chat['from_user']] = $chat['sent'];
 		}
 
 		if (!empty($_SESSION['openChatBoxes'])) {
 			foreach ($_SESSION['openChatBoxes'] as $chatbox => $time) {
 				if (!isset($_SESSION['tsChatBoxes'][$chatbox])) {
-					$now = time()-strtotime($time);
+					$now = time() - strtotime($time);
 					$time = date('g:iA M dS', strtotime($time));
 
-					$message = "Sent at $time";
+					$message = get_lang('SentAt')." ".$time;
 					if ($now > 180) {
-
-						$item = array('s' => '2', 'f' => $chatbox, 'm' => $message);
-						$items[] = $item;
+						$user_info = api_get_user_info($chatbox, true);
+						$item = array('s' => '2', 'f' => $chatbox, 'm' => $message, 'online' => $user_info['user_is_online'], 'username' => $user_info['complete_name']);
+						$items [] = ($item);
 						if (!isset($_SESSION['chatHistory'][$chatbox])) {
 							$_SESSION['chatHistory'][$chatbox] = '';
 						}
 
-						$_SESSION['chatHistory'][$chatbox] .= json_encode($item);
+						$_SESSION['chatHistory'][$chatbox][] = ($item);
 						$_SESSION['tsChatBoxes'][$chatbox] = 1;
 					}			
 				}
 			}
 		}
 
-
-		$sql = "update chat set recd = 1 where chat.to = '".mysql_real_escape_string($to_user_id)."' and recd = 0";
+		$sql = "UPDATE ".$this->table." SET recd = 1 WHERE to_user = '".$to_user_id."' AND recd = 0";
 		$query = Database::query($sql);
+		
 		if ($items != '') {
 			//$items = substr($items, 0, -1);
-		}	
-	
+		}		
 		echo json_encode(array('items' => $items));
 	}
 	
-	function chatBoxSession($chatbox) {
-		$items = '';
+	/* 
+	 * chatBoxSession
+	 */
+	function box_session($chatbox) {
+		$items = array();
 		if (isset($_SESSION['chatHistory'][$chatbox])) {
 			$items = $_SESSION['chatHistory'][$chatbox];
 		}
@@ -82,47 +92,53 @@ class Chat {
 
 	function start_session() {
 		$items = '';
+		
 		if (!empty($_SESSION['openChatBoxes'])) {
 			foreach ($_SESSION['openChatBoxes'] as $chatbox => $void) {
-				$items .= chatBoxSession($chatbox);
+				$items = self::box_session($chatbox);
 			}
-		}
-		
+		}		
 		if ($items != '') {
-			$items = substr($items, 0, -1);
-		}
-		
-		$return = array('username' => api_get_user_id(), 'items' => $items);
+			//$items = substr($items, 0, -1);
+		}		
+		$return = array('username' => get_lang('Me'), 'user_id' => api_get_user_id(), 'items' => $items);
 		echo json_encode($return);
 		exit;
 	}
 
 	function send($from_user_id, $to_user_id, $message) {
-		$from = $_SESSION['username'];
-		$to = $_POST['to'];
-		$message = $_POST['message'];
-
-		$_SESSION['openChatBoxes'][$_POST['to']] = date('Y-m-d H:i:s', time());
+	
+		$_SESSION['openChatBoxes'][$to_user_id] = api_get_utc_datetime();
 
-		$messagesan = sanitize($message);
+		$messagesan = self::sanitize($message);
 
-		if (!isset($_SESSION['chatHistory'][$_POST['to']])) {
-			$_SESSION['chatHistory'][$_POST['to']] = '';
+		if (!isset($_SESSION['chatHistory'][$to_user_id])) {
+			$_SESSION['chatHistory'][$to_user_id] = array();
 		}
+		$user_info = api_get_user_info($to);
+		
+		$complete_name = $user_info['complete_name'];
 
-		$_SESSION['chatHistory'][$_POST['to']] .= <<<EOD
-						   {
-				"s": "1",
-				"f": "{$to}",
-				"m": "{$messagesan}"
-		   },
-EOD;
-
+		$_SESSION['chatHistory'][$to_user_id][] = (
+												array(	"s" => "1", 
+														"f" => $to,
+														"m" => $messagesan,
+														"username" => $complete_name
+														)
+												);
 
-		unset($_SESSION['tsChatBoxes'][$_POST['to']]);
 
-		$sql = "insert into chat (chat.from,chat.to,message,sent) values ('".mysql_real_escape_string($from)."', '".mysql_real_escape_string($to)."','".mysql_real_escape_string($message)."',NOW())";
-		$query = mysql_query($sql);
+		unset($_SESSION['tsChatBoxes'][$to_user_id]);
+		
+		$params = array();
+		$params['from_user']	= $from_user_id;
+		$params['to_user']		= $to_user_id;
+		$params['message']		= $message;
+		$params['sent']			= api_get_utc_datetime();
+		
+		if (!empty($from_user_id) && !empty($to_user_id)) {		
+			$this->save($params);
+		}
 		echo "1";
 		exit;
 	}

+ 9 - 8
main/inc/lib/database.constants.inc.php

@@ -310,19 +310,21 @@ define('TABLE_USERGROUP_REL_SESSION',   'usergroup_rel_session');
 // Mail notifications
 define('TABLE_NOTIFICATION',               'notification');
 
-
 //Custom reports table
 define('TABLE_MAIN_REPORTS_KEYS',			'reports_keys');
 define('TABLE_MAIN_REPORTS_VALUES', 			'reports_values');
 
 //Storage api tables
 define('TABLE_MAIN_STORED_VALUES',			'stored_values');
-define('TABLE_MAIN_STORED_VALUES_STACK',	'stored_values_stack');
+define('TABLE_MAIN_STORED_VALUES_STACK',		'stored_values_stack');
+
 
 //Event tables
-define('TABLE_MAIN_EVENT_TYPE','event_type');
-define('TABLE_MAIN_EVENT_TYPE_MESSAGE','event_type_message');
-define('TABLE_MAIN_EVENT_TYPE_REL_USER','user_rel_event_type');
+/*
+define('TABLE_MAIN_EVENT_TYPE',				'event_type');
+define('TABLE_MAIN_EVENT_TYPE_MESSAGE',		'event_type_message');
+define('TABLE_MAIN_EVENT_TYPE_REL_USER',		'user_rel_event_type');
+*/
 
 define('TABLE_MAIN_SKILL',                  'skill');
 define('TABLE_MAIN_SKILL_REL_SKILL',        'skill_rel_skill');
@@ -330,7 +332,6 @@ define('TABLE_MAIN_SKILL_REL_GRADEBOOK',    'skill_rel_gradebook');
 define('TABLE_MAIN_SKILL_REL_USER',         'skill_rel_user');
 
 define('TABLE_MAIN_SKILL_PROFILE',          'skill_profile');
-define('TABLE_MAIN_SKILL_REL_PROFILE',         'skill_rel_profile');
-
-
+define('TABLE_MAIN_SKILL_REL_PROFILE',      'skill_rel_profile');
 
+define('TABLE_MAIN_CHAT',					'chat');

+ 19 - 7
main/inc/lib/javascript/chat/css/chat.css

@@ -5,9 +5,24 @@
 	display:none;
 }
 
+.user_status {
+	width:16px;
+	display:inline;
+	float:left;
+	padding: 0px 4px 0px 4px;	
+}
+
+.chatboxtitle {
+	font-weight: bold;
+	float: left;
+	font-size: 13px;
+	width: 160px;
+	cursor:pointer;
+}
+
 .chatboxhead {
 	background-color: #222;
-	padding:7px;
+	padding:7px 7px 7px 0px;
 	color: #ffffff;
 	border-right:1px solid #222;
 	border-left:1px solid #222;
@@ -64,7 +79,6 @@
 .chatboxinfo {
 	margin-left:-1em;
 	color:#666666;
-
 }
 
 .chatboxmessagefrom {
@@ -86,8 +100,6 @@
 	font-family:Verdana,Arial,"Bitstream Vera Sans",sans-serif;
 }
 
-.chatboxtitle {
-	font-weight: bold;
-	float: left;
-	font-size: 13px;
-}
+.chatboxoptions a:hover {
+	background-color: #aaa;
+}

+ 129 - 69
main/inc/lib/javascript/chat/js/chat.js

@@ -34,7 +34,8 @@ var newMessages = new Array();
 var newMessagesWin = new Array();
 var chatBoxes = new Array();
 
-//var ajax_url = 'chat.php'; variable loaded in header.inc.php
+
+//var ajax_url = 'chat.php'; // This variable is loaded in header.inc.php
 
 $(document).ready(function(){
 	originalTitle = document.title;
@@ -46,35 +47,58 @@ $(document).ready(function(){
 		windowFocus = true;
 		document.title = originalTitle;
 	});
+	
+	/* Live conditions */
+	
+	// Header
+	$('.chatboxtitle').live('click', function(){
+		chatbox = $(this).parents(".chatbox");
+		var chat_id = chatbox.attr('id');
+		chat_id = chat_id.split('_')[1];		
+		toggleChatBoxGrowth(chat_id);
+	});
+	
+	//Toggle
+	$('.chatboxhead .togglelink').live('click', function(){
+		var chat_id =  $(this).attr('rel');	
+		toggleChatBoxGrowth(chat_id);		
+	});	
+	
+	//Close
+	$('.chatboxhead .closelink').live('click', function(){			
+		var chat_id =  $(this).attr('rel');	
+		closeChatBox(chat_id);		
+	});	
 });
 
 
-
-function startChatSession(){  
+function startChatSession() {  
 	$.ajax({
 	  url: ajax_url+"?action=startchatsession",
 	  cache: false,
 	  dataType: "json",
 	  success: function(data) {
 		if (data) {
-			username = data.username;
+			username = data.username;			
 
 			$.each(data.items, function(i,item){
 				if (item)	{ // fix strange ie bug
-					my_user_id = item.f;
+					my_user_id		= item.f;
+					chatboxtitle	= item.username;
 					
 					if ($("#chatbox_"+my_user_id).length <= 0) {
-						createChatBox(my_user_id, chatboxtitle, 1);
+						createChatBox(my_user_id, chatboxtitle, 1, item.online);
 					}
 
 					if (item.s == 1) {
-						item.f = username;
+						//item.f = username;
 					}
-
 					if (item.s == 2) {
 						$("#chatbox_"+my_user_id+" .chatboxcontent").append('<div class="chatboxmessage"><span class="chatboxinfo">'+item.m+'</span></div>');
 					} else {
-						$("#chatbox_"+my_user_id+" .chatboxcontent").append('<div class="chatboxmessage"><span class="chatboxmessagefrom">'+item.f+':&nbsp;&nbsp;</span><span class="chatboxmessagecontent">'+item.m+'</span></div>');
+						$("#chatbox_"+my_user_id+" .chatboxcontent").append('<div class="chatboxmessage">\n\
+																				<span class="chatboxmessagefrom">'+item.username+':&nbsp;&nbsp;</span>\n\
+																				<span class="chatboxmessagecontent">'+item.m+'</span></div>');
 					}
 				}
 			});
@@ -82,7 +106,7 @@ function startChatSession(){
 			for (i=0;i<chatBoxes.length;i++) {
 				my_user_id = chatBoxes[i];
 				$("#chatbox_"+my_user_id+" .chatboxcontent").scrollTop($("#chatbox_"+my_user_id+" .chatboxcontent")[0].scrollHeight);
-				setTimeout('$("#chatbox_"+chatboxtitle+" .chatboxcontent").scrollTop($("#chatbox_"+chatboxtitle+" .chatboxcontent")[0].scrollHeight);', 100); // yet another strange ie bug
+				setTimeout('$("#chatbox_"+my_user_id+" .chatboxcontent").scrollTop($("#chatbox_"+my_user_id+" .chatboxcontent")[0].scrollHeight);', 100); // yet another strange ie bug
 			}
 			setTimeout('chatHeartbeat();',chatHeartbeatTime);
 		}		
@@ -107,11 +131,11 @@ function restructureChatBoxes() {
 }
 
 function chatWith(user_id, user_name) {
-	createChatBox(user_id, user_name);
+	createChatBox(user_id, user_name, 0, 1);
 	$("#chatbox_"+user_id+" .chatboxtextarea").focus();
 }
 
-function createChatBox(user_id, chatboxtitle, minimizeChatBox) {
+function createChatBox(user_id, chatboxtitle, minimizeChatBox, online) {
 	if ($("#chatbox_"+user_id).length > 0) {
 		if ($("#chatbox_"+user_id).css('display') == 'none') {
 			$("#chatbox_"+user_id).css('display','block');
@@ -119,14 +143,19 @@ function createChatBox(user_id, chatboxtitle, minimizeChatBox) {
 		}
 		$("#chatbox_"+user_id+" .chatboxtextarea").focus();
 		return;
-	}
+	}	
+
+	user_is_online = return_online_user(user_id, online);
 
 	$("<div />" ).attr("id","chatbox_"+user_id)
 	.addClass("chatbox")
 	.html('<div class="chatboxhead">\n\
+			'+user_is_online+'	\n\
 			<div class="chatboxtitle">'+chatboxtitle+'</div>\n\
-			<div class="chatboxoptions"><a href="javascript:void(0)" onclick="javascript:toggleChatBoxGrowth(\''+user_id+'\')"> _ </a>&nbsp;\n\
-			<a href="javascript:void(0)" onclick="javascript:closeChatBox(\''+user_id+'\')">X</a></div><br clear="all"/></div>\n\
+			<div class="chatboxoptions">\n\
+				<a class="togglelink" rel="'+user_id+'" href="javascript:void(0)" > _ </a>&nbsp;\n\
+				<a class="closelink" rel="'+user_id+'" href="javascript:void(0)">X</a></div>\n\
+				<br clear="all"/></div>\n\
 			<div class="chatboxcontent"></div>\n\
 			<div class="chatboxinput"><textarea class="chatboxtextarea" onkeydown="javascript:return checkChatBoxInputKey(event,this,\''+user_id+'\');"></textarea></div>')
 	.appendTo($( "body" ));
@@ -190,20 +219,52 @@ function createChatBox(user_id, chatboxtitle, minimizeChatBox) {
 	$("#chatbox_"+user_id).show();
 }
 
+function return_online_user(user_id, status) {
+	var div_wrapper = $("<div />" );
+	var new_div = $("<div />" );
+	
+	new_div.attr("id","online_"+user_id);
+	new_div.attr("class","user_status");
+	
+	if (status == '1' || status == 1) {
+		new_div.html(online_button);
+	} else {
+		new_div.html(offline_button);
+	}
+	div_wrapper.append(new_div);
+	return div_wrapper.html();	
+}
 
-function chatHeartbeat(){
+function update_online_user(user_id, status) {
+	if ($("#online_" +user_id).length > 0) {
+		if (status == 1) {
+			$("#online_" +user_id).html(online_button);
+		} else {
+			$("#online_" +user_id).html(offline_button);
+		}
+	}
+}
+/*
+ * Item array structure :
+ * 
+ * item.s = type 1= message, 2= sent at string
+ * item.m = message
+ * item.f = from user
+ *
+ **/
 
+function chatHeartbeat() {
 	var itemsfound = 0;
 	
 	if (windowFocus == false) {
  
 		var blinkNumber = 0;
-		var titleChanged = 0;
+		var titleChanged = 0;		
 		for (x in newMessagesWin) {
-			if (newMessagesWin[x] == true) {
+			if (newMessagesWin[x].status == true) {
 				++blinkNumber;
 				if (blinkNumber >= blinkOrder) {
-					document.title = x+' says...';
+					document.title = newMessagesWin[x].username+' says...';
 					titleChanged = 1;
 					break;	
 				}
@@ -219,7 +280,7 @@ function chatHeartbeat(){
 
 	} else {
 		for (x in newMessagesWin) {
-			newMessagesWin[x] = false;
+			newMessagesWin[x].status = false;
 		}
 	}
 
@@ -233,40 +294,44 @@ function chatHeartbeat(){
 	}
 	
 	$.ajax({
-	  url: ajax_url+"?action=chatheartbeat",
-	  cache: false,
-	  dataType: "json",
-	  success: function(data) {
-
-		$.each(data.items, function(i, item) {
-			if (item)	{ // fix strange ie bug
+		url: ajax_url+"?action=chatheartbeat",
+		cache: false,
+		dataType: "json",
+		success: function(data) {			
+			$.each(data.items, function(i, item) {
+				if (item)	{ // fix strange ie bug
 
-				my_user_id = item.f;
+					my_user_id = item.f;				
 
-				if ($("#chatbox_"+my_user_id).length <= 0) {
-					createChatBox(my_user_id);
-				}
-				if ($("#chatbox_"+my_user_id).css('display') == 'none') {
-					$("#chatbox_"+my_user_id).css('display','block');
-					restructureChatBoxes();
-				}
-				
-				if (item.s == 1) {
-					item.f = username;
-				}
+					if ($("#chatbox_"+my_user_id).length <= 0) {
+						createChatBox(my_user_id, item.username, 0, item.online);
+					}
+					
+					if ($("#chatbox_"+my_user_id).css('display') == 'none') {
+						$("#chatbox_"+my_user_id).css('display','block');
+						restructureChatBoxes();
+					}
+						
+					if (item.s == 1) {
+						//item.f = username;
+					}
+					update_online_user(my_user_id, item.online);
+					
+					if (item.s == 2) {
+						$("#chatbox_"+my_user_id+" .chatboxcontent").append('<div class="chatboxmessage"><span class="chatboxinfo">'+item.m+'</span></div>');
+					} else {
+						newMessages[my_user_id]		= {'status':true,'username':item.username};
+						newMessagesWin[my_user_id]	= {'status':true,'username':item.username};						
+						
+						$("#chatbox_"+my_user_id+" .chatboxcontent").append('<div class="chatboxmessage">\n\
+																			 <span class="chatboxmessagefrom">'+item.username+':&nbsp;&nbsp;</span>\n\
+																			 <span class="chatboxmessagecontent">'+item.m+'</span></div>');
+					}
 
-				if (item.s == 2) {
-					$("#chatbox_"+my_user_id+" .chatboxcontent").append('<div class="chatboxmessage"><span class="chatboxinfo">'+item.m+'</span></div>');
-				} else {
-					newMessages[my_user_id] = true;
-					newMessagesWin[my_user_id] = true;
-					$("#chatbox_"+chatboxtitle+" .chatboxcontent").append('<div class="chatboxmessage"><span class="chatboxmessagefrom">'+item.f+':&nbsp;&nbsp;</span><span class="chatboxmessagecontent">'+item.m+'</span></div>');
+					$("#chatbox_"+my_user_id+" .chatboxcontent").scrollTop($("#chatbox_"+my_user_id+" .chatboxcontent")[0].scrollHeight);
+					itemsfound += 1;
 				}
-
-				$("#chatbox_"+my_user_id+" .chatboxcontent").scrollTop($("#chatbox_"+my_user_id+" .chatboxcontent")[0].scrollHeight);
-				itemsfound += 1;
-			}
-		});
+			});
 
 		chatHeartbeatCount++;
 
@@ -280,7 +345,7 @@ function chatHeartbeat(){
 				chatHeartbeatTime = maxChatHeartbeat;
 			}
 		}
-		
+
 		setTimeout('chatHeartbeat();',chatHeartbeatTime);
 	}});
 }
@@ -288,48 +353,43 @@ function chatHeartbeat(){
 function closeChatBox(chatboxtitle) {
 	$('#chatbox_'+chatboxtitle).css('display','none');
 	restructureChatBoxes();
-
 	$.post(ajax_url+"?action=closechat", { chatbox: chatboxtitle} , function(data){	
 	});
 
 }
 
-function toggleChatBoxGrowth(chatboxtitle) {
-	if ($('#chatbox_'+chatboxtitle+' .chatboxcontent').css('display') == 'none') {  
+function toggleChatBoxGrowth(user_id) {		
+	if ($('#chatbox_'+user_id+' .chatboxcontent').css('display') == 'none') {  
 		
 		var minimizedChatBoxes = new Array();
 		
 		if ($.cookie('chatbox_minimized')) {
-			minimizedChatBoxes = $.cookie('chatbox_minimized').split(/\|/);
+			minimizedChatBoxes = $.cookie('chatbox_minimized').split(/\|/);			
 		}
 
 		var newCookie = '';
 
 		for (i=0;i<minimizedChatBoxes.length;i++) {
-			if (minimizedChatBoxes[i] != chatboxtitle) {
-				newCookie += chatboxtitle+'|';
+			if (minimizedChatBoxes[i] != user_id) {
+				newCookie += user_id+'|';
 			}
 		}
 
-		newCookie = newCookie.slice(0, -1)
-
+		newCookie = newCookie.slice(0, -1);
 
 		$.cookie('chatbox_minimized', newCookie);
-		$('#chatbox_'+chatboxtitle+' .chatboxcontent').css('display','block');
-		$('#chatbox_'+chatboxtitle+' .chatboxinput').css('display','block');
-		$("#chatbox_"+chatboxtitle+" .chatboxcontent").scrollTop($("#chatbox_"+chatboxtitle+" .chatboxcontent")[0].scrollHeight);
-	} else {
-		
-		var newCookie = chatboxtitle;
+		$('#chatbox_'+user_id+' .chatboxcontent').css('display','block');
+		$('#chatbox_'+user_id+' .chatboxinput').css('display','block');
+		$("#chatbox_"+user_id+" .chatboxcontent").scrollTop($("#chatbox_"+user_id+" .chatboxcontent")[0].scrollHeight);
+	} else {		
+		var newCookie = user_id;
 
 		if ($.cookie('chatbox_minimized')) {
 			newCookie += '|'+$.cookie('chatbox_minimized');
 		}
-
-
 		$.cookie('chatbox_minimized',newCookie);
-		$('#chatbox_'+chatboxtitle+' .chatboxcontent').css('display','none');
-		$('#chatbox_'+chatboxtitle+' .chatboxinput').css('display','none');
+		$('#chatbox_'+user_id+' .chatboxcontent').css('display','none');
+		$('#chatbox_'+user_id+' .chatboxinput').css('display','none');
 	}
 	
 }

+ 9 - 3
main/inc/lib/main_api.lib.php

@@ -955,7 +955,10 @@ function _api_format_user($user) {
 	}    
 	
     $result['avatar'] = $avatar;
-    $result['avatar_small'] = $avatar_small;    
+    $result['avatar_small'] = $avatar_small;
+	if (isset($user['user_is_online'])) {
+		$result['user_is_online'] = $user['user_is_online'] == true ? 1 : 0;
+	}	
     return $result;
 }
 
@@ -966,7 +969,7 @@ function _api_format_user($user) {
  * @author Patrick Cool <patrick.cool@UGent.be>
  * @version 21 September 2004
  */
-function api_get_user_info($user_id = '') {    
+function api_get_user_info($user_id = '', $check_if_user_is_online = false) {    
     if ($user_id == '') {
         return _api_format_user($GLOBALS['_user']);
     }
@@ -974,9 +977,12 @@ function api_get_user_info($user_id = '') {
     $result = Database::query($sql);
     if (Database::num_rows($result) > 0) {
         $result_array = Database::fetch_array($result);
+		if ($check_if_user_is_online) {
+			$result_array['user_is_online'] = user_is_online($user_id);
+		}
         return _api_format_user($result_array);
-
     }
+	
     return false;
 }
 

+ 21 - 0
main/inc/lib/online.inc.php

@@ -115,6 +115,27 @@ function LoginDelete($user_id) {
 	@Database::query($query);
 }
 
+function user_is_online($user_id) {
+	$track_online_table = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ONLINE);
+	$friend_user_table  = Database::get_main_table(TABLE_MAIN_USER_REL_USER);
+	$table_user			= Database::get_main_table(TABLE_MAIN_USER);
+	
+	$current_date		= date('Y-m-d H:i:s',time());	
+	$access_url_id		= api_get_current_access_url_id();
+	
+	$time_limit			= api_get_setting('time_limit_whosonline');
+	$time_limit = 1;
+	
+	$query = "SELECT login_user_id,login_date FROM ".$track_online_table ." track INNER JOIN ".$table_user ." u ON (u.user_id=track.login_user_id)
+			  WHERE track.access_url_id =  $access_url_id AND DATE_ADD(login_date,INTERVAL $time_limit MINUTE) >= '".$current_date."'  AND u.user_id =  $user_id LIMIT 1  ";
+	
+	$result = Database::query($query);
+	if (Database::num_rows($result)) {
+		return true;
+	}
+	return false;
+	
+}
 /**
  * Gives a list of people online now (and in the last $valid minutes)
  * @param   int         Number of minutes to account logins for

+ 10 - 6
main/inc/lib/social.lib.php

@@ -677,17 +677,15 @@ class SocialManager extends UserManager {
 	        	echo '<li><a href="'.api_get_path(WEB_PATH).'main/social/search.php">'.Display::return_icon('zoom.png',get_lang('Search'),array('hspace'=>'6')).'<span class="'.($show=='search'?'social-menu-text-active':'social-menu-text4').'" >'.get_lang('Search').'</span></a></li>';
 				echo '<li><a href="'.api_get_path(WEB_PATH).'main/social/myfiles.php">'.Display::return_icon('briefcase.png',get_lang('MyFiles'),array('hspace'=>'6'),16).'<span class="'.($show=='myfiles'?'social-menu-text-active':'social-menu-text4').'" >'.get_lang('MyFiles').'</span></a></li>';
     	  	}
-
+			
+			$user_info = api_get_user_info($user_id);
+			
     	  	// My friend profile
     	  	$html_actions = '';
 
 	  		if ($user_id != api_get_user_id()) {
 	  			echo  '<li><a href="'.api_get_path(WEB_PATH).'main/messages/send_message_to_userfriend.inc.php?height=300&width=470&user_friend='.$user_id.'&view=profile&view_panel=1" class="thickbox" title="'.get_lang('SendMessage').'">';
-	  			echo  Display::return_icon('compose_message.png',get_lang('SendMessage')).'&nbsp;&nbsp;'.get_lang('SendMessage').'</a></li>';				
-				
-				$user_info = api_get_user_info($user_id);
-				$user_name  =$user_info['complete_name'];				
-				echo  Display::tag('li', Display::url(Display::return_icon('chat.gif').get_lang('chat'), 'javascript:void(0);', array('onclick' => "javascript:chatWith('".$user_id."', '".$user_name."')")));
+	  			echo  Display::return_icon('compose_message.png',get_lang('SendMessage')).'&nbsp;&nbsp;'.get_lang('SendMessage').'</a></li>';						
 	  		}
 
 	  		//check if I already sent an invitation message
@@ -700,6 +698,12 @@ class SocialManager extends UserManager {
 	  				echo  '<li><a href="'.api_get_path(WEB_PATH).'main/messages/send_message_to_userfriend.inc.php?view_panel=2&height=230&width=500&user_friend='.$user_id.'" class="thickbox" title="'.get_lang('SendInvitation').'">'.Display :: return_icon('invitation.png', get_lang('SocialInvitationToFriends')).'&nbsp;'.get_lang('SendInvitation').'</a></li>';
 	  			}
 	  		}
+			
+			//@todo check if user is online to show the chat link
+			if ($user_id != api_get_user_id()) {
+				$user_name  =$user_info['complete_name'];				
+				echo  Display::tag('li', Display::url(Display::return_icon('chat.gif').get_lang('Chat'), 'javascript:void(0);', array('onclick' => "javascript:chatWith('".$user_id."', '".Security::remove_XSS($user_name)."')")));
+			}
 	  		echo '</ul></div>';
 
         	/*

+ 30 - 13
main/inc/lib/template.lib.php

@@ -26,20 +26,20 @@ class Template extends Smarty {
 		$this->cache_lifetime 	= Smarty::CACHING_OFF; // no caching
 		//$this->cache_lifetime 	= 120;
 		
+		//Setting system variables
+		$this->set_system_parameters();	
+		
+		//Setting user variables 
+		$this->set_user_parameters();
+		
 		//header and footer are showed by default
 		$this->set_footer($show_footer);
 		$this->set_header($show_header);
 		
-		//Setting system variables
-		$this->set_system_parameters();
-        
-        //Setting user variables 
-		$this->set_user_parameters();
-		
 		//Creating a Smarty modifier - Now we can call the get_lang from a template!!! Just use {"MyString"|get_lang} 
 		$this->registerPlugin("modifier","get_lang", "get_lang");
 		
-		//Not recomended to use get_path, use {$_p['xxx']} see set_system_parameters(functions)
+		//Not recomended to use get_path, use {$_p.'xxx'} see the set_system_parameters()
 		$this->registerPlugin("modifier","get_path", "api_get_path");
 		$this->registerPlugin("modifier","get_setting", "api_get_setting");
 		
@@ -47,8 +47,7 @@ class Template extends Smarty {
 		//$this->loadPlugin('smarty_function_get_lang');
 		
 		//To the the smarty installation
-		//$this->testInstall();			
-		
+		//$this->testInstall();					
 		$this->set_header_parameters();
 		$this->set_footer_parameters();
         
@@ -200,6 +199,9 @@ class Template extends Smarty {
 			}
 		}
 		
+		 $this->assign('online_button', Security::remove_XSS(Display::return_icon('online.png')));
+		 $this->assign('offline_button', Security::remove_XSS(Display::return_icon('offline.png')));
+		
 		// Get language iso-code for this page - ignore errors		
 		
 		$this->assign('document_language', api_get_language_isocode());
@@ -229,11 +231,13 @@ class Template extends Smarty {
 		$my_style 		= api_get_visual_theme();	
 		
 		$style = '';
+		
 		//Base CSS
 		$style = '@import "'.api_get_path(WEB_CSS_PATH).'base.css";';
-		//Default CSS
+		
+		//Default theme CSS
 		$style .= '@import "'.api_get_path(WEB_CSS_PATH).$my_style.'/default.css";';
-		//Course CSS
+		//Course theme CSS
 		$style .= '@import "'.api_get_path(WEB_CSS_PATH).$my_style.'/course.css";';
 		
 		if ($navigator_info['name']=='Internet Explorer' &&  $navigator_info['version']=='6') {
@@ -245,6 +249,8 @@ class Template extends Smarty {
 		$style_print =  '@import "'.api_get_path(WEB_CSS_PATH).$my_style.'/print.css";';
 		$this->assign('css_style_print', $style_print);
 		
+		//Extra JS files
+		
 		$js_files = array(
 			'jquery.min.js',
 			'chosen/chosen.jquery.min.js',
@@ -252,9 +258,13 @@ class Template extends Smarty {
 			'jquery.menu.js',
 			'dtree/dtree.js',
 			'email_links.lib.js.php',
-			'bootstrap/bootstrap-dropdown.js'
+			'bootstrap/bootstrap-dropdown.js'			
 		);
 		
+		if (1) {
+			$js_files[] = 'chat/js/chat.js';
+		}
+		
 		if (api_get_setting('accessibility_font_resize') == 'true') {
 			$js_files[] = 'fontresize.js';
 		}
@@ -269,6 +279,8 @@ class Template extends Smarty {
 			$js_file_to_string .= api_get_js($js_file);
 		}
 		
+		//Extra CSS files
+		
 		$css_files = array (
 			api_get_path(WEB_LIBRARY_PATH).'javascript/thickbox.css',
 			api_get_path(WEB_LIBRARY_PATH).'javascript/chosen/chosen.css',
@@ -279,12 +291,17 @@ class Template extends Smarty {
 			$css_files[] = api_get_path(WEB_CSS_PATH).$my_style.'/learnpath.css';
 		}
 		
+		if (1) {
+			$css_files[] = api_get_path(WEB_LIBRARY_PATH).'javascript/chat/css/chat.css';
+		}
+		
+		
 		$css_file_to_string = '';
 		foreach($css_files  as $css_file) {
 			$css_file_to_string .= api_get_css($css_file);
 		}
 	
-		global $this_section, $nameTools;	
+		global $this_section, $nameTools;
 		$this->assign('css_file_to_string', $css_file_to_string);
 		$this->assign('js_file_to_string',  $js_file_to_string);		
 		$this->assign('text_direction',	    api_get_text_direction());			

+ 14 - 1
main/install/db_main.sql

@@ -2844,4 +2844,17 @@ CREATE TABLE user_rel_course_vote (
 
 ALTER TABLE user_course_vote ADD INDEX idx_ucv_cid (c_id);
 ALTER TABLE user_course_vote ADD INDEX idx_ucv_uid (user_id);
-ALTER TABLE user_course_vote ADD INDEX idx_ucv_cuid (user_id, c_id);
+ALTER TABLE user_course_vote ADD INDEX idx_ucv_cuid (user_id, c_id);
+
+
+CREATE TABLE chat (
+	id			INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
+	from_user	INTEGER,
+	to_user		INTEGER,
+	message		TEXT NOT NULL,
+	sent		DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+	recd		INTEGER UNSIGNED NOT NULL DEFAULT 0,
+	PRIMARY KEY (id),
+	INDEX to (to),
+ INDEX from (from)
+);

+ 3 - 3
main/social/profile.php

@@ -234,8 +234,8 @@ $user_online_count = count($user_online_list);
 echo '<div id="social-content">';
 
 echo '<div id="social-content-left">';
-    //this include the social menu div
-    SocialManager::show_social_menu('shared_profile', null, $user_id, $show_full_profile);
+//this include the social menu div
+SocialManager::show_social_menu('shared_profile', null, $user_id, $show_full_profile);
 echo '</div>';
 
 echo '<div id="social-content-right">';
@@ -388,8 +388,8 @@ if ($show_full_profile) {
 
 		$j=1;
 		for ($k=0;$k<$number_friends;$k++) {
-
 			if ($j > $number_of_images) break;
+			
 			if (isset($friends[$k])) {
 				$friend = $friends[$k];
 				$name_user	= api_get_person_name($friend['firstName'], $friend['lastName']);

+ 8 - 3
main/template/default/layout/head.tpl

@@ -20,11 +20,11 @@
 	/*<![CDATA[*/
 	{$css_style_print}
 	/*]]>*/
-</style>	
-{literal}
+</style>
 <script type="text/javascript">
 //<![CDATA[
 // This is a patch for the "__flash__removeCallback" bug, see FS#4378.
+{literal}
 if ( ( navigator.userAgent.toLowerCase().indexOf('msie') != -1 ) && ( navigator.userAgent.toLowerCase().indexOf( 'opera' ) == -1 ) ) {
     window.attachEvent( 'onunload', function() {
             window['__flash__removeCallback'] = function ( instance, name ) {
@@ -37,9 +37,14 @@ if ( ( navigator.userAgent.toLowerCase().indexOf('msie') != -1 ) && ( navigator.
             } ;
     });
 }
+{/literal}
 //]]>
+	
+var ajax_url = '{$_p.web_ajax}chat.ajax.php';
+var online_button = '{$online_button}';
+var offline_button ='{$offline_button}';
+
 </script>
-{/literal}
 {$js_file_to_string}
 {$css_file_to_string}
 {$extra_headers}