diff --git a/src/webim/client.php b/src/webim/client.php
index 6e632adf..e2e7a35a 100644
--- a/src/webim/client.php
+++ b/src/webim/client.php
@@ -29,7 +29,11 @@ if( !isset($_GET['token']) || !isset($_GET['thread']) ) {
$thread = create_thread($userName, $remote, $referer,$current_locale);
$_SESSION['threadid'] = $thread['threadid'];
+ if( $referer ) {
+ post_message($thread['threadid'],$kind_for_agent,getstring2('chat.came.from',array($referer)));
+ }
post_message($thread['threadid'],$kind_info,getstring('chat.wait'));
+
}
$threadid = $thread['threadid'];
$token = $thread['ltoken'];
@@ -52,7 +56,7 @@ if( !$thread || !isset($thread['ltoken']) || $token != $thread['ltoken'] ) {
setup_chatview_for_user($thread, $level);
start_html_output();
-$pparam = verifyparam( "page", "/^(mailthread)$/", "default");
+$pparam = verifyparam( "act", "/^(mailthread)$/", "default");
if( $pparam == "mailthread" ) {
require('view/chat_mailthread.php');
} else if( $level == "ajaxed" ) {
diff --git a/src/webim/install/index.php b/src/webim/install/index.php
index 6ee0cc8f..0e4f02df 100644
--- a/src/webim/install/index.php
+++ b/src/webim/install/index.php
@@ -13,6 +13,7 @@
*/
require('../libs/common.php');
-require('view_index.php');
-?>
\ No newline at end of file
+start_html_output();
+require('view_index.php');
+?>
diff --git a/src/webim/install/install.php b/src/webim/install/install.php
index 1e0f3378..b47e3929 100644
--- a/src/webim/install/install.php
+++ b/src/webim/install/install.php
@@ -84,6 +84,7 @@ function create_tables() {
drop_tables();
create_tables();
+start_html_output();
require('view_install.php');
?>
\ No newline at end of file
diff --git a/src/webim/libs/chat.php b/src/webim/libs/chat.php
index 02acfb8d..d070bf6a 100644
--- a/src/webim/libs/chat.php
+++ b/src/webim/libs/chat.php
@@ -10,8 +10,11 @@
*
* Contributors:
* Evgeny Gryaznov - initial API and implementation
+ * Pavel Petroshenko - history search
*/
+$connection_timeout = 30; # sec
+
$namecookie = "WEBIM_Name";
$state_queue = 0;
@@ -21,13 +24,16 @@ $state_closed = 3;
$kind_user = 1;
$kind_agent = 2;
+$kind_for_agent = 3;
$kind_info = 4;
$kind_conn = 5;
$kind_events = 6;
-$kind_to_string = array( $kind_user => "user", $kind_agent => "agent",
+$kind_to_string = array( $kind_user => "user", $kind_agent => "agent", $kind_for_agent => "hidden",
$kind_info => "inf", $kind_conn => "conn", $kind_events => "event" );
+
+
function next_token() {
return rand(99999,99999999);
}
@@ -38,17 +44,21 @@ function next_revision($link) {
return $val;
}
-function post_message($threadid,$kind,$message,$from=null) {
- $link = connect();
-
+function post_message_($threadid,$kind,$message,$link,$from=null,$time=null) {
$query = sprintf(
- "insert into chatmessage (threadid,ikind,tmessage,tname,dtmcreated) values (%s, %s,'%s',%s,CURRENT_TIMESTAMP)",
+ "insert into chatmessage (threadid,ikind,tmessage,tname,dtmcreated) values (%s, %s,'%s',%s,%s)",
$threadid,
$kind,
mysql_real_escape_string($message),
- $from ? "'".mysql_real_escape_string($from)."'" : "null" );
+ $from ? "'".mysql_real_escape_string($from)."'" : "null",
+ $time ? "FROM_UNIXTIME($time)" : "CURRENT_TIMESTAMP" );
perform_query($query,$link);
+}
+
+function post_message($threadid,$kind,$message,$from=null) {
+ $link = connect();
+ post_message_($threadid,$kind,$message,$link,$from);
mysql_close($link);
}
@@ -84,13 +94,14 @@ function message_to_text($msg) {
}
}
-function get_messages($threadid,$meth,&$lastid) {
+function get_messages($threadid,$meth,$isuser,&$lastid) {
+ global $kind_for_agent;
$link = connect();
$query = sprintf(
"select messageid,ikind,unix_timestamp(dtmcreated) as created,tname,tmessage from chatmessage ".
- "where threadid = %s and messageid > %s order by messageid",
- $threadid, $lastid );
+ "where threadid = %s and messageid > %s %s order by messageid",
+ $threadid, $lastid, $isuser ? "and ikind <> $kind_for_agent" : "" );
$messages = array();
$result = mysql_query($query,$link) or die(' Query failed: ' .mysql_error().": ".$query);
@@ -109,7 +120,7 @@ function get_messages($threadid,$meth,&$lastid) {
function print_thread_mesages($threadid, $token, $lastid, $isuser,$format) {
global $webim_encoding, $webimroot;
- $output = get_messages( $threadid, "html", $lastid );
+ $output = get_messages($threadid,"html",$isuser,$lastid);
if( $format == "xml" ) {
start_xml_output();
@@ -162,7 +173,7 @@ function setup_chatview_for_user($thread,$level) {
}
function setup_chatview_for_operator($thread) {
- global $page;
+ global $page, $webimroot;
$page = array();
$page['agent'] = true;
$page['user'] = false;
@@ -172,6 +183,9 @@ function setup_chatview_for_operator($thread) {
$page['ct.user.name'] = $thread['userName'];
$page['ct.company.name'] = "Test company";
$page['ct.company.chatLogoURL'] = "";
+
+ // TODO
+ $page['namePostfix'] = "";
}
function is_ajax_browser($name,$ver,$useragent) {
@@ -221,19 +235,55 @@ function get_remote_level($useragent) {
return "simple";
}
-function ping_thread($thread, $isuser) {
- $link = connect();
- $query = sprintf(
- "update chatthread set %s = CURRENT_TIMESTAMP where threadid = %s",
- $isuser ? "lastpinguser" : "lastpingagent",
- $thread['threadid']);
+function update_thread_access($threadid, $params, $link) {
+ $clause = "";
+ foreach( $params as $k => $v ) {
+ if( strlen($clause) > 0 )
+ $clause .= ", ";
+ $clause .= $k."=".$v;
+ }
+ perform_query(
+ "update chatthread set $clause ".
+ "where threadid = ".$threadid,$link);
+}
- perform_query($query,$link);
+function get_access_time($threadid, $isuser, $link) {
+ return select_one_row(sprintf(
+ "select unix_timestamp(%s) as lastping, ".
+ "unix_timestamp(CURRENT_TIMESTAMP) as current ".
+ "from chatthread where threadid = %s",
+ $isuser ? "lastpinguser" : "lastpingagent",
+ $threadid), $link);
+}
+
+function ping_thread($thread, $isuser) {
+ global $kind_for_agent, $state_chatting, $state_waiting, $kind_conn, $connection_timeout;
+ $link = connect();
+ $params = array(($isuser ? "lastpinguser" : "lastpingagent") => "CURRENT_TIMESTAMP" );
+
+ $access = get_access_time($thread['threadid'], !$isuser, $link);
+ if( $access['lastping'] > 0 && abs($access['current']-$access['lastping']) > $connection_timeout ) {
+ $params[$isuser ? "lastpingagent" : "lastpinguser"] = "0";
+ if( !$isuser ) {
+ $message_to_post = getstring_("chat.status.user.dead", $thread['locale']);
+ post_message_($thread['threadid'],$kind_for_agent,$message_to_post,$link,null,$access['lastping']+$connection_timeout);
+ } else if( $thread['istate'] == $state_chatting ) {
+
+ $message_to_post = getstring_("chat.status.operator.dead", $thread['locale']);
+ post_message_($thread['threadid'],$kind_conn,$message_to_post,$link,null,$access['lastping']+$connection_timeout);
+ $params['istate'] = $state_waiting;
+ commit_thread($thread['threadid'], $params, $link);
+ mysql_close($link);
+ return;
+ }
+ }
+
+ update_thread_access($thread['threadid'], $params, $link);
mysql_close($link);
}
function commit_thread($threadid,$params,$link) {
- $query = "update chatthread set lrevision = ".next_revision($link);
+ $query = "update chatthread set lrevision = ".next_revision($link).", dtmmodified = CURRENT_TIMESTAMP";
foreach( $params as $k => $v ) {
$query .= ", ".$k."=".$v;
}
@@ -273,7 +323,7 @@ function create_thread($username,$remote,$referer,$lang) {
$link = connect();
$query = sprintf(
- "insert into chatthread (userName,ltoken,remote,referer,lrevision,locale,dtmcreated,dtmmodified) values ('%s',%s,'%s','%s',%s,'%s',CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)",
+ "insert into chatthread (userName,"."ltoken,remote,referer,lrevision,locale,dtmcreated,dtmmodified) values ('%s','%s',%s,'%s','%s',%s,'%s',CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)",
mysql_real_escape_string($username),
next_token(),
mysql_real_escape_string($remote),
@@ -289,26 +339,29 @@ function create_thread($username,$remote,$referer,$lang) {
return $newthread;
}
-function do_take_thread($threadid,$operator) {
+function do_take_thread($threadid,$operatorName) {
global $state_chatting;
$link = connect();
commit_thread( $threadid,
array("istate" => $state_chatting,
- "agentName" => "'".mysql_real_escape_string($operator)."'"), $link);
+ "agentName" => "'".mysql_real_escape_string($operatorName)."'"), $link);
mysql_close($link);
}
function reopen_thread($threadid) {
- global $state_queue,$state_waiting,$state_chatting,$kind_events;
+ global $state_queue,$state_waiting,$state_chatting,$state_closed,$kind_events;
$thread = thread_by_id($threadid);
if( !$thread )
return FALSE;
+ if( $thread['istate'] == $state_closed )
+ return FALSE;
+
if( $thread['istate'] != $state_chatting && $thread['istate'] != $state_queue ) {
$link = connect();
commit_thread( $threadid,
- array("istate" => $state_waiting), $link);
+ array("istate" => $state_waiting ), $link);
mysql_close($link);
}
@@ -317,20 +370,26 @@ function reopen_thread($threadid) {
}
function take_thread($thread,$operator) {
- global $state_queue, $state_waiting,
- $state_chatting, $kind_events;
+ global $state_queue, $state_waiting, $state_chatting, $kind_events, $home_locale;
$state = $thread['istate'];
$threadid = $thread['threadid'];
$message_to_post = "";
+ $operatorName = ($thread['locale'] == $home_locale) ? $operator['vclocalename'] : $operator['vccommonname'];
+
if( $state == $state_queue || $state == $state_waiting) {
- do_take_thread($threadid, $operator);
- $message_to_post = getstring2_("chat.status.operator.joined", array($operator), $thread['locale']);
+ do_take_thread($threadid, $operatorName);
+
+ if( $state == $state_waiting ) {
+ $message_to_post = getstring2_("chat.status.operator.changed", array($operatorName,$thread['agentName']), $thread['locale']);
+ } else {
+ $message_to_post = getstring2_("chat.status.operator.joined", array($operatorName), $thread['locale']);
+ }
} else if( $state == $state_chatting ) {
- if( $operator != $thread['agentName'] ) {
- do_take_thread($threadid, $operator);
- $message_to_post = getstring2_("chat.status.operator.changed", array($operator, $thread['agentName']), $thread['locale']);
+ if( $operatorName != $thread['agentName'] ) {
+ do_take_thread($threadid, $operatorName);
+ $message_to_post = getstring2_("chat.status.operator.changed", array($operatorName, $thread['agentName']), $thread['locale']);
}
} else {
die("cannot take thread");
@@ -340,6 +399,17 @@ function take_thread($thread,$operator) {
post_message($threadid,$kind_events,$message_to_post);
}
+function check_for_reassign($thread,$operator) {
+ global $state_waiting, $home_locale, $kind_events;
+ $operatorName = ($thread['locale'] == $home_locale) ? $operator['vclocalename'] : $operator['vccommonname'];
+ if( $thread['istate'] == $state_waiting &&
+ ( $thread['agentName'] == $operatorName )) {
+ do_take_thread($thread['threadid'], $operatorName);
+ $message_to_post = getstring2_("chat.status.operator.changed", array($operatorName,$thread['agentName']), $thread['locale']);
+ post_message($thread['threadid'],$kind_events,$message_to_post);
+ }
+}
+
function thread_by_id($id) {
$link = connect();
$thread = select_one_row("select * from chatthread where threadid = ". $id, $link );
diff --git a/src/webim/libs/operator.php b/src/webim/libs/operator.php
index d2a944db..29cbe48e 100644
--- a/src/webim/libs/operator.php
+++ b/src/webim/libs/operator.php
@@ -15,7 +15,19 @@
function operator_by_login($login) {
$link = connect();
$operator = select_one_row(
- "select * from chatoperator where vclogin = '".mysql_real_escape_string($login)."'", $link );
+ "select * from chatoperator where vclogin = '".mysql_real_escape_string($login)."'", $link );
+ mysql_close($link);
+ return $operator;
+}
+
+function operator_by_id_($id,$link) {
+ return select_one_row(
+ "select * from chatoperator where operatorid = $id", $link );
+}
+
+function operator_by_id($id) {
+ $link = connect();
+ $operator = operator_by_id_($id,$link);
mysql_close($link);
return $operator;
}
diff --git a/src/webim/libs/pagination.php b/src/webim/libs/pagination.php
index 52a6fa0e..627de9cf 100644
--- a/src/webim/libs/pagination.php
+++ b/src/webim/libs/pagination.php
@@ -27,11 +27,11 @@ function generate_pagination_image($id) {
return "";
}
-function setup_pagination($items) {
+function setup_pagination($items,$default_items_per_page=15) {
global $page;
if( $items ) {
- $items_per_page = verifyparam("items", "/^\d{1,3}$/", 2);
+ $items_per_page = verifyparam("items", "/^\d{1,3}$/", $default_items_per_page);
if( $items_per_page < 2 )
$items_per_page = 2;
diff --git a/src/webim/mail.php b/src/webim/mail.php
index 1f3b0120..89fffbb4 100644
--- a/src/webim/mail.php
+++ b/src/webim/mail.php
@@ -30,7 +30,7 @@ $page['email'] = $mail;
$history = "";
$lastid = -1;
-$output = get_messages( $threadid, "text", $lastid );
+$output = get_messages( $threadid,"text",true,$lastid );
foreach( $output as $msg ) {
$history .= $msg;
}
diff --git a/src/webim/operator/agent.php b/src/webim/operator/agent.php
index 471dd790..04e16d45 100644
--- a/src/webim/operator/agent.php
+++ b/src/webim/operator/agent.php
@@ -31,9 +31,7 @@ if( !isset($_GET['token']) ) {
die("wrong thread");
}
- $operatorName = ($thread['locale'] == $home_locale) ? $operator['vclocalename'] : $operator['vccommonname'];
-
- take_thread($thread,$operatorName);
+ take_thread($thread,$operator);
$token = $thread['ltoken'];
header("Location: ".$_SERVER['PHP_SELF']."?thread=$threadid&token=$token");
@@ -50,6 +48,8 @@ if( !$thread || !isset($thread['ltoken']) || $token != $thread['ltoken'] ) {
setup_chatview_for_operator($thread);
start_html_output();
-require('../view/chat_ajaxed.php');
+
+
+ require('../view/chat_ajaxed.php');
?>
\ No newline at end of file
diff --git a/src/webim/operator/history.php b/src/webim/operator/history.php
new file mode 100644
index 00000000..052a4b91
--- /dev/null
+++ b/src/webim/operator/history.php
@@ -0,0 +1,55 @@
+ get_operator_name($operator) );
+$query = isset($_GET['q']) ? $_GET['q'] : false;
+
+if($query !== false) {
+ $link = connect();
+
+ $result = mysql_query(
+ "select DISTINCT unix_timestamp(chatthread.dtmcreated) as created, ".
+ "unix_timestamp(chatthread.dtmmodified) as modified, chatthread.threadid, ".
+ "chatthread.remote, chatthread.agentName, chatthread.userName ".
+ "from chatthread, chatmessage ".
+ "where chatmessage.threadid = chatthread.threadid and ".
+ "((chatthread.userName LIKE '%%$query%%') or ".
+ " (chatmessage.tmessage LIKE '%%$query%%'))".
+ "order by created DESC", $link)
+ or die(' Query failed: ' .mysql_error().": ".$query);
+
+ $foundThreads = array();
+ while ($thread = mysql_fetch_array($result, MYSQL_ASSOC)) {
+ $foundThreads[] = $thread;
+ }
+
+ mysql_free_result($result);
+ mysql_close($link);
+
+ $page['formq'] = $query;
+ setup_pagination($foundThreads);
+} else {
+ setup_empty_pagination();
+}
+
+start_html_output();
+require('../view/thread_search.php');
+?>
\ No newline at end of file
diff --git a/src/webim/operator/index.php b/src/webim/operator/index.php
index 0f82d3e0..7cb3c7f4 100644
--- a/src/webim/operator/index.php
+++ b/src/webim/operator/index.php
@@ -17,7 +17,22 @@ require('../libs/operator.php');
$operator = check_login();
-$page = array( 'operator' => get_operator_name($operator) );
+$page = array(
+ 'operator' => get_operator_name($operator),
+ 'version' => 'v1.0.7'
+);
+
+$localeLinks = "";
+foreach($available_locales as $k) {
+ if( strlen($localeLinks) > 0 )
+ $localeLinks .= " • ";
+ if( $k == $current_locale )
+ $localeLinks .= $k;
+ else
+ $localeLinks .= "$k";
+}
+
+$page['localeLinks'] = $localeLinks;
start_html_output();
require('../view/menu.php');
diff --git a/src/webim/operator/threadprocessor.php b/src/webim/operator/threadprocessor.php
new file mode 100644
index 00000000..e87d88ec
--- /dev/null
+++ b/src/webim/operator/threadprocessor.php
@@ -0,0 +1,32 @@
+ get_operator_name($operator) );
+
+
+if( isset($_GET['threadid'])) {
+ $threadid = verifyparam( "threadid", "/^(\d{1,9})?$/", "");
+ $lastid = -1;
+ $page['threadMessages'] = get_messages($threadid,"html",false,$lastid);
+}
+
+start_html_output();
+require('../view/thread_log.php');
+?>
\ No newline at end of file
diff --git a/src/webim/operator/update.php b/src/webim/operator/update.php
index 67fbf8e7..d92393c7 100644
--- a/src/webim/operator/update.php
+++ b/src/webim/operator/update.php
@@ -45,10 +45,12 @@ function thread_to_xml($thread) {
return $result."/>";
$state = getstring($threadstate_key[$thread['istate']]);
+ $threadoperator = ($thread['agentName'] ? $thread['agentName'] : "-");
+
$result .= " canopen=\"true\" state=\"$state\">";
$result .= "