From 61c52eb1278184111f7373794c78dea3735fc484 Mon Sep 17 00:00:00 2001
From: Dmitriy Simushev <simushevds@ossg.ru>
Date: Sat, 25 Feb 2012 19:40:05 +0000
Subject: [PATCH] Added groups isolation

---
 src/messenger/webim/libs/common.php        |  1 +
 src/messenger/webim/libs/operator.php      | 81 ++++++++++++++++++----
 src/messenger/webim/locales/en/properties  |  2 +
 src/messenger/webim/locales/ru/properties  |  2 +
 src/messenger/webim/operator/agent.php     |  2 +-
 src/messenger/webim/operator/canned.php    |  2 +-
 src/messenger/webim/operator/features.php  |  4 +-
 src/messenger/webim/operator/operators.php |  2 +-
 src/messenger/webim/operator/opgroups.php  |  3 +-
 src/messenger/webim/operator/themes.php    |  2 +-
 src/messenger/webim/operator/update.php    |  8 +--
 src/messenger/webim/view/features.php      | 23 +++++-
 12 files changed, 109 insertions(+), 23 deletions(-)

diff --git a/src/messenger/webim/libs/common.php b/src/messenger/webim/libs/common.php
index 8e8cdaf6..7a23952a 100644
--- a/src/messenger/webim/libs/common.php
+++ b/src/messenger/webim/libs/common.php
@@ -695,6 +695,7 @@ $settings = array(
 	'forcessl' => '0',
 	'usercanchangename' => '1',
 	'enablegroups' => '0',
+	'enablegroupsisolation' => '0',
 	'enablestatistics' => '1',
 	'enabletracking' => '0',
 	'enablepresurvey' => '1',
diff --git a/src/messenger/webim/libs/operator.php b/src/messenger/webim/libs/operator.php
index f5fc9826..ad4d33f2 100755
--- a/src/messenger/webim/libs/operator.php
+++ b/src/messenger/webim/libs/operator.php
@@ -80,6 +80,25 @@ function operator_get_all()
 	return $operators;
 }
 
+function get_operators_from_adjacent_groups($operator)
+{
+	global $mysqlprefix;
+	$link = connect();
+
+	$query = "select distinct ${mysqlprefix}chatoperator.operatorid, vclogin, vclocalename, vccommonname, istatus, idisabled, (unix_timestamp(CURRENT_TIMESTAMP)-unix_timestamp(dtmlastvisited)) as time " .
+		 "from ${mysqlprefix}chatoperator, ${mysqlprefix}chatgroupoperator " .
+		 " where ${mysqlprefix}chatoperator.operatorid = ${mysqlprefix}chatgroupoperator.operatorid and ${mysqlprefix}chatgroupoperator.groupid in " .
+		 "(select g.groupid from ${mysqlprefix}chatgroup g, " .
+		 "(select distinct parent from ${mysqlprefix}chatgroup, ${mysqlprefix}chatgroupoperator " .
+		 "where ${mysqlprefix}chatgroup.groupid = ${mysqlprefix}chatgroupoperator.groupid and ${mysqlprefix}chatgroupoperator.operatorid = ".$operator['operatorid'].") i " .
+		 "where g.groupid = i.parent or g.parent = i.parent " .
+		 ") order by vclogin";
+
+	$operators = select_multi_assoc($query, $link);
+	close_connection($link);
+	return $operators;
+}
+
 function operator_is_online($operator)
 {
 	global $settings;
@@ -286,18 +305,23 @@ function logout_operator()
 	}
 }
 
-function setup_redirect_links($threadid, $token)
+function setup_redirect_links($threadid, $operator, $token)
 {
 	global $page, $webimroot, $settings, $mysqlprefix;
 	loadsettings();
-	$link = connect();
 
-	$operatorscount = db_rows_count("${mysqlprefix}chatoperator", array(), "", $link);
+	$operator_in_isolation = in_isolation($operator);
+
+	$operators = $operator_in_isolation?get_operators_from_adjacent_groups($operator):operator_get_all();
+	$operatorscount = count($operators);
+
+	$link = connect();
 
 	$groupscount = 0;
 	$groups = array();
 	if ($settings['enablegroups'] == "1") {
-		foreach (get_groups($link, true) as $group) {
+		$groupslist = $operator_in_isolation?get_groups_for_operator($link, $operator, true):get_groups($link, true);
+		foreach ($groupslist as $group) {
 			if ($group['inumofagents'] == 0) {
 				continue;
 			}
@@ -305,17 +329,14 @@ function setup_redirect_links($threadid, $token)
 		}
 		$groupscount = count($groups);
 	}
+	close_connection($link);
 
 	prepare_pagination(max($operatorscount, $groupscount), 8);
 	$p = $page['pagination'];
 	$limit = $p['limit'];
 
-	$operators = select_multi_assoc(db_build_select(
-										"operatorid, vclogin, vclocalename, vccommonname, istatus, (unix_timestamp(CURRENT_TIMESTAMP)-unix_timestamp(dtmlastvisited)) as time",
-										"${mysqlprefix}chatoperator", array(), "order by vclogin $limit"), $link);
-
+	$operators = array_slice($operators, $p['start'], $p['end'] - $p['start']);
 	$groups = array_slice($groups, $p['start'], $p['end'] - $p['start']);
-	close_connection($link);
 
 	$agent_list = "";
 	$params = array('thread' => $threadid, 'token' => $token);
@@ -375,6 +396,13 @@ function is_capable($perm, $operator)
 	return $perm >= 0 && $perm < 32 && ($permissions & (1 << $perm)) != 0;
 }
 
+function in_isolation($operator)
+{
+	global $settings, $can_administrate;
+	loadsettings();
+	return (!is_capable($can_administrate, $operator) && $settings['enablegroups'] && $settings['enablegroupsisolation']);
+}
+
 function prepare_menu($operator, $hasright = true)
 {
 	global $page, $settings, $can_administrate;
@@ -395,6 +423,18 @@ function get_all_groups($link)
 	return get_sorted_child_groups_(select_multi_assoc($query, $link));
 }
 
+function get_all_groups_for_operator($operator, $link)
+{
+	global $mysqlprefix;
+	$query = "select g.groupid as groupid, g.parent, g.vclocalname, g.vclocaldescription " .
+		 "from ${mysqlprefix}chatgroup g, " .
+		 "(select distinct parent from ${mysqlprefix}chatgroup, ${mysqlprefix}chatgroupoperator " .
+		 "where ${mysqlprefix}chatgroup.groupid = ${mysqlprefix}chatgroupoperator.groupid and ${mysqlprefix}chatgroupoperator.operatorid = ".$operator['operatorid'].") i " .
+		 "where g.groupid = i.parent or g.parent = i.parent " .
+		 "order by vclocalname";
+	return get_sorted_child_groups_(select_multi_assoc($query, $link));
+}
+
 function get_sorted_child_groups_($groupslist, $skipgroups = array(), $maxlevel = -1, $groupid = NULL, $level = 0)
 {
 	$child_groups = array();
@@ -410,10 +450,10 @@ function get_sorted_child_groups_($groupslist, $skipgroups = array(), $maxlevel
 	return $child_groups;
 }
 
-function get_groups($link, $checkaway)
+function get_groups_($link, $operator, $checkaway)
 {
 	global $mysqlprefix;
-	$query = "select ${mysqlprefix}chatgroup.groupid as groupid, parent, vclocalname, vclocaldescription, iweight" .
+	$query = "select ${mysqlprefix}chatgroup.groupid as groupid, ${mysqlprefix}chatgroup.parent as parent, vclocalname, vclocaldescription, iweight" .
 			 ", (SELECT count(*) from ${mysqlprefix}chatgroupoperator where ${mysqlprefix}chatgroup.groupid = " .
 			 "${mysqlprefix}chatgroupoperator.groupid) as inumofagents" .
 			 ", (SELECT min(unix_timestamp(CURRENT_TIMESTAMP)-unix_timestamp(dtmlastvisited)) as time " .
@@ -427,10 +467,27 @@ function get_groups($link, $checkaway)
 					   "and ${mysqlprefix}chatgroupoperator.operatorid = ${mysqlprefix}chatoperator.operatorid) as ilastseenaway"
 					 : ""
 			 ) .
-			 " from ${mysqlprefix}chatgroup order by iweight, vclocalname";
+			 " from ${mysqlprefix}chatgroup" .
+			 ($operator
+					 ? ", (select distinct parent from ${mysqlprefix}chatgroup, ${mysqlprefix}chatgroupoperator " .
+					   "where ${mysqlprefix}chatgroup.groupid = ${mysqlprefix}chatgroupoperator.groupid and ${mysqlprefix}chatgroupoperator.operatorid = ".$operator['operatorid'].") i " .
+					   "where ${mysqlprefix}chatgroup.groupid = i.parent or ${mysqlprefix}chatgroup.parent = i.parent "
+					 : ""
+			 ) .
+			 " order by iweight, vclocalname";
 	return get_sorted_child_groups_(select_multi_assoc($query, $link));
 }
 
+function get_groups($link, $checkaway)
+{
+	return get_groups_($link, NULL, $checkaway);
+}
+
+function get_groups_for_operator($link, $operator, $checkaway)
+{
+	return get_groups_($link, $operator, $checkaway);
+}
+
 function get_operator_groupids($operatorid)
 {
 	global $mysqlprefix;
diff --git a/src/messenger/webim/locales/en/properties b/src/messenger/webim/locales/en/properties
index a1f81e22..499cb548 100644
--- a/src/messenger/webim/locales/en/properties
+++ b/src/messenger/webim/locales/en/properties
@@ -478,6 +478,8 @@ settings.enableban.description=Using it you can block attacks from specific IPs
 settings.enableban=Enable feature "Malicious Visitors"
 settings.enablegroups.description=Use it to have separate queues for different questions.  
 settings.enablegroups=Enable "Groups"
+settings.enablegroupsisolation=Enable "Groups Isolation"
+settings.enablegroupsisolation.description=Use it to completely isolate groups from each other.
 settings.enablepresurvey.description=Forces the user to fill out a special form to start a chat.
 settings.enablepresurvey=Enable "Pre-chat survey"
 settings.enablessl.description=Please note that your web server should be configured to support https requests.
diff --git a/src/messenger/webim/locales/ru/properties b/src/messenger/webim/locales/ru/properties
index b79d8738..4b7f7585 100644
--- a/src/messenger/webim/locales/ru/properties
+++ b/src/messenger/webim/locales/ru/properties
@@ -476,6 +476,8 @@ settings.enableban.description=
 settings.enableban=�������� ������� "������������� ����������"
 settings.enablegroups.description=��������� ���������� ���������� � ������ � �������������� ��� ��� ��������� �������.
 settings.enablegroups=�������� ������� "������"
+settings.enablegroupsisolation=�������� ������� "�������� �����"
+settings.enablegroupsisolation.description=��������� ��������� ����������� ������ ���� �� �����.
 settings.enablepresurvey.description=���������� ���������� ��������� ����������� ����� ����� ������� ����.
 settings.enablepresurvey=�������� "����� ����� ������� �������"
 settings.enablessl.description=��� ������ ������ ���� �������� ��� ��������� https ��������.
diff --git a/src/messenger/webim/operator/agent.php b/src/messenger/webim/operator/agent.php
index b1f61def..795590e7 100644
--- a/src/messenger/webim/operator/agent.php
+++ b/src/messenger/webim/operator/agent.php
@@ -123,7 +123,7 @@ start_html_output();
 
 $pparam = verifyparam("act", "/^(redirect)$/", "default");
 if ($pparam == "redirect") {
-	setup_redirect_links($threadid, $token);
+	setup_redirect_links($threadid, $operator, $token);
 	expand("../styles/dialogs", getchatstyle(), "redirect.tpl");
 } else {
 	expand("../styles/dialogs", getchatstyle(), "chat.tpl");
diff --git a/src/messenger/webim/operator/canned.php b/src/messenger/webim/operator/canned.php
index a050a937..dd01f4c2 100644
--- a/src/messenger/webim/operator/canned.php
+++ b/src/messenger/webim/operator/canned.php
@@ -61,7 +61,7 @@ if ($groupid) {
 }
 
 $link = connect();
-$allgroups = get_all_groups($link);
+$allgroups = in_isolation($operator)?get_all_groups_for_operator($operator, $link):get_all_groups($link);
 close_connection($link);
 $page['groups'] = array();
 $page['groups'][] = array('groupid' => '', 'vclocalname' => getlocal("page.gen_button.default_group"));
diff --git a/src/messenger/webim/operator/features.php b/src/messenger/webim/operator/features.php
index 147b10b9..7419e181 100644
--- a/src/messenger/webim/operator/features.php
+++ b/src/messenger/webim/operator/features.php
@@ -29,7 +29,9 @@ $page = array('agentId' => '');
 $errors = array();
 
 $options = array(
-	'enableban', 'usercanchangename', 'enablegroups', 'enablestatistics', 'enabletracking',
+	'enableban', 'usercanchangename',
+	'enablegroups', 'enablegroupsisolation',
+	'enablestatistics', 'enabletracking',
 	'enablessl', 'forcessl',
 	'enablepresurvey', 'surveyaskmail', 'surveyaskgroup', 'surveyaskmessage',
 	'enablepopupnotification', 'showonlineoperators',
diff --git a/src/messenger/webim/operator/operators.php b/src/messenger/webim/operator/operators.php
index 28983492..f6c2de41 100644
--- a/src/messenger/webim/operator/operators.php
+++ b/src/messenger/webim/operator/operators.php
@@ -92,7 +92,7 @@ if (isset($_GET['act'])) {
 }
 
 $page = array();
-$page['allowedAgents'] = operator_get_all();
+$page['allowedAgents'] = in_isolation($operator)?get_operators_from_adjacent_groups($operator):operator_get_all();
 $page['canmodify'] = is_capable($can_administrate, $operator);
 
 setlocale(LC_TIME, getstring("time.locale"));
diff --git a/src/messenger/webim/operator/opgroups.php b/src/messenger/webim/operator/opgroups.php
index a83e1d91..a0a704a5 100644
--- a/src/messenger/webim/operator/opgroups.php
+++ b/src/messenger/webim/operator/opgroups.php
@@ -36,11 +36,12 @@ function update_operator_groups($operatorid, $newvalue)
 	close_connection($link);
 }
 
+$operator_in_isolation = in_isolation($operator);
 
 $opId = verifyparam("op", "/^\d{1,9}$/");
 $page = array('opid' => $opId);
 $link = connect();
-$page['groups'] = get_all_groups($link);
+$page['groups'] = $operator_in_isolation?get_all_groups_for_operator($operator, $link):get_all_groups($link);
 close_connection($link);
 $errors = array();
 
diff --git a/src/messenger/webim/operator/themes.php b/src/messenger/webim/operator/themes.php
index 66a24677..d6eb3a45 100644
--- a/src/messenger/webim/operator/themes.php
+++ b/src/messenger/webim/operator/themes.php
@@ -79,7 +79,7 @@ if ($show == 'redirect' || $show == 'redirected' || $show == 'agentchat' || $sho
 			 'operatorid' => ($show == 'agentrochat' ? 2 : 1),
 		));
 	if ($show == 'redirect') {
-		setup_redirect_links(0, $show == 'agentrochat' ? 124 : 123);
+		setup_redirect_links(0, $operator, $show == 'agentrochat' ? 124 : 123);
 	} elseif ($show == 'redirected') {
 		$page['message'] = getlocal2("chat.redirected.content", array("Administrator"));
 	}
diff --git a/src/messenger/webim/operator/update.php b/src/messenger/webim/operator/update.php
index ec4ea5f9..1b7b65cb 100644
--- a/src/messenger/webim/operator/update.php
+++ b/src/messenger/webim/operator/update.php
@@ -151,11 +151,11 @@ function print_pending_threads($groupids, $since)
 	echo "</threads>";
 }
 
-function print_operators()
+function print_operators($operator)
 {
-	global $webim_encoding;
+	global $webim_encoding, $settings;
 	echo "<operators>";
-	$operators = operator_get_all();
+	$operators = in_isolation($operator)?get_operators_from_adjacent_groups($operator):operator_get_all();
 
 	foreach ($operators as $operator) {
 		if (!operator_is_online($operator))
@@ -278,7 +278,7 @@ $groupids = $_SESSION["${mysqlprefix}operatorgroups"];
 start_xml_output();
 echo '<update>';
 if ($showonline) {
-	print_operators();
+	print_operators($operator);
 }
 print_pending_threads($groupids, $since);
 if ($showvisitors) {
diff --git a/src/messenger/webim/view/features.php b/src/messenger/webim/view/features.php
index 559411a1..0d842d41 100644
--- a/src/messenger/webim/view/features.php
+++ b/src/messenger/webim/view/features.php
@@ -45,6 +45,14 @@ function updateSSL() {
 	}
 }
 
+function updateGroups(){
+	if($("#enablegroups").is(":checked")) {
+		$(".undergroups").show();
+	} else {
+		$(".undergroups").hide();
+	}
+}
+
 $(function(){
 	$("#enablepresurvey").change(function() {
 		updateSurvey();
@@ -52,8 +60,12 @@ $(function(){
 	$("#enablessl").change(function() {
 		updateSSL();
 	});
+	$("#enablegroups").change(function() {
+		updateGroups();
+	});
 	updateSurvey();
 	updateSSL();
+	updateGroups();
 });
 </script>
 <?php
@@ -109,10 +121,19 @@ require_once('inc_errors.php');
 		<div class="field">
 			<div class="flabel"><?php echo getlocal('settings.enablegroups') ?></div>
 			<div class="fvalue">
-				<input type="checkbox" name="enablegroups" value="on"<?php echo form_value_cb('enablegroups') ? " checked=\"checked\"" : "" ?><?php echo $page['canmodify'] ? "" : " disabled=\"disabled\"" ?>/>
+				<input id="enablegroups" type="checkbox" name="enablegroups" value="on"<?php echo form_value_cb('enablegroups') ? " checked=\"checked\"" : "" ?><?php echo $page['canmodify'] ? "" : " disabled=\"disabled\"" ?>/>
 			</div>
 			<div class="fdescr"> &mdash; <?php echo getlocal('settings.enablegroups.description') ?></div>
 			<br clear="all"/>
+
+			<div class="subfield undergroups">
+				<div class="flabel"><?php echo getlocal('settings.enablegroupsisolation') ?></div>
+				<div class="fvalue">
+					<input type="checkbox" name="enablegroupsisolation" value="on"<?php echo form_value_cb('enablegroupsisolation') ? " checked=\"checked\"" : "" ?><?php echo $page['canmodify'] ? "" : " disabled=\"disabled\"" ?>/>
+				</div>
+				<div class="fdescr"> &mdash; <?php echo getlocal('settings.enablegroupsisolation.description') ?></div>
+				<br clear="all"/>
+			</div>
 		</div>
 
 		<div class="field">