mirror of
				https://github.com/Mibew/java.git
				synced 2025-10-31 18:41:09 +03:00 
			
		
		
		
	Replace thread related functions by Thread's methods
This commit is contained in:
		
							parent
							
								
									50283a0b21
								
							
						
					
					
						commit
						f81dad7eae
					
				| @ -19,13 +19,14 @@ require_once('libs/init.php'); | ||||
| require_once('libs/chat.php'); | ||||
| require_once('libs/operator.php'); | ||||
| require_once('libs/groups.php'); | ||||
| require_once('libs/classes/thread.php'); | ||||
| 
 | ||||
| $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ""; | ||||
| if($referer && isset($_SESSION['threadid'])) { | ||||
| 	$thread = thread_by_id($_SESSION['threadid']); | ||||
|     if ($thread && $thread['istate'] != $state_closed) { | ||||
|         $msg = getstring2_("chat.client.visited.page", array($referer), $thread['locale']); | ||||
|         post_message_($thread['threadid'], $kind_for_agent,$msg); | ||||
| 	$thread = Thread::load($_SESSION['threadid']); | ||||
|     if ($thread && $thread->state != Thread::STATE_CLOSED) { | ||||
|         $msg = getstring2_("chat.client.visited.page", array($referer), $thread->locale); | ||||
| 		$thread->postMessage(Thread::KIND_FOR_AGENT, $msg); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -22,6 +22,7 @@ require_once('libs/groups.php'); | ||||
| require_once('libs/expand.php'); | ||||
| require_once('libs/captcha.php'); | ||||
| require_once('libs/invitation.php'); | ||||
| require_once('libs/classes/thread.php'); | ||||
| 
 | ||||
| if(Settings::get('enablessl') == "1" && Settings::get('forcessl') == "1") { | ||||
| 	if(!is_secure_request()) { | ||||
| @ -39,7 +40,7 @@ if( !isset($_GET['token']) || !isset($_GET['thread']) ) { | ||||
| 
 | ||||
| 	$thread = NULL; | ||||
| 	if( isset($_SESSION['threadid']) ) { | ||||
| 		$thread = reopen_thread($_SESSION['threadid']); | ||||
| 		$thread = Thread::reopen($_SESSION['threadid']); | ||||
| 	} | ||||
| 
 | ||||
| 	if( !$thread ) { | ||||
| @ -106,36 +107,53 @@ if( !isset($_GET['token']) || !isset($_GET['thread']) ) { | ||||
| 		$remoteHost = get_remote_host(); | ||||
| 		$userbrowser = $_SERVER['HTTP_USER_AGENT']; | ||||
| 
 | ||||
| 		if(!check_connections_from_remote($remoteHost)) { | ||||
| 		if(Thread::connectionLimitReached($remoteHost)) { | ||||
| 			die("number of connections from your IP is exceeded, try again later"); | ||||
| 		} | ||||
| 		$thread = create_thread($groupid,$visitor['name'], $remoteHost, $referrer,$current_locale,$visitor['id'], $userbrowser,$state_loading); | ||||
| 		$_SESSION['threadid'] = $thread['threadid']; | ||||
| 		$thread = Thread::create(); | ||||
| 		$thread->groupId = $groupid; | ||||
| 		$thread->userName = $visitor['name']; | ||||
| 		$thread->remote = $remoteHost; | ||||
| 		$thread->referer = $referrer; | ||||
| 		$thread->locale = $current_locale; | ||||
| 		$thread->userId = $visitor['id']; | ||||
| 		$thread->userAgent = $userbrowser; | ||||
| 		$thread->state = Thread::STATE_LOADING; | ||||
| 		$thread->save(); | ||||
| 
 | ||||
| 		$operator = invitation_accept($_SESSION['visitorid'], $thread['threadid']); | ||||
| 		$_SESSION['threadid'] = $thread->id; | ||||
| 
 | ||||
| 		$operator = invitation_accept($_SESSION['visitorid'], $thread->id); | ||||
| 		if ($operator) { | ||||
| 		    $operator = operator_by_id($operator); | ||||
| 		    $operatorName = ($current_locale == $home_locale) ? $operator['vclocalename'] : $operator['vccommonname']; | ||||
| 		    post_message_($thread['threadid'], $kind_for_agent, getstring2('chat.visitor.invitation.accepted', array($operatorName))); | ||||
| 			$thread->postMessage( | ||||
| 				Thread::KIND_FOR_AGENT, | ||||
| 				getstring2('chat.visitor.invitation.accepted', array($operatorName)) | ||||
| 			); | ||||
| 		} | ||||
| 
 | ||||
| 		if( $referrer ) { | ||||
| 			post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.came.from',array($referrer))); | ||||
| 			$thread->postMessage( | ||||
| 				Thread::KIND_FOR_AGENT, | ||||
| 				getstring2('chat.came.from',array($referrer)) | ||||
| 			); | ||||
| 		} | ||||
| 		post_message_($thread['threadid'],$kind_info,getstring('chat.wait')); | ||||
| 		$thread->postMessage(Thread::KIND_INFO, getstring('chat.wait')); | ||||
| 		if($email) { | ||||
| 			post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.visitor.email',array($email))); | ||||
| 			$thread->postMessage(Thread::KIND_FOR_AGENT, getstring2('chat.visitor.email',array($email))); | ||||
| 		} | ||||
| 		if($info) { | ||||
| 			post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.visitor.info',array($info))); | ||||
| 			$thread->postMessage(Thread::KIND_FOR_AGENT, getstring2('chat.visitor.info',array($info))); | ||||
| 		} | ||||
| 		if($firstmessage) { | ||||
| 			$postedid = post_message_($thread['threadid'],$kind_user,$firstmessage,$visitor['name']); | ||||
| 			commit_thread( $thread['threadid'], array('shownmessageid' => $postedid)); | ||||
| 			$postedid = $thread->postMessage(Thread::KIND_USER, $firstmessage, $visitor['name']); | ||||
| 			$thread->shownMessageId = $postedid; | ||||
| 			$thread->save(); | ||||
| 		} | ||||
| 	} | ||||
| 	$threadid = $thread['threadid']; | ||||
| 	$token = $thread['ltoken']; | ||||
| 	$threadid = $thread->id; | ||||
| 	$token = $thread->lastToken; | ||||
| 	$level = get_remote_level($_SERVER['HTTP_USER_AGENT']); | ||||
| 	$chatstyle = verifyparam( "style", "/^\w+$/", ""); | ||||
| 	header("Location: $webimroot/client.php?thread=$threadid&token=$token&level=$level".($chatstyle ? "&style=$chatstyle" : "")); | ||||
| @ -146,8 +164,8 @@ $token = verifyparam( "token", "/^\d{1,8}$/"); | ||||
| $threadid = verifyparam( "thread", "/^\d{1,8}$/"); | ||||
| $level = verifyparam( "level", "/^(ajaxed|simple|old)$/"); | ||||
| 
 | ||||
| $thread = thread_by_id($threadid); | ||||
| if( !$thread || !isset($thread['ltoken']) || $token != $thread['ltoken'] ) { | ||||
| $thread = Thread::load($threadid, $token); | ||||
| if (! $thread) { | ||||
| 	die("wrong thread"); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -21,26 +21,39 @@ require_once('libs/expand.php'); | ||||
| require_once('libs/groups.php'); | ||||
| require_once('libs/captcha.php'); | ||||
| require_once('libs/notify.php'); | ||||
| require_once('libs/classes/thread.php'); | ||||
| 
 | ||||
| $errors = array(); | ||||
| $page = array(); | ||||
| 
 | ||||
| function store_message($name, $email, $info, $message,$groupid,$referrer) { | ||||
| 	global $state_left, $current_locale, $kind_for_agent, $kind_user; | ||||
| 	global $current_locale; | ||||
| 
 | ||||
| 	$remoteHost = get_remote_host(); | ||||
| 	$userbrowser = $_SERVER['HTTP_USER_AGENT']; | ||||
| 	$visitor = visitor_from_request(); | ||||
| 	$thread = create_thread($groupid,$name,$remoteHost,$referrer,$current_locale,$visitor['id'], $userbrowser,$state_left); | ||||
| 
 | ||||
| 	$thread = Thread::create(); | ||||
| 	$thread->groupId = $groupid; | ||||
| 	$thread->userName = $name; | ||||
| 	$thread->remote = $remoteHost; | ||||
| 	$thread->referer = $referrer; | ||||
| 	$thread->locale = $current_locale; | ||||
| 	$thread->userId = $visitor['id']; | ||||
| 	$thread->userAgent = $userbrowser; | ||||
| 	$thread->state = Thread::STATE_LEFT; | ||||
| 	$thread->save(); | ||||
| 
 | ||||
| 	if( $referrer ) { | ||||
| 		post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.came.from',array($referrer))); | ||||
| 		$thread->postMessage(Thread::KIND_FOR_AGENT,getstring2('chat.came.from',array($referrer))); | ||||
| 	} | ||||
| 	if($email) { | ||||
| 		post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.visitor.email',array($email))); | ||||
| 		$thread->postMessage(Thread::KIND_FOR_AGENT, getstring2('chat.visitor.email',array($email))); | ||||
| 	} | ||||
| 	if($info) { | ||||
| 		post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.visitor.info',array($info))); | ||||
| 		$thread->postMessage(Thread::KIND_FOR_AGENT, getstring2('chat.visitor.info',array($info))); | ||||
| 	} | ||||
| 	post_message_($thread['threadid'],$kind_user,$message,$name); | ||||
| 	$thread->postMessage(Thread::KIND_USER, $message, $name); | ||||
| } | ||||
| 
 | ||||
| $groupid = ""; | ||||
|  | ||||
| @ -16,77 +16,16 @@ | ||||
|  */ | ||||
| 
 | ||||
| require_once(dirname(__FILE__).'/track.php'); | ||||
| 
 | ||||
| $connection_timeout = 30; // sec
 | ||||
| require_once(dirname(__FILE__).'/classes/thread.php'); | ||||
| 
 | ||||
| $namecookie = "WEBIM_Data"; | ||||
| $usercookie = "WEBIM_UserID"; | ||||
| 
 | ||||
| $state_queue = 0; | ||||
| $state_waiting = 1; | ||||
| $state_chatting = 2; | ||||
| $state_closed = 3; | ||||
| $state_loading = 4; | ||||
| $state_left = 5; | ||||
| 
 | ||||
| $kind_user = 1; | ||||
| $kind_agent = 2; | ||||
| $kind_for_agent = 3; | ||||
| $kind_info = 4; | ||||
| $kind_conn = 5; | ||||
| $kind_events = 6; | ||||
| $kind_avatar = 7; | ||||
| 
 | ||||
| $kind_to_string = array($kind_user => "user", $kind_agent => "agent", $kind_for_agent => "hidden", | ||||
| 						$kind_info => "inf", $kind_conn => "conn", $kind_events => "event", $kind_avatar => "avatar"); | ||||
| 
 | ||||
| function get_user_id() | ||||
| { | ||||
| 	return (time() + microtime()) . rand(0, 99999999); | ||||
| } | ||||
| 
 | ||||
| function next_token() | ||||
| { | ||||
| 	return rand(99999, 99999999); | ||||
| } | ||||
| 
 | ||||
| function next_revision() | ||||
| { | ||||
| 	$db = Database::getInstance(); | ||||
| 	$db->query("update {chatrevision} set id=LAST_INSERT_ID(id+1)"); | ||||
| 	$val = $db->insertedId(); | ||||
| 	return $val; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * @todo Think about post_message_ and post_message diffrence | ||||
|  */ | ||||
| function post_message_($threadid, $kind, $message, $from = null, $utime = null, $opid = null) | ||||
| { | ||||
| 	$db = Database::getInstance(); | ||||
| 
 | ||||
| 	$query = "insert into {chatmessage} " . | ||||
| 		"(threadid,ikind,tmessage,tname,agentId,dtmcreated) " . | ||||
| 		"values (:threadid,:kind,:message,:name,:agentid,:created)"; | ||||
| 
 | ||||
| 	 $values = array( | ||||
| 		':threadid' => $threadid, | ||||
| 		':kind' => $kind, | ||||
| 		':message' => $message, | ||||
| 		':name' => ($from ? $from : "null"), | ||||
| 		':agentid' => ($opid ? $opid : 0), | ||||
| 		':created' => ($utime ? $utime : time()) | ||||
| 	); | ||||
| 
 | ||||
| 	$db->query($query, $values); | ||||
| 	return $db->insertedId(); | ||||
| } | ||||
| 
 | ||||
| function post_message($threadid, $kind, $message, $from = null, $agentid = null) | ||||
| { | ||||
| 	return post_message_($threadid, $kind, $message, $from, null, $agentid); | ||||
| } | ||||
| 
 | ||||
| function prepare_html_message($text, $allow_formating) | ||||
| { | ||||
| 	$escaped_text = htmlspecialchars($text); | ||||
| @ -102,28 +41,30 @@ function prepare_html_message($text, $allow_formating) | ||||
| 
 | ||||
| function message_to_html($msg) | ||||
| { | ||||
| 	global $kind_to_string, $kind_user, $kind_agent, $kind_avatar; | ||||
| 	if ($msg['ikind'] == $kind_avatar) return ""; | ||||
| 	if ($msg['ikind'] == Thread::KIND_AVATAR) { | ||||
| 		return ""; | ||||
| 	} | ||||
| 	$message = "<span>" . date("H:i:s", $msg['created']) . "</span> "; | ||||
| 	$kind = $kind_to_string{$msg['ikind']}; | ||||
| 	$kind = Thread::kindToString($msg['ikind']); | ||||
| 	if ($msg['tname']) | ||||
| 		$message .= "<span class='n$kind'>" . htmlspecialchars($msg['tname']) . "</span>: "; | ||||
| 	$allow_formating = ($msg['ikind'] != $kind_user && $msg['ikind'] != $kind_agent); | ||||
| 	$allow_formating = ($msg['ikind'] != Thread::KIND_USER && $msg['ikind'] != Thread::KIND_AGENT); | ||||
| 	$message .= "<span class='m$kind'>" . prepare_html_message($msg['tmessage'], $allow_formating) . "</span><br/>"; | ||||
| 	return $message; | ||||
| } | ||||
| 
 | ||||
| function message_to_text($msg) | ||||
| { | ||||
| 	global $kind_user, $kind_agent, $kind_info, $kind_avatar; | ||||
| 	if ($msg['ikind'] == $kind_avatar) return ""; | ||||
| 	if ($msg['ikind'] == Thread::KIND_AVATAR) { | ||||
| 		return ""; | ||||
| 	} | ||||
| 	$message_time = date("H:i:s ", $msg['created']); | ||||
| 	if ($msg['ikind'] == $kind_user || $msg['ikind'] == $kind_agent) { | ||||
| 	if ($msg['ikind'] == Thread::KIND_USER || $msg['ikind'] == Thread::KIND_AGENT) { | ||||
| 		if ($msg['tname']) | ||||
| 			return $message_time . $msg['tname'] . ": " . $msg['tmessage'] . "\n"; | ||||
| 		else | ||||
| 			return $message_time . $msg['tmessage'] . "\n"; | ||||
| 	} else if ($msg['ikind'] == $kind_info) { | ||||
| 	} else if ($msg['ikind'] == Thread::KIND_INFO) { | ||||
| 		return $message_time . $msg['tmessage'] . "\n"; | ||||
| 	} else { | ||||
| 		return $message_time . "[" . $msg['tmessage'] . "]\n"; | ||||
| @ -132,14 +73,14 @@ function message_to_text($msg) | ||||
| 
 | ||||
| function get_messages($threadid, $meth, $isuser, &$lastid) | ||||
| { | ||||
| 	global $kind_for_agent, $kind_avatar, $webim_encoding; | ||||
| 	global $webim_encoding; | ||||
| 	$db = Database::getInstance(); | ||||
| 
 | ||||
| 	$msgs = $db->query( | ||||
| 		"select messageid,ikind,dtmcreated as created,tname,tmessage from {chatmessage} " . | ||||
| 		"where threadid = :threadid and messageid > :lastid " . | ||||
| 		($isuser ? "and ikind <> {$kind_for_agent} " : "") . | ||||
| 		"order by messageid", | ||||
| 		($isuser ? "and ikind <> ". Thread::KIND_FOR_AGENT : "") . | ||||
| 		" order by messageid", | ||||
| 		array( | ||||
| 			':threadid' => $threadid, | ||||
| 			':lastid' => $lastid, | ||||
| @ -153,14 +94,14 @@ function get_messages($threadid, $meth, $isuser, &$lastid) | ||||
| 		$message = ""; | ||||
| 		if ($meth == 'xml') { | ||||
| 			switch ($msg['ikind']) { | ||||
| 				case $kind_avatar: | ||||
| 				case Thread::KIND_AVATAR: | ||||
| 					$message = "<avatar>" . myiconv($webim_encoding, "utf-8", escape_with_cdata($msg['tmessage'])) . "</avatar>"; | ||||
| 					break; | ||||
| 				default: | ||||
| 					$message = "<message>" . myiconv($webim_encoding, "utf-8", escape_with_cdata(message_to_html($msg))) . "</message>\n"; | ||||
| 			} | ||||
| 		} else { | ||||
| 			if ($msg['ikind'] != $kind_avatar) { | ||||
| 			if ($msg['ikind'] != Thread::KIND_AVATAR) { | ||||
| 				$message = (($meth == 'text') ? message_to_text($msg) : topage(message_to_html($msg))); | ||||
| 			} | ||||
| 		} | ||||
| @ -176,16 +117,16 @@ function get_messages($threadid, $meth, $isuser, &$lastid) | ||||
| 
 | ||||
| function print_thread_messages($thread, $token, $lastid, $isuser, $format, $agentid = null) | ||||
| { | ||||
| 	global $webim_encoding, $webimroot, $connection_timeout; | ||||
| 	$threadid = $thread['threadid']; | ||||
| 	$istyping = abs(time() - $thread[$isuser ? "lpagent" : "lpuser"]) < $connection_timeout | ||||
| 				&& $thread[$isuser ? "agentTyping" : "userTyping"] == "1" ? "1" : "0"; | ||||
| 	global $webim_encoding, $webimroot; | ||||
| 	$threadid = $thread->id; | ||||
| 	$istyping = abs(time() - $isuser ? $thread->lastPingAgent : $thread->lastPingUser) < Thread::CONNECTION_TIMEOUT | ||||
| 				&& (($isuser ? $thread->agentTyping : $thread->userTyping) == "1") ? "1" : "0"; | ||||
| 
 | ||||
| 	if ($format == "xml") { | ||||
| 		$output = get_messages($threadid, "xml", $isuser, $lastid); | ||||
| 
 | ||||
| 		start_xml_output(); | ||||
| 		print("<thread lastid=\"$lastid\" typing=\"" . $istyping . "\" canpost=\"" . (($isuser || $agentid != null && $agentid == $thread['agentId']) ? 1 : 0) . "\">"); | ||||
| 		print("<thread lastid=\"$lastid\" typing=\"" . $istyping . "\" canpost=\"" . (($isuser || $agentid != null && $agentid == $thread->agentId) ? 1 : 0) . "\">"); | ||||
| 		foreach ($output as $msg) { | ||||
| 			print $msg; | ||||
| 		} | ||||
| @ -409,8 +350,8 @@ function setup_chatview_for_user($thread, $level) | ||||
| { | ||||
| 	global $page, $webimroot; | ||||
| 	$page = array(); | ||||
| 	if (! empty($thread['groupid'])) { | ||||
| 		$group = group_by_id($thread['groupid']); | ||||
| 	if (! empty($thread->groupId)) { | ||||
| 		$group = group_by_id($thread->groupId); | ||||
| 		$group = get_top_level_group($group); | ||||
| 	} else { | ||||
| 		$group = array(); | ||||
| @ -418,13 +359,13 @@ function setup_chatview_for_user($thread, $level) | ||||
| 	$page['agent'] = false; | ||||
| 	$page['user'] = true; | ||||
| 	$page['canpost'] = true; | ||||
| 	$nameisset = getstring("chat.default.username") != $thread['userName']; | ||||
| 	$nameisset = getstring("chat.default.username") != $thread->userName; | ||||
| 	$page['displ1'] = $nameisset ? "none" : "inline"; | ||||
| 	$page['displ2'] = $nameisset ? "inline" : "none"; | ||||
| 	$page['level'] = $level; | ||||
| 	$page['ct.chatThreadId'] = $thread['threadid']; | ||||
| 	$page['ct.token'] = $thread['ltoken']; | ||||
| 	$page['ct.user.name'] = htmlspecialchars(topage($thread['userName'])); | ||||
| 	$page['ct.chatThreadId'] = $thread->id; | ||||
| 	$page['ct.token'] = $thread->lastToken; | ||||
| 	$page['ct.user.name'] = htmlspecialchars(topage($thread->userName)); | ||||
| 	$page['canChangeName'] = Settings::get('usercanchangename') == "1"; | ||||
| 	$page['chat.title'] = topage(empty($group['vcchattitle'])?Settings::get('chattitle'):$group['vcchattitle']); | ||||
| 	$page['chat.close.confirmation'] = getlocal('chat.close.confirmation'); | ||||
| @ -438,7 +379,7 @@ function setup_chatview_for_user($thread, $level) | ||||
| 		$page['ignorectrl'] = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	$params = "thread=" . $thread['threadid'] . "&token=" . $thread['ltoken']; | ||||
| 	$params = "thread=" . $thread->id . "&token=" . $thread->lastToken; | ||||
| 	$page['mailLink'] = "$webimroot/client.php?" . $params . "&level=$level&act=mailthread"; | ||||
| 
 | ||||
| 	if (Settings::get('enablessl') == "1" && !is_secure_request()) { | ||||
| @ -455,18 +396,18 @@ function setup_chatview_for_operator($thread, $operator) | ||||
| { | ||||
| 	global $page, $webimroot, $company_logo_link, $webim_encoding, $company_name; | ||||
| 	$page = array(); | ||||
| 	if (! is_null($thread['groupid'])) { | ||||
| 		$group = group_by_id($thread['groupid']); | ||||
| 	if (! is_null($thread->groupId)) { | ||||
| 		$group = group_by_id($thread->groupId); | ||||
| 		$group = get_top_level_group($group); | ||||
| 	} else { | ||||
| 		$group = array(); | ||||
| 	} | ||||
| 	$page['agent'] = true; | ||||
| 	$page['user'] = false; | ||||
| 	$page['canpost'] = $thread['agentId'] == $operator['operatorid']; | ||||
| 	$page['ct.chatThreadId'] = $thread['threadid']; | ||||
| 	$page['ct.token'] = $thread['ltoken']; | ||||
| 	$page['ct.user.name'] = htmlspecialchars(topage(get_user_name($thread['userName'], $thread['remote'], $thread['userid']))); | ||||
| 	$page['canpost'] = $thread->agentId == $operator['operatorid']; | ||||
| 	$page['ct.chatThreadId'] = $thread->id; | ||||
| 	$page['ct.token'] = $thread->lastToken; | ||||
| 	$page['ct.user.name'] = htmlspecialchars(topage(get_user_name($thread->userName, $thread->remote, $thread->userId))); | ||||
| 	$page['chat.title'] = topage(empty($group['vcchattitle'])?Settings::get('chattitle'):$group['vcchattitle']); | ||||
| 	$page['chat.close.confirmation'] = getlocal('chat.close.confirmation'); | ||||
| 
 | ||||
| @ -480,22 +421,22 @@ function setup_chatview_for_operator($thread, $operator) | ||||
| 	} | ||||
| 
 | ||||
| 	if (Settings::get('enablessl') == "1" && !is_secure_request()) { | ||||
| 		$page['sslLink'] = get_app_location(true, true) . "/operator/agent.php?thread=" . $thread['threadid'] . "&token=" . $thread['ltoken']; | ||||
| 		$page['sslLink'] = get_app_location(true, true) . "/operator/agent.php?thread=" . $thread->id . "&token=" . $thread->lastToken; | ||||
| 	} | ||||
| 	$page['isOpera95'] = is_agent_opera95(); | ||||
| 	$page['neediframesrc'] = needsFramesrc(); | ||||
| 	$page['historyParams'] = array("userid" => "" . $thread['userid']); | ||||
| 	$page['historyParams'] = array("userid" => "" . $thread->userId); | ||||
| 	$page['historyParamsLink'] = add_params($webimroot . "/operator/userhistory.php", $page['historyParams']); | ||||
| 	if (Settings::get('enabletracking')) { | ||||
| 	    $visitor = track_get_visitor_by_threadid($thread['threadid']); | ||||
| 	    $visitor = track_get_visitor_by_threadid($thread->id); | ||||
| 	    $page['trackedParams'] = array("visitor" => "" . $visitor['visitorid']); | ||||
| 	    $page['trackedParamsLink'] = add_params($webimroot . "/operator/tracked.php", $page['trackedParams']); | ||||
| 	} | ||||
| 	$predefinedres = ""; | ||||
| 	$canned_messages = load_canned_messages($thread['locale'], 0); | ||||
| 	if ($thread['groupid']) { | ||||
| 	$canned_messages = load_canned_messages($thread->locale, 0); | ||||
| 	if ($thread->groupId) { | ||||
| 		$canned_messages = array_merge( | ||||
| 			load_canned_messages($thread['locale'], $thread['groupid']), | ||||
| 			load_canned_messages($thread->locale, $thread->groupId), | ||||
| 			$canned_messages | ||||
| 		); | ||||
| 	}; | ||||
| @ -505,191 +446,13 @@ function setup_chatview_for_operator($thread, $operator) | ||||
| 	} | ||||
| 	$page['predefinedAnswers'] = $predefinedres; | ||||
| 	$page['fullPredefinedAnswers'] = json_encode($fullAnswers); | ||||
| 	$params = "thread=" . $thread['threadid'] . "&token=" . $thread['ltoken']; | ||||
| 	$params = "thread=" . $thread->id . "&token=" . $thread->lastToken; | ||||
| 	$page['redirectLink'] = "$webimroot/operator/agent.php?" . $params . "&act=redirect"; | ||||
| 
 | ||||
| 	$page['namePostfix'] = ""; | ||||
| 	$page['frequency'] = Settings::get('updatefrequency_chat'); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Pings the chat thread. Updates 'lastpinguser' (or 'lastpingagent') to current timestamp.  | ||||
|  * Sends system messages when operator or user was seen more than $connection_timeout seconds ago | ||||
|  * | ||||
|  * @global int $kind_for_agent | ||||
|  * @global int $state_queue | ||||
|  * @global int $state_loading | ||||
|  * @global int $state_chatting | ||||
|  * @global int $state_waiting | ||||
|  * @global int $kind_conn | ||||
|  * @global int $connection_timeout | ||||
|  * @param array $thread Thread's array | ||||
|  * @param boolean $isuser true for user and false for operator | ||||
|  * @param boolean $istyping true if user (or agent) is typing | ||||
|  */ | ||||
| function ping_thread($thread, $isuser, $istyping) | ||||
| { | ||||
| 	global $kind_for_agent, $state_queue, $state_loading, $state_chatting, $state_waiting, $kind_conn, $connection_timeout; | ||||
| 
 | ||||
| 	$db = Database::getInstance(); | ||||
| 
 | ||||
| 	$params = array(($isuser ? "lastpinguser" : "lastpingagent") => time(), | ||||
| 					($isuser ? "userTyping" : "agentTyping") => ($istyping ? "1" : "0")); | ||||
| 
 | ||||
| 	$lastping = $thread[$isuser ? "lpagent" : "lpuser"]; | ||||
| 
 | ||||
| 	if ($thread['istate'] == $state_loading && $isuser) { | ||||
| 		$params['istate'] = $state_queue; | ||||
| 		commit_thread($thread['threadid'], $params); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if ($lastping > 0 && abs(time() - $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, null, $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, null, $lastping + $connection_timeout); | ||||
| 			$params['istate'] = $state_waiting; | ||||
| 			$params['nextagent'] = 0; | ||||
| 			commit_thread($thread['threadid'], $params); | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	$clause = ""; | ||||
| 	$values = array(); | ||||
| 	foreach ($params as $k => $v) { | ||||
| 		if (strlen($clause) > 0) { | ||||
| 			$clause .= ", "; | ||||
| 		} | ||||
| 		$clause .= $k . "=?"; | ||||
| 		$values[] = $v; | ||||
| 	} | ||||
| 	$values[] = $thread['threadid']; | ||||
| 
 | ||||
| 	$db->query( | ||||
| 		"update {chatthread} set {$clause} where threadid = ?", | ||||
| 		$values | ||||
| 	); | ||||
| } | ||||
| 
 | ||||
| function commit_thread($threadid, $params) | ||||
| { | ||||
| 	$db = Database::getInstance(); | ||||
| 
 | ||||
| 	$query = "update {chatthread} t " . | ||||
| 		"set lrevision = ?, dtmmodified = ?"; | ||||
| 
 | ||||
| 	$values = array(); | ||||
| 	$values[] = next_revision(); | ||||
| 	$values[] = time(); | ||||
| 
 | ||||
| 	foreach ($params as $name => $value) { | ||||
| 		$query .= ", {$name} = ?" ; | ||||
| 		$values[] = $value; | ||||
| 	} | ||||
| 
 | ||||
| 	$query .= " where threadid = ?"; | ||||
| 	$values[] = $threadid; | ||||
| 
 | ||||
| 	$db->query($query, $values); | ||||
| } | ||||
| 
 | ||||
| function rename_user($thread, $newname) | ||||
| { | ||||
| 	global $kind_events; | ||||
| 
 | ||||
| 	commit_thread($thread['threadid'], array('userName' => $newname)); | ||||
| 
 | ||||
| 	if ($thread['userName'] != $newname) { | ||||
| 		post_message_($thread['threadid'], $kind_events, | ||||
| 					  getstring2_("chat.status.user.changedname", array($thread['userName'], $newname), $thread['locale'])); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function close_thread($thread, $isuser) | ||||
| { | ||||
| 	global $state_closed, $kind_events; | ||||
| 
 | ||||
| 	$db = Database::getInstance(); | ||||
| 	list($message_count) = $db->query( | ||||
| 		"SELECT COUNT(*) FROM {chatmessage} WHERE {chatmessage}.threadid = ? AND ikind = 1", | ||||
| 		array($thread['threadid']), | ||||
| 		array( | ||||
| 			'return_rows' => Database::RETURN_ONE_ROW, | ||||
| 			'fetch_type' => Database::FETCH_NUM | ||||
| 		) | ||||
| 	); | ||||
| 	if ($thread['istate'] != $state_closed) { | ||||
| 		commit_thread( | ||||
| 			$thread['threadid'], | ||||
| 			array( | ||||
| 				'istate' => $state_closed, | ||||
| 				'messageCount' => $message_count | ||||
| 			) | ||||
| 		); | ||||
| 	} | ||||
| 
 | ||||
| 	$message = $isuser ? getstring2_("chat.status.user.left", array($thread['userName']), $thread['locale']) | ||||
| 			: getstring2_("chat.status.operator.left", array($thread['agentName']), $thread['locale']); | ||||
| 	post_message_($thread['threadid'], $kind_events, $message); | ||||
| } | ||||
| 
 | ||||
| function close_old_threads() | ||||
| { | ||||
| 	global $state_closed, $state_left, $state_chatting; | ||||
| 	if (Settings::get('thread_lifetime') == 0) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	$db = Database::getInstance(); | ||||
| 
 | ||||
| 	$query = "update {chatthread} set lrevision = :next_revision, " . | ||||
| 		"dtmmodified = :now, istate = :state_closed " . | ||||
| 		"where istate <> :state_closed and istate <> :state_left " . | ||||
| 		"and ((lastpingagent <> 0 and lastpinguser <> 0 and " . | ||||
| 		"(ABS(:now - lastpinguser) > ". | ||||
| 		":thread_lifetime and " . | ||||
| 		"ABS(:now - lastpingagent) > ". | ||||
| 		":thread_lifetime)) or " . | ||||
| 		"lastpingagent = 0 and lastpinguser <> 0 and " . | ||||
| 		"ABS(:now - lastpinguser) > ". | ||||
| 		":thread_lifetime)"; | ||||
| 
 | ||||
| 	$db->query( | ||||
| 		$query, | ||||
| 		array( | ||||
| 			':next_revision' => next_revision(), | ||||
| 			':now' => time(), | ||||
| 			':state_closed' => $state_closed, | ||||
| 			':state_left' => $state_left, | ||||
| 			':thread_lifetime' => Settings::get('thread_lifetime') | ||||
| 		) | ||||
| 	); | ||||
| } | ||||
| 
 | ||||
| function thread_by_id($id) | ||||
| { | ||||
| 	$db = Database::getInstance(); | ||||
| 	return $db->query( | ||||
| 		"select threadid,userName,agentName,agentId,lrevision,istate,ltoken,userTyping, " . | ||||
| 		"agentTyping,dtmmodified as modified, " . | ||||
| 		"dtmcreated as created, " . | ||||
| 		"dtmchatstarted as chatstarted,remote,referer,locale," . | ||||
| 		"lastpinguser as lpuser,lastpingagent as lpagent," . | ||||
| 		"nextagent,shownmessageid,userid, " . | ||||
| 		"userAgent,groupid from {chatthread} where threadid = :threadid", | ||||
| 		array( | ||||
| 			':threadid' => $id | ||||
| 		), | ||||
| 		array('return_rows' => Database::RETURN_ONE_ROW) | ||||
| 	); | ||||
| } | ||||
| 
 | ||||
| function ban_for_addr($addr) | ||||
| { | ||||
| 	$db = Database::getInstance(); | ||||
| @ -704,181 +467,6 @@ function ban_for_addr($addr) | ||||
| 	); | ||||
| } | ||||
| 
 | ||||
| function create_thread($groupid, $username, $remoteHost, $referer, $lang, $userid, $userbrowser, $initialState) | ||||
| { | ||||
| 	$db = Database::getInstance(); | ||||
| 
 | ||||
| 	$query = "insert into {chatthread} (" . | ||||
| 			"userName, " . | ||||
| 			"userid, " . | ||||
| 			"ltoken, " . | ||||
| 			"remote, " . | ||||
| 			"referer, " . | ||||
| 			"lrevision, " . | ||||
| 			"locale, " . | ||||
| 			"userAgent, " . | ||||
| 			"dtmcreated, " . | ||||
| 			"dtmmodified, " . | ||||
| 			"istate" . | ||||
| 			($groupid ? ", groupid" : "") . | ||||
| 		") values (" . | ||||
| 			":username, " . | ||||
| 			":userid, " . | ||||
| 			":ltoken, " . | ||||
| 			":remote," . | ||||
| 			":referer, " . | ||||
| 			":lrevision, " . | ||||
| 			":locale, " . | ||||
| 			":useragent, " . | ||||
| 			":now, " . | ||||
| 			":now, " . | ||||
| 			":istate" . | ||||
| 			($groupid ? ", :groupid" : "") . | ||||
| 		")"; | ||||
| 
 | ||||
| 	$values = array( | ||||
| 		':username' => $username, | ||||
| 		':userid' => $userid, | ||||
| 		':ltoken' => next_token(), | ||||
| 		':remote' => $remoteHost, | ||||
| 		':referer' => $referer, | ||||
| 		':lrevision' => next_revision(), | ||||
| 		':locale' => $lang, | ||||
| 		':useragent' => $userbrowser, | ||||
| 		':now' => time(), | ||||
| 		':istate' => $initialState | ||||
| 	); | ||||
| 
 | ||||
| 	if ($groupid) { | ||||
| 		$values[':groupid'] = $groupid; | ||||
| 	} | ||||
| 
 | ||||
| 	$db->query($query, $values); | ||||
| 	$id = $db->insertedId(); | ||||
| 
 | ||||
| 	$newthread = thread_by_id($id); | ||||
| 	return $newthread; | ||||
| } | ||||
| 
 | ||||
| function do_take_thread($threadid, $operatorId, $operatorName, $chatstart = false) | ||||
| { | ||||
| 	global $state_chatting; | ||||
| 	$params = array("istate" => $state_chatting, | ||||
| 			"nextagent" => 0, | ||||
| 			"agentId" => $operatorId, | ||||
| 			"agentName" => $operatorName); | ||||
| 	if ($chatstart){ | ||||
| 		$params['dtmchatstarted'] = time(); | ||||
| 	} | ||||
| 	commit_thread($threadid, $params); | ||||
| } | ||||
| 
 | ||||
| function reopen_thread($threadid) | ||||
| { | ||||
| 	global $state_queue, $state_loading, $state_waiting, $state_chatting, $state_closed, $state_left, $kind_events; | ||||
| 
 | ||||
| 	$thread = thread_by_id($threadid); | ||||
| 
 | ||||
| 	if (!$thread) | ||||
| 		return FALSE; | ||||
| 
 | ||||
| 	if (Settings::get('thread_lifetime') != 0 && abs($thread['lpuser'] - time()) > Settings::get('thread_lifetime') && abs($thread['lpagent'] - time()) > Settings::get('thread_lifetime')) { | ||||
| 		return FALSE; | ||||
| 	} | ||||
| 
 | ||||
| 	if ($thread['istate'] == $state_closed || $thread['istate'] == $state_left) | ||||
| 		return FALSE; | ||||
| 
 | ||||
| 	if ($thread['istate'] != $state_chatting && $thread['istate'] != $state_queue && $thread['istate'] != $state_loading) { | ||||
| 		commit_thread( | ||||
| 			$threadid, | ||||
| 			array("istate" => $state_waiting, "nextagent" => 0) | ||||
| 		); | ||||
| 	} | ||||
| 
 | ||||
| 	post_message_($thread['threadid'], $kind_events, getstring_("chat.status.user.reopenedthread", $thread['locale'])); | ||||
| 	return $thread; | ||||
| } | ||||
| 
 | ||||
| function take_thread($thread, $operator) | ||||
| { | ||||
| 	global $state_queue, $state_loading, $state_waiting, $state_chatting, $kind_events, $kind_avatar, $home_locale; | ||||
| 
 | ||||
| 	$state = $thread['istate']; | ||||
| 	$threadid = $thread['threadid']; | ||||
| 	$message_to_post = ""; | ||||
| 	$chatstart = $thread['chatstarted'] == 0; | ||||
| 
 | ||||
| 	$operatorName = ($thread['locale'] == $home_locale) ? $operator['vclocalename'] : $operator['vccommonname']; | ||||
| 
 | ||||
| 	if ($state == $state_queue || $state == $state_waiting || $state == $state_loading) { | ||||
| 		do_take_thread($threadid, $operator['operatorid'], $operatorName, $chatstart); | ||||
| 
 | ||||
| 		if ($state == $state_waiting) { | ||||
| 			if ($operatorName != $thread['agentName']) { | ||||
| 				$message_to_post = getstring2_("chat.status.operator.changed", array($operatorName, $thread['agentName']), $thread['locale']); | ||||
| 			} else { | ||||
| 				$message_to_post = getstring2_("chat.status.operator.returned", array($operatorName), $thread['locale']); | ||||
| 			} | ||||
| 		} else { | ||||
| 			$message_to_post = getstring2_("chat.status.operator.joined", array($operatorName), $thread['locale']); | ||||
| 		} | ||||
| 	} else if ($state == $state_chatting) { | ||||
| 		if ($operator['operatorid'] != $thread['agentId']) { | ||||
| 			do_take_thread($threadid, $operator['operatorid'], $operatorName, $chatstart); | ||||
| 			$message_to_post = getstring2_("chat.status.operator.changed", array($operatorName, $thread['agentName']), $thread['locale']); | ||||
| 		} | ||||
| 	} else { | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	if ($message_to_post) { | ||||
| 		post_message($threadid, $kind_events, $message_to_post); | ||||
| 		post_message($threadid, $kind_avatar, $operator['vcavatar'] ? $operator['vcavatar'] : ""); | ||||
| 	} | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| function check_for_reassign($thread, $operator) | ||||
| { | ||||
| 	global $state_waiting, $home_locale, $kind_events, $kind_avatar; | ||||
| 	$operatorName = ($thread['locale'] == $home_locale) ? $operator['vclocalename'] : $operator['vccommonname']; | ||||
| 	if ($thread['istate'] == $state_waiting && | ||||
| 		($thread['nextagent'] == $operator['operatorid'] | ||||
| 		 || $thread['agentId'] == $operator['operatorid'])) { | ||||
| 		do_take_thread($thread['threadid'], $operator['operatorid'], $operatorName); | ||||
| 		if ($operatorName != $thread['agentName']) { | ||||
| 			$message_to_post = getstring2_("chat.status.operator.changed", array($operatorName, $thread['agentName']), $thread['locale']); | ||||
| 		} else { | ||||
| 			$message_to_post = getstring2_("chat.status.operator.returned", array($operatorName), $thread['locale']); | ||||
| 		} | ||||
| 
 | ||||
| 		post_message($thread['threadid'], $kind_events, $message_to_post); | ||||
| 		post_message($thread['threadid'], $kind_avatar, $operator['vcavatar'] ? $operator['vcavatar'] : ""); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function check_connections_from_remote($remote) | ||||
| { | ||||
| 	global $state_closed, $state_left; | ||||
| 	if (Settings::get('max_connections_from_one_host') == 0) { | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	$db = Database::getInstance(); | ||||
| 	$result = $db->query( | ||||
| 		"select count(*) as opened from {chatthread} " . | ||||
| 		"where remote = ? AND istate <> ? AND istate <> ?", | ||||
| 		array($remote, $state_closed, $state_left), | ||||
| 		array('return_rows' => Database::RETURN_ONE_ROW) | ||||
| 	); | ||||
| 
 | ||||
| 	if ($result && isset($result['opened'])) { | ||||
| 		return $result['opened'] < Settings::get('max_connections_from_one_host'); | ||||
| 	} | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| function visitor_from_request() | ||||
| { | ||||
| 	global $namecookie, $webim_encoding, $usercookie; | ||||
|  | ||||
| @ -27,7 +27,7 @@ function demo_print_message($msg, $format) | ||||
| 
 | ||||
| function demo_process_thread($act, $outformat, $lastid, $isuser, $canpost, $istyping, $postmessage) | ||||
| { | ||||
| 	global $kind_for_agent, $kind_info, $kind_events, $kind_user, $kind_agent, $webimroot; | ||||
| 	global $webimroot; | ||||
| 	if ($act == "refresh" || $act == "post") { | ||||
| 		$lastid++; | ||||
| 		if ($outformat == "xml") { | ||||
| @ -51,29 +51,29 @@ function demo_process_thread($act, $outformat, $lastid, $isuser, $canpost, $isty | ||||
| 		} | ||||
| 		if ($lastid == 1) { | ||||
| 			demo_print_message( | ||||
| 				array('ikind' => $kind_for_agent, 'created' => time() - 15, 'tname' => '', | ||||
| 				array('ikind' => Thread::KIND_FOR_AGENT, 'created' => time() - 15, 'tname' => '', | ||||
| 					 'tmessage' => getstring2('chat.came.from', array("http://google.com"))), $outformat); | ||||
| 			demo_print_message( | ||||
| 				array('ikind' => $kind_info, 'created' => time() - 15, 'tname' => '', | ||||
| 				array('ikind' => Thread::KIND_INFO, 'created' => time() - 15, 'tname' => '', | ||||
| 					 'tmessage' => getstring('chat.wait')), $outformat); | ||||
| 			demo_print_message( | ||||
| 				array('ikind' => $kind_events, 'created' => time() - 10, 'tname' => '', | ||||
| 				array('ikind' => Thread::KIND_EVENTS, 'created' => time() - 10, 'tname' => '', | ||||
| 					 'tmessage' => getstring2("chat.status.operator.joined", array("Administrator"))), $outformat); | ||||
| 			demo_print_message( | ||||
| 				array('ikind' => $kind_agent, 'created' => time() - 9, 'tname' => 'Administrator', | ||||
| 				array('ikind' => Thread::KIND_AGENT, 'created' => time() - 9, 'tname' => 'Administrator', | ||||
| 					 'tmessage' => getstring("demo.chat.welcome")), $outformat); | ||||
| 			demo_print_message( | ||||
| 				array('ikind' => $kind_user, 'created' => time() - 5, 'tname' => getstring("chat.default.username"), | ||||
| 				array('ikind' => Thread::KIND_USER, 'created' => time() - 5, 'tname' => getstring("chat.default.username"), | ||||
| 					 'tmessage' => getstring("demo.chat.question")), $outformat); | ||||
| 			if ($canpost && $outformat == 'xml') { | ||||
| 				demo_print_message( | ||||
| 					array('ikind' => $kind_info, 'created' => time() - 5, 'tname' => '', | ||||
| 					array('ikind' => Thread::KIND_INFO, 'created' => time() - 5, 'tname' => '', | ||||
| 						 'tmessage' => 'Hint: type something in message field to see typing notification'), $outformat); | ||||
| 			} | ||||
| 		} | ||||
| 		if ($act == 'post') { | ||||
| 			demo_print_message( | ||||
| 				array('ikind' => $isuser ? $kind_user : $kind_agent, 'created' => time(), 'tmessage' => $postmessage, | ||||
| 				array('ikind' => $isuser ? Thread::KIND_USER : Thread::KIND_AGENT, 'created' => time(), 'tmessage' => $postmessage, | ||||
| 					 'tname' => $isuser ? getstring("chat.default.username") : "Administrator"), $outformat); | ||||
| 		} | ||||
| 		if ($outformat == "xml") { | ||||
|  | ||||
| @ -20,6 +20,7 @@ require_once('libs/chat.php'); | ||||
| require_once('libs/expand.php'); | ||||
| require_once('libs/groups.php'); | ||||
| require_once('libs/notify.php'); | ||||
| require_once('libs/classes/thread.php'); | ||||
| 
 | ||||
| $errors = array(); | ||||
| $page = array(); | ||||
| @ -27,14 +28,14 @@ $page = array(); | ||||
| $token = verifyparam( "token", "/^\d{1,8}$/"); | ||||
| $threadid = verifyparam( "thread", "/^\d{1,8}$/"); | ||||
| 
 | ||||
| $thread = thread_by_id($threadid); | ||||
| if( !$thread || !isset($thread['ltoken']) || $token != $thread['ltoken'] ) { | ||||
| $thread = Thread::load($threadid, $token); | ||||
| if (! $thread) { | ||||
| 	die("wrong thread"); | ||||
| } | ||||
| 
 | ||||
| $email = getparam('email'); | ||||
| $page['email'] = $email; | ||||
| $group = is_null($thread['groupid'])?NULL:group_by_id($thread['groupid']); | ||||
| $group = is_null($thread->groupId)?NULL:group_by_id($thread->groupId); | ||||
| if( !$email ) { | ||||
| 	$errors[] = no_field("form.field.email"); | ||||
| } else if( !is_valid_email($email)) { | ||||
| @ -43,8 +44,8 @@ if( !$email ) { | ||||
| 
 | ||||
| if( count($errors) > 0 ) { | ||||
| 	$page['formemail'] = $email; | ||||
| 	$page['ct.chatThreadId'] = $thread['threadid']; | ||||
| 	$page['ct.token'] = $thread['ltoken']; | ||||
| 	$page['ct.chatThreadId'] = $thread->id; | ||||
| 	$page['ct.token'] = $thread->lastToken; | ||||
| 	$page['level'] = ""; | ||||
| 	setup_logo($group); | ||||
| 	expand("styles/dialogs", getchatstyle(), "mail.tpl"); | ||||
| @ -59,7 +60,10 @@ foreach( $output as $msg ) { | ||||
| } | ||||
| 
 | ||||
| $subject = getstring("mail.user.history.subject"); | ||||
| $body = getstring2("mail.user.history.body", array($thread['userName'],$history,Settings::get('title'),Settings::get('hosturl')) ); | ||||
| $body = getstring2( | ||||
| 	"mail.user.history.body", | ||||
| 	array($thread->userName, $history, Settings::get('title'), Settings::get('hosturl')) | ||||
| ); | ||||
| 
 | ||||
| webim_mail($email, $webim_mailbox, $subject, $body); | ||||
| 
 | ||||
|  | ||||
| @ -22,6 +22,7 @@ require_once('../libs/groups.php'); | ||||
| require_once('../libs/operator.php'); | ||||
| require_once('../libs/pagination.php'); | ||||
| require_once('../libs/expand.php'); | ||||
| require_once('../libs/classes/thread.php'); | ||||
| 
 | ||||
| $operator = check_login(); | ||||
| 
 | ||||
| @ -49,8 +50,8 @@ if (!isset($_GET['token'])) { | ||||
| 		exit; | ||||
| 	} | ||||
| 
 | ||||
| 	$thread = thread_by_id($threadid); | ||||
| 	if (!$thread || !isset($thread['ltoken'])) { | ||||
| 	$thread = Thread::load($threadid); | ||||
| 	if (!$thread || !isset($thread->lastToken)) { | ||||
| 		$errors = array(getlocal("thread.error.wrong_thread")); | ||||
| 		start_html_output(); | ||||
| 		expand("../styles/dialogs", getchatstyle(), "error.tpl"); | ||||
| @ -60,7 +61,7 @@ if (!isset($_GET['token'])) { | ||||
| 	$viewonly = verifyparam("viewonly", "/^true$/", false); | ||||
| 
 | ||||
| 	$forcetake = verifyparam("force", "/^true$/", false); | ||||
| 	if (!$viewonly && $thread['istate'] == $state_chatting && $operator['operatorid'] != $thread['agentId']) { | ||||
| 	if (!$viewonly && $thread->state == Thread::STATE_CHATTING && $operator['operatorid'] != $thread->agentId) { | ||||
| 
 | ||||
| 		if (!is_capable($can_takeover, $operator)) { | ||||
| 			$errors = array(getlocal("thread.error.cannot_take_over")); | ||||
| @ -71,7 +72,9 @@ if (!isset($_GET['token'])) { | ||||
| 
 | ||||
| 		if ($forcetake == false) { | ||||
| 			$page = array( | ||||
| 				'user' => topage($thread['userName']), 'agent' => topage($thread['agentName']), 'link' => $_SERVER['PHP_SELF'] . "?thread=$threadid&force=true" | ||||
| 				'user' => topage($thread->userName), | ||||
| 				'agent' => topage($thread->agentName), | ||||
| 				'link' => $_SERVER['PHP_SELF'] . "?thread=$threadid&force=true" | ||||
| 			); | ||||
| 			start_html_output(); | ||||
| 			require('../view/confirm.php'); | ||||
| @ -80,7 +83,7 @@ if (!isset($_GET['token'])) { | ||||
| 	} | ||||
| 
 | ||||
| 	if (!$viewonly) { | ||||
| 		if(! take_thread($thread, $operator)){ | ||||
| 		if(! $thread->take($operator)){ | ||||
| 			$errors = array(getlocal("thread.error.cannot_take")); | ||||
| 			start_html_output(); | ||||
| 			expand("../styles/dialogs", getchatstyle(), "error.tpl"); | ||||
| @ -93,19 +96,19 @@ if (!isset($_GET['token'])) { | ||||
| 		exit; | ||||
| 	} | ||||
| 
 | ||||
| 	$token = $thread['ltoken']; | ||||
| 	$token = $thread->lastToken; | ||||
| 	header("Location: $webimroot/operator/agent.php?thread=$threadid&token=$token&level=$remote_level"); | ||||
| 	exit; | ||||
| } | ||||
| 
 | ||||
| $token = verifyparam("token", "/^\d{1,8}$/"); | ||||
| 
 | ||||
| $thread = thread_by_id($threadid); | ||||
| if (!$thread || !isset($thread['ltoken']) || $token != $thread['ltoken']) { | ||||
| $thread = Thread::load($threadid, $token); | ||||
| if (!$thread) { | ||||
| 	die("wrong thread"); | ||||
| } | ||||
| 
 | ||||
| if ($thread['agentId'] != $operator['operatorid'] && !is_capable($can_viewthreads, $operator)) { | ||||
| if ($thread->agentId != $operator['operatorid'] && !is_capable($can_viewthreads, $operator)) { | ||||
| 	$errors = array("Cannot view threads"); | ||||
| 	start_html_output(); | ||||
| 	expand("../styles/dialogs", getchatstyle(), "error.tpl"); | ||||
|  | ||||
| @ -19,6 +19,7 @@ require_once('../libs/init.php'); | ||||
| require_once('../libs/chat.php'); | ||||
| require_once('../libs/operator.php'); | ||||
| require_once('../libs/pagination.php'); | ||||
| require_once('../libs/classes/thread.php'); | ||||
| 
 | ||||
| $operator = check_login(); | ||||
| $page = array('banId' => ''); | ||||
| @ -118,11 +119,11 @@ if (isset($_POST['address'])) { | ||||
| 	} | ||||
| } else if (isset($_GET['thread'])) { | ||||
| 	$threadid = verifyparam('thread', "/^\d{1,9}$/"); | ||||
| 	$thread = thread_by_id($threadid); | ||||
| 	$thread = Thread::load($threadid); | ||||
| 	if ($thread) { | ||||
| 		$page['thread'] = topage($thread['userName']); | ||||
| 		$page['thread'] = topage($thread->userName); | ||||
| 		$page['threadid'] = $threadid; | ||||
| 		$page['formaddress'] = topage($thread['remote']); | ||||
| 		$page['formaddress'] = topage($thread->remote); | ||||
| 		$page['formdays'] = 15; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -58,8 +58,8 @@ if ($query !== false) { | ||||
| 		$searchConditions[] = "({chatmessage}.tmessage LIKE :query" . | ||||
| 					($searchInSystemMessages?'':" AND ({chatmessage}.ikind = :kind_user OR {chatmessage}.ikind = :kind_agent)") . | ||||
| 					")"; | ||||
| 		$values[':kind_user'] = $kind_user; | ||||
| 		$values[':kind_agent'] = $kind_agent; | ||||
| 		$values[':kind_user'] = Thread::KIND_USER; | ||||
| 		$values[':kind_agent'] = Thread::KIND_AGENT; | ||||
| 	} | ||||
| 	if ($searchType == 'operator' || $searchType == 'all') { | ||||
| 		$searchConditions[] = "({chatthread}.agentName LIKE :query)"; | ||||
|  | ||||
| @ -20,14 +20,15 @@ require_once('../libs/operator.php'); | ||||
| require_once('../libs/chat.php'); | ||||
| require_once('../libs/expand.php'); | ||||
| require_once('../libs/groups.php'); | ||||
| require_once('../libs/classes/thread.php'); | ||||
| 
 | ||||
| $operator = check_login(); | ||||
| 
 | ||||
| $threadid = verifyparam("thread", "/^\d{1,8}$/"); | ||||
| $token = verifyparam("token", "/^\d{1,8}$/"); | ||||
| 
 | ||||
| $thread = thread_by_id($threadid); | ||||
| if (!$thread || !isset($thread['ltoken']) || $token != $thread['ltoken']) { | ||||
| $thread = Thread::load($threadid, $token); | ||||
| if (! $thread) { | ||||
| 	die("wrong thread"); | ||||
| } | ||||
| 
 | ||||
| @ -40,12 +41,21 @@ if (isset($_GET['nextGroup'])) { | ||||
| 
 | ||||
| 	if ($nextGroup) { | ||||
| 		$page['message'] = getlocal2("chat.redirected.group.content", array(topage(get_group_name($nextGroup)))); | ||||
| 		if ($thread['istate'] == $state_chatting) { | ||||
| 			commit_thread($threadid, | ||||
| 						  array("istate" => $state_waiting, "nextagent" => 0, "groupid" => $nextid, "agentId" => 0, "agentName" => "''")); | ||||
| 			post_message_($thread['threadid'], $kind_events, | ||||
| 						  getstring2_("chat.status.operator.redirect", | ||||
| 									  array(get_operator_name($operator)), $thread['locale'])); | ||||
| 		if ($thread->state == Thread::STATE_CHATTING) { | ||||
| 			$thread->state = Thread::STATE_WAITING; | ||||
| 			$thread->nextAgent = 0; | ||||
| 			$thread->groupId = $nextid; | ||||
| 			$thread->agentId = 0; | ||||
| 			$thread->agentName = "''"; | ||||
| 
 | ||||
| 			$thread->postMessage( | ||||
| 				Thread::KIND_EVENTS, | ||||
| 				getstring2_( | ||||
| 					"chat.status.operator.redirect", | ||||
| 					array(get_operator_name($operator)), | ||||
| 					$thread->locale | ||||
| 				) | ||||
| 			); | ||||
| 		} else { | ||||
| 			$errors[] = getlocal("chat.redirect.cannot"); | ||||
| 		} | ||||
| @ -59,27 +69,34 @@ if (isset($_GET['nextGroup'])) { | ||||
| 
 | ||||
| 	if ($nextOperator) { | ||||
| 		$page['message'] = getlocal2("chat.redirected.content", array(topage(get_operator_name($nextOperator)))); | ||||
| 		if ($thread['istate'] == $state_chatting) { | ||||
| 			$threadupdate = array("istate" => $state_waiting, "nextagent" => $nextid, "agentId" => 0); | ||||
| 			if ($thread['groupid'] != 0) { | ||||
| 		if ($thread->state == Thread::STATE_CHATTING) { | ||||
| 			$thread->state = Thread::STATE_WAITING; | ||||
| 			$thread->nextAgent = $nextid; | ||||
| 			$thread->agentId = 0; | ||||
| 			if ($thread->groupId != 0) { | ||||
| 				$db = Database::getInstance(); | ||||
| 				list($groups_count) = $db->query( | ||||
| 					"select count(*) AS count from {chatgroupoperator} " . | ||||
| 					"where operatorid = ? and groupid = ?", | ||||
| 					array($nextid, $thread['groupid']), | ||||
| 					array($nextid, $thread->groupId), | ||||
| 					array( | ||||
| 						'return_rows' => Database::RETURN_ONE_ROW,  | ||||
| 						'fetch_type' => Database::FETCH_NUM | ||||
| 					) | ||||
| 				); | ||||
| 				if ($groups_count === 0) { | ||||
| 					$threadupdate['groupid'] = 0; | ||||
| 					$thread->groupId = 0; | ||||
| 				} | ||||
| 			} | ||||
| 			commit_thread($threadid, $threadupdate); | ||||
| 			post_message_($thread['threadid'], $kind_events, | ||||
| 						  getstring2_("chat.status.operator.redirect", | ||||
| 									  array(get_operator_name($operator)), $thread['locale'])); | ||||
| 			$thread->save(); | ||||
| 			$thread->postMessage( | ||||
| 				Thread::KIND_EVENTS, | ||||
| 				getstring2_( | ||||
| 					"chat.status.operator.redirect", | ||||
| 					array(get_operator_name($operator)), | ||||
| 					$thread->locale | ||||
| 				) | ||||
| 			); | ||||
| 		} else { | ||||
| 			$errors[] = getlocal("chat.redirect.cannot"); | ||||
| 		} | ||||
|  | ||||
| @ -78,8 +78,8 @@ if ($statisticstype == 'bydate') { | ||||
| 		"from {chatmessage} m, {chatthread} t, (SELECT i.threadid, MAX(i.dtmcreated) AS lastmsgtime  FROM {chatmessage} i WHERE (ikind = :kind_user OR ikind = :kind_agent) GROUP BY i.threadid) tmp " . | ||||
| 		"where m.threadid = t.threadid AND tmp.threadid = t.threadid AND t.dtmchatstarted <> 0 AND m.dtmcreated >= :start AND m.dtmcreated < :end group by DATE(FROM_UNIXTIME(m.dtmcreated)) order by m.dtmcreated desc", | ||||
| 		array( | ||||
| 			':kind_agent' => $kind_agent, | ||||
| 			':kind_user' => $kind_user, | ||||
| 			':kind_agent' => Thread::KIND_AGENT, | ||||
| 			':kind_user' => Thread::KIND_USER, | ||||
| 			':start' => $start, | ||||
| 			':end' => $end | ||||
| 		), | ||||
| @ -91,8 +91,8 @@ if ($statisticstype == 'bydate') { | ||||
| 		"from {chatmessage} m, {chatthread} t, (SELECT i.threadid, MAX(i.dtmcreated) AS lastmsgtime FROM {chatmessage} i WHERE (ikind = :kind_user OR ikind = :kind_agent) GROUP BY i.threadid) tmp " . | ||||
| 		"where m.threadid = t.threadid AND tmp.threadid = t.threadid AND t.dtmchatstarted <> 0 AND m.dtmcreated >= :start AND m.dtmcreated < :end", | ||||
| 		array( | ||||
| 			':kind_agent' => $kind_agent, | ||||
| 			':kind_user' => $kind_user, | ||||
| 			':kind_agent' => Thread::KIND_AGENT, | ||||
| 			':kind_user' => Thread::KIND_USER, | ||||
| 			':start' => $start, | ||||
| 			':end' => $end | ||||
| 		), | ||||
| @ -107,7 +107,7 @@ if ($statisticstype == 'bydate') { | ||||
| 		"where agentId = operatorid AND dtmcreated >= :start " . | ||||
| 		"AND dtmcreated < :end group by operatorid", | ||||
| 		array( | ||||
| 			':kind_agent' => $kind_agent, | ||||
| 			':kind_agent' => Thread::KIND_AGENT, | ||||
| 			':start' => $start, | ||||
| 			':end' => $end | ||||
| 		), | ||||
|  | ||||
| @ -21,6 +21,7 @@ require_once('../libs/userinfo.php'); | ||||
| require_once('../libs/operator.php'); | ||||
| require_once('../libs/groups.php'); | ||||
| require_once('../libs/track.php'); | ||||
| require_once('../libs/classes/thread.php'); | ||||
| 
 | ||||
| $operator = get_logged_in(); | ||||
| if (!$operator) { | ||||
| @ -30,25 +31,25 @@ if (!$operator) { | ||||
| } | ||||
| 
 | ||||
| $threadstate_to_string = array( | ||||
| 	$state_queue => "wait", | ||||
| 	$state_waiting => "prio", | ||||
| 	$state_chatting => "chat", | ||||
| 	$state_closed => "closed", | ||||
| 	$state_loading => "wait", | ||||
| 	$state_left => "closed" | ||||
| 	Thread::STATE_QUEUE => "wait", | ||||
| 	Thread::STATE_WAITING => "prio", | ||||
| 	Thread::STATE_CHATTING => "chat", | ||||
| 	Thread::STATE_CLOSED => "closed", | ||||
| 	Thread::STATE_LOADING => "wait", | ||||
| 	Thread::STATE_LEFT => "closed" | ||||
| ); | ||||
| 
 | ||||
| $threadstate_key = array( | ||||
| 	$state_queue => "chat.thread.state_wait", | ||||
| 	$state_waiting => "chat.thread.state_wait_for_another_agent", | ||||
| 	$state_chatting => "chat.thread.state_chatting_with_agent", | ||||
| 	$state_closed => "chat.thread.state_closed", | ||||
| 	$state_loading => "chat.thread.state_loading" | ||||
| 	Thread::STATE_QUEUE => "chat.thread.state_wait", | ||||
| 	Thread::STATE_WAITING => "chat.thread.state_wait_for_another_agent", | ||||
| 	Thread::STATE_CHATTING => "chat.thread.state_chatting_with_agent", | ||||
| 	Thread::STATE_CLOSED => "chat.thread.state_closed", | ||||
| 	Thread::STATE_LOADING => "chat.thread.state_loading" | ||||
| ); | ||||
| 
 | ||||
| function thread_to_xml($thread) | ||||
| { | ||||
| 	global $state_chatting, $threadstate_to_string, $threadstate_key, | ||||
| 	global $threadstate_to_string, $threadstate_key, | ||||
| 		$webim_encoding, $operator, $can_viewthreads, $can_takeover; | ||||
| 	$state = $threadstate_to_string[$thread['istate']]; | ||||
| 	$result = "<thread id=\"" . $thread['threadid'] . "\" stateid=\"$state\"";
 | ||||
| @ -64,7 +65,7 @@ function thread_to_xml($thread) | ||||
| 		$threadoperator = "- " . $thread['groupname'] . " -"; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!($thread['istate'] == $state_chatting && $thread['agentId'] != $operator['operatorid'] && !is_capable($can_takeover, $operator))) { | ||||
| 	if (!($thread['istate'] == Thread::STATE_CHATTING && $thread['agentId'] != $operator['operatorid'] && !is_capable($can_takeover, $operator))) { | ||||
| 		$result .= " canopen=\"true\""; | ||||
| 	} | ||||
| 	if ($thread['agentId'] != $operator['operatorid'] && $thread['nextagent'] != $operator['operatorid'] | ||||
| @ -115,7 +116,7 @@ function thread_to_xml($thread) | ||||
| 
 | ||||
| function print_pending_threads($groupids, $since) | ||||
| { | ||||
| 	global $webim_encoding, $state_closed, $state_left; | ||||
| 	global $webim_encoding; | ||||
| 	$db = Database::getInstance(); | ||||
| 
 | ||||
| 	$revision = $since; | ||||
| @ -124,7 +125,7 @@ function print_pending_threads($groupids, $since) | ||||
| 		"userid, shownmessageid, userAgent, (select vclocalname from {chatgroup} where {chatgroup}.groupid = {chatthread}.groupid) as groupname " . | ||||
| 		"from {chatthread} where lrevision > :since " . | ||||
| 		($since <= 0 | ||||
| 			? "AND istate <> {$state_closed} AND istate <> {$state_left} " | ||||
| 			? "AND istate <> " . Thread::STATE_CLOSED . " AND istate <> " . Thread::STATE_LEFT . " " | ||||
| 			: "") . | ||||
| 		(Settings::get('enablegroups') == '1' | ||||
| 			? "AND (groupid is NULL" . ($groupids | ||||
| @ -215,7 +216,7 @@ function visitor_to_xml($visitor) | ||||
| 
 | ||||
| function print_visitors() | ||||
| { | ||||
| 	global $webim_encoding, $state_closed, $state_left; | ||||
| 	global $webim_encoding; | ||||
| 
 | ||||
| 	$db = Database::getInstance(); | ||||
| 
 | ||||
| @ -225,7 +226,7 @@ function print_visitors() | ||||
| 		"WHERE (:now - lasttime) > :lifetime ". | ||||
| 		"AND (threadid IS NULL OR " . | ||||
| 		"(SELECT count(*) FROM {chatthread} WHERE threadid = {chatsitevisitor}.threadid " . | ||||
| 		"AND istate <> {$state_closed} AND istate <> {$state_left}) = 0)", | ||||
| 		"AND istate <> " . Thread::STATE_CLOSED . " AND istate <> " . Thread::STATE_LEFT . ") = 0)", | ||||
| 		array( | ||||
| 			':lifetime' => Settings::get('tracking_lifetime'), | ||||
| 			':now' => time() | ||||
| @ -246,7 +247,7 @@ function print_visitors() | ||||
| 	$db->query( | ||||
| 		"UPDATE {chatsitevisitor} SET threadid = NULL WHERE threadid IS NOT NULL AND" . | ||||
| 		" (SELECT count(*) FROM {chatthread} WHERE threadid = {chatsitevisitor}.threadid" . | ||||
| 		" AND istate <> {$state_closed} AND istate <> {$state_left}) = 0" | ||||
| 		" AND istate <> " . Thread::STATE_CLOSED . " AND istate <> " . Thread::STATE_LEFT . ") = 0" | ||||
| 	); | ||||
| 
 | ||||
| // Remove old visitors' tracks
 | ||||
| @ -289,7 +290,7 @@ $showvisitors = verifyparam("showvisitors", "/^1$/", 0); | ||||
| if (!isset($_SESSION["${mysqlprefix}operatorgroups"])) { | ||||
| 	$_SESSION["${mysqlprefix}operatorgroups"] = get_operator_groupslist($operator['operatorid']); | ||||
| } | ||||
| close_old_threads(); | ||||
| Thread::closeOldThreads(); | ||||
| $groupids = $_SESSION["${mysqlprefix}operatorgroups"]; | ||||
| 
 | ||||
| start_xml_output(); | ||||
|  | ||||
| @ -18,6 +18,7 @@ | ||||
| require_once('libs/init.php'); | ||||
| require_once('libs/chat.php'); | ||||
| require_once('libs/operator.php'); | ||||
| require_once('libs/classes/thread.php'); | ||||
| 
 | ||||
| $act = verifyparam( "act", "/^(refresh|post|rename|close|ping)$/"); | ||||
| $token = verifyparam( "token", "/^\d{1,9}$/"); | ||||
| @ -33,8 +34,8 @@ if($threadid == 0 && ($token == 123 || $token == 124)) { | ||||
| 	exit; | ||||
| } | ||||
| 
 | ||||
| $thread = thread_by_id($threadid); | ||||
| if( !$thread || !isset($thread['ltoken']) || $token != $thread['ltoken'] ) { | ||||
| $thread = Thread::load($threadid, $token); | ||||
| if (! $thread) { | ||||
| 	die("wrong thread"); | ||||
| } | ||||
| 
 | ||||
| @ -50,11 +51,11 @@ function show_error($message) { | ||||
| 	exit; | ||||
| } | ||||
| 
 | ||||
| ping_thread($thread, $isuser,$istyping); | ||||
| $thread->ping($isuser, $istyping); | ||||
| 
 | ||||
| if( !$isuser && $act != "rename" ) { | ||||
| 	$operator = check_login(); | ||||
| 	check_for_reassign($thread,$operator); | ||||
| 	$thread->checkForReassign($operator); | ||||
| } | ||||
| 
 | ||||
| if( $act == "refresh" ) { | ||||
| @ -66,16 +67,22 @@ if( $act == "refresh" ) { | ||||
| 	$lastid = verifyparam( "lastid", "/^\d{1,9}$/", -1); | ||||
| 	$message = getrawparam('message'); | ||||
| 
 | ||||
| 	$kind = $isuser ? $kind_user : $kind_agent; | ||||
| 	$from = $isuser ? $thread['userName'] : $thread['agentName']; | ||||
| 	$kind = $isuser ? Thread::KIND_USER : Thread::KIND_AGENT; | ||||
| 	$from = $isuser ? $thread->userName : $thread->agentName; | ||||
| 
 | ||||
| 	if(!$isuser && $operator['operatorid'] != $thread['agentId']) { | ||||
| 	if(!$isuser && $operator['operatorid'] != $thread->agentId) { | ||||
| 		show_error("cannot send"); | ||||
| 	} | ||||
| 
 | ||||
| 	$postedid = post_message_($threadid,$kind,$message,$from,null,$isuser ? null : $operator['operatorid'] ); | ||||
| 	if($isuser && $thread["shownmessageid"] == 0) { | ||||
| 		commit_thread( $thread['threadid'], array('shownmessageid' => $postedid)); | ||||
| 	$postedid = $thread->postMessage( | ||||
| 		$kind, | ||||
| 		$message, | ||||
| 		$from, | ||||
| 		$isuser ? null : $operator['operatorid'] | ||||
| 	); | ||||
| 	if($isuser && $thread->shownMessageId == 0) { | ||||
| 		$thread->shownMessageId = $postedid; | ||||
| 		$thread->save(); | ||||
| 	} | ||||
| 	print_thread_messages($thread, $token, $lastid, $isuser, $outformat, $isuser ? null : $operator['operatorid']); | ||||
| 	exit; | ||||
| @ -88,7 +95,7 @@ if( $act == "refresh" ) { | ||||
| 
 | ||||
| 	$newname = getrawparam('name'); | ||||
| 
 | ||||
| 	rename_user($thread, $newname); | ||||
| 	$thread->renameUser($newname); | ||||
| 	$data = strtr(base64_encode(myiconv($webim_encoding,"utf-8",$newname)), '+/=', '-_,'); | ||||
| 	setcookie($namecookie, $data, time()+60*60*24*365); | ||||
| 	show_ok_result("rename"); | ||||
| @ -98,8 +105,8 @@ if( $act == "refresh" ) { | ||||
| 
 | ||||
| } else if( $act == "close" ) { | ||||
| 
 | ||||
| 	if( $isuser || $thread['agentId'] == $operator['operatorid']) { | ||||
| 		close_thread($thread, $isuser); | ||||
| 	if( $isuser || $thread->agentId == $operator['operatorid']) { | ||||
| 		$thread->close($isuser); | ||||
| 	} | ||||
| 	show_ok_result("closed"); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user