Operator Panel: Drag n' drop call transfer and origination, extension monitoring, etc.

This commit is contained in:
Nate Jones
2014-12-03 11:05:13 +00:00
parent bed960fd04
commit f64b010c28
11 changed files with 1099 additions and 0 deletions

View File

@@ -0,0 +1,84 @@
<?php
//application details
$apps[$x]['name'] = "Operator Panel";
$apps[$x]['uuid'] = '01b78ec9-5e12-4aca-95a3-893a98c80762';
$apps[$x]['category'] = 'Switch';
$apps[$x]['subcategory'] = '';
$apps[$x]['version'] = '';
$apps[$x]['license'] = 'Mozilla Public License 1.1';
$apps[$x]['url'] = 'http://www.fusionpbx.com';
$apps[$x]['description']['en-us'] = 'Operator panel shows the status.';
$apps[$x]['description']['es-mx'] = '';
$apps[$x]['description']['de'] = '';
$apps[$x]['description']['de-ch'] = '';
$apps[$x]['description']['de-at'] = '';
$apps[$x]['description']['fr'] = '';
$apps[$x]['description']['fr-ca'] = '';
$apps[$x]['description']['fr-ch'] = '';
$apps[$x]['description']['pt-pt'] = 'Canais ativos no sistema.';
$apps[$x]['description']['pt-br'] = '';
//menu details
$apps[$x]['menu'][0]['title']['en-us'] = 'Operator Panel';
$apps[$x]['menu'][0]['title']['es-mx'] = '';
$apps[$x]['menu'][0]['title']['de'] = '';
$apps[$x]['menu'][0]['title']['de-ch'] = '';
$apps[$x]['menu'][0]['title']['de-at'] = '';
$apps[$x]['menu'][0]['title']['fr'] = '';
$apps[$x]['menu'][0]['title']['fr-ca'] = '';
$apps[$x]['menu'][0]['title']['fr-ch'] = '';
$apps[$x]['menu'][0]['title']['pt-pt'] = '';
$apps[$x]['menu'][0]['title']['pt-br'] = '';
$apps[$x]['menu'][0]['uuid'] = '30fa146b-18a8-4d18-8576-16d3cbf25fd8';
$apps[$x]['menu'][0]['parent_uuid'] = '0438b504-8613-7887-c420-c837ffb20cb1';
$apps[$x]['menu'][0]['category'] = 'internal';
$apps[$x]['menu'][0]['path'] = '/app/operator_panel/index.php';
$apps[$x]['menu'][0]['groups'][] = 'superadmin';
//permission details
$apps[$x]['permissions'][0]['name'] = 'calls_active_view';
$apps[$x]['permissions'][0]['groups'][] = 'superadmin';
$apps[$x]['permissions'][1]['name'] = 'calls_active_transfer';
$apps[$x]['permissions'][1]['groups'][] = 'superadmin';
$apps[$x]['permissions'][2]['name'] = 'calls_active_hangup';
$apps[$x]['permissions'][2]['groups'][] = 'superadmin';
$apps[$x]['permissions'][3]['name'] = 'calls_active_park';
$apps[$x]['permissions'][3]['groups'][] = 'superadmin';
$apps[$x]['permissions'][4]['name'] = 'calls_active_rec';
$apps[$x]['permissions'][4]['groups'][] = 'superadmin';
$apps[$x]['permissions'][5]['name'] = 'extensions_active_view';
//$apps[$x]['permissions'][5]['groups'][] = 'user';
$apps[$x]['permissions'][5]['groups'][] = 'admin';
$apps[$x]['permissions'][5]['groups'][] = 'superadmin';
$apps[$x]['permissions'][6]['name'] = 'extensions_active_transfer';
$apps[$x]['permissions'][6]['groups'][] = 'admin';
$apps[$x]['permissions'][6]['groups'][] = 'superadmin';
$apps[$x]['permissions'][7]['name'] = 'extensions_active_hangup';
$apps[$x]['permissions'][7]['groups'][] = 'admin';
$apps[$x]['permissions'][7]['groups'][] = 'superadmin';
$apps[$x]['permissions'][8]['name'] = 'extensions_active_park';
$apps[$x]['permissions'][8]['groups'][] = 'admin';
$apps[$x]['permissions'][8]['groups'][] = 'superadmin';
$apps[$x]['permissions'][9]['name'] = 'extensions_active_rec';
$apps[$x]['permissions'][9]['groups'][] = 'admin';
$apps[$x]['permissions'][9]['groups'][] = 'superadmin';
$apps[$x]['permissions'][10]['name'] = 'extensions_active_list_view';
//$apps[$x]['permissions'][10]['groups'][] = 'user';
$apps[$x]['permissions'][10]['groups'][] = 'admin';
$apps[$x]['permissions'][10]['groups'][] = 'superadmin';
$apps[$x]['permissions'][11]['name'] = 'extensions_active_assigned_view';
//$apps[$x]['permissions'][11]['groups'][] = 'user';
$apps[$x]['permissions'][11]['groups'][] = 'admin';
$apps[$x]['permissions'][11]['groups'][] = 'superadmin';
?>

View File

@@ -0,0 +1,23 @@
<?php
$text['title-operator_panel']['en-us'] = 'Operator Panel';
$text['title-operator_panel']['es-cl'] = 'Panel de Operador';
$text['title-operator_panel']['pt-pt'] = 'Painel do Operador';
$text['title-operator_panel']['fr-fr'] = 'Operator Panel';
$text['label-call_group']['en-us'] = "Call Group";
$text['label-call_group']['es-cl'] = "Llamar a Grupo";
$text['label-call_group']['pt-pt'] = "Grupo";
$text['label-call_group']['fr-fr'] = "Groupe d'appel";
$text['label-other_extensions']['en-us'] = "Other Extensions";
$text['label-other_extensions']['es-cl'] = "Otras Extensiones";
$text['label-other_extensions']['pt-pt'] = "Outros Extensions";
$text['label-other_extensions']['fr-fr'] = "Autres Extensions";
$text['label-no_extensions_found']['en-us'] = "No extensions found.";
$text['label-no_extensions_found']['es-cl'] = "No hay extensiones encontrados.";
$text['label-no_extensions_found']['pt-pt'] = "Sem extensões encontrado.";
$text['label-no_extensions_found']['fr-fr'] = "Aucun extensions trouvés.";
?>

185
app/operator_panel/exec.php Normal file
View File

@@ -0,0 +1,185 @@
<?php
/* $Id$ */
/*
v_exec.php
Copyright (C) 2008 Mark J Crane
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
include "root.php";
require_once "resources/require.php";
require_once "resources/check_auth.php";
/*
if (permission_exists('calls_active_view') || permission_exists('extensions_active_view')) {
//access granted
}
else {
echo "access denied";
exit;
}
*/
//authorized referrer
// if(stristr($_SERVER["HTTP_REFERER"], '/index.php') === false) {
// if(stristr($_SERVER["HTTP_REFERER"], '/index_inc.php') === false) {
// echo " access denied";
// exit;
// }
// }
//http get variables set to php variables
if (count($_GET)>0) {
$switch_cmd = trim(check_str($_GET["cmd"]));
$action = trim(check_str($_GET["action"]));
$data = trim(check_str($_GET["data"]));
$direction = trim(check_str($_GET["direction"]));
$username = $_SESSION['username'];
}
//authorized commands
// if (stristr($switch_cmd, '&uuid=') == true) {
// //authorized;
// } elseif (stristr($switch_cmd, 'uuid_kill') == true) {
// //authorized;
// } elseif (stristr($switch_cmd, 'uuid_transfer') == true) {
// //authorized;
// } elseif (stristr($switch_cmd, 'uuid_record') == true) {
// //authorized;
// } elseif (stristr($action, 'user_status') == true) {
// //authorized;
// } elseif (stristr($action, 'callcenter_config') == true) {
// //authorized;
// } elseif (stristr($action, 'originate') == true) {
// //authorized;
// } else {
// //not found. this command is not authorized
// echo "access denied";
// exit;
// }
if (count($_GET)>0) {
//setup the event socket connection
$fp = event_socket_create($_SESSION['event_socket_ip_address'], $_SESSION['event_socket_port'], $_SESSION['event_socket_password']);
if (stristr($action, 'user_status') == true) {
$user_status = $data;
switch ($user_status) {
case "Available":
$user_status = "Available";
//update the user state
$cmd = "api callcenter_config agent set state ".$username."@".$_SESSION['domain_name']." Waiting";
$response = event_socket_request($fp, $cmd);
break;
case "Available_On_Demand":
$user_status = "Available (On Demand)";
//update the user state
$cmd = "api callcenter_config agent set state ".$username."@".$_SESSION['domain_name']." Waiting";
$response = event_socket_request($fp, $cmd);
break;
case "Logged_Out":
$user_status = "Logged Out";
//update the user state
$cmd = "api callcenter_config agent set state ".$username."@".$_SESSION['domain_name']." Waiting";
$response = event_socket_request($fp, $cmd);
break;
case "On_Break":
$user_status = "On Break";
//update the user state
$cmd = "api callcenter_config agent set state ".$username."@".$_SESSION['domain_name']." Waiting";
$response = event_socket_request($fp, $cmd);
break;
case "Do_Not_Disturb":
$user_status = "Do Not Disturb";
//update the user state
$cmd = "api callcenter_config agent set state ".$username."@".$_SESSION['domain_name']." Waiting";
$response = event_socket_request($fp, $cmd);
break;
default:
$user_status = "";
}
}
//fs cmd
if (strlen($switch_cmd) > 0) {
//set the status so they are compatible with mod_callcenter
$switch_cmd = str_replace("Available_On_Demand", "'Available (On Demand)'", $switch_cmd);
$switch_cmd = str_replace("Logged_Out", "'Logged Out'", $switch_cmd);
$switch_cmd = str_replace("On_Break", "'On Break'", $switch_cmd);
$switch_cmd = str_replace("Do_Not_Disturb", "'Logged Out'", $switch_cmd);
/*
//if ($action == "energy") {
//conference 3001-example.org energy 103
$switch_result = event_socket_request($fp, 'api '.$switch_cmd);
$result_array = explode("=",$switch_result);
$tmp_value = $result_array[1];
//if ($direction == "up") { $tmp_value = $tmp_value + 100; }
//if ($direction == "down") { $tmp_value = $tmp_value - 100; }
//echo "energy $tmp_value<br />\n";
$switch_result = event_socket_request($fp, 'api '.$switch_cmd.' '.$tmp_value);
//}
if ($action == "volume_in") {
$switch_result = event_socket_request($fp, 'api '.$switch_cmd);
$result_array = explode("=",$switch_result);
$tmp_value = $result_array[1];
if ($direction == "up") { $tmp_value = $tmp_value + 1; }
if ($direction == "down") { $tmp_value = $tmp_value - 1; }
//echo "volume $tmp_value<br />\n";
$switch_result = event_socket_request($fp, 'api '.$switch_cmd.' '.$tmp_value);
}
if ($action == "volume_out") {
$switch_result = event_socket_request($fp, 'api '.$switch_cmd);
$result_array = explode("=",$switch_result);
$tmp_value = $result_array[1];
if ($direction == "up") { $tmp_value = $tmp_value + 1; }
if ($direction == "down") { $tmp_value = $tmp_value - 1; }
//echo "volume $tmp_value<br />\n";
$switch_result = event_socket_request($fp, 'api '.$switch_cmd.' '.$tmp_value);
}
*/
$switch_result = event_socket_request($fp, 'api '.$switch_cmd);
if ($action == "record") {
if (trim($_GET["action2"]) == "stop") {
$x=0;
while (true) {
if ($x > 0) {
$dest_file = $_SESSION['switch']['recordings']['dir']."/archive/".date("Y")."/".date("M")."/".date("d")."/".$_GET["uuid"]."_".$x.".wav";
}
else {
$dest_file = $_SESSION['switch']['recordings']['dir']."/archive/".date("Y")."/".date("M")."/".date("d")."/".$_GET["uuid"].".wav";
}
if (!file_exists($dest_file)) {
rename($_SESSION['switch']['recordings']['dir']."/archive/".date("Y")."/".date("M")."/".date("d")."/".$_GET["uuid"].".wav", $dest_file);
break;
}
$x++;
}
}
}
}
}
?>

View File

@@ -0,0 +1,340 @@
<?php
/*
FusionPBX
Version: MPL 1.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is FusionPBX
The Initial Developer of the Original Code is
Mark J Crane <markjcrane@fusionpbx.com>
Portions created by the Initial Developer are Copyright (C) 2008-2012
the Initial Developer. All Rights Reserved.
Contributor(s):
Mark J Crane <markjcrane@fusionpbx.com>
*/
include "root.php";
require_once "resources/require.php";
require_once "resources/check_auth.php";
if (permission_exists('extensions_active_view')) {
//access granted
}
else {
echo "access denied";
exit;
}
//add multi-lingual support
include "app_languages.php";
foreach($text as $key => $value) {
$text[$key] = $value[$_SESSION['domain']['language']['code']];
}
require_once "resources/header.php";
?>
<script type="text/javascript">
//ajax refresh
var refresh = 1000;
var source_url = 'index_inc.php?<?php if (isset($_GET['debug'])) { echo "&debug"; } ?>';
var interval_timer_id;
function loadXmlHttp(url, id) {
var f = this;
f.xmlHttp = null;
/*@cc_on @*/ // used here and below, limits try/catch to those IE browsers that both benefit from and support it
/*@if(@_jscript_version >= 5) // prevents errors in old browsers that barf on try/catch & problems in IE if Active X disabled
try {f.ie = window.ActiveXObject}catch(e){f.ie = false;}
@end @*/
if (window.XMLHttpRequest&&!f.ie||/^http/.test(window.location.href))
f.xmlHttp = new XMLHttpRequest(); // Firefox, Opera 8.0+, Safari, others, IE 7+ when live - this is the standard method
else if (/(object)|(function)/.test(typeof createRequest))
f.xmlHttp = createRequest(); // ICEBrowser, perhaps others
else {
f.xmlHttp = null;
// Internet Explorer 5 to 6, includes IE 7+ when local //
/*@cc_on @*/
/*@if(@_jscript_version >= 5)
try{f.xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");}
catch (e){try{f.xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");}catch(e){f.xmlHttp=null;}}
@end @*/
}
if(f.xmlHttp != null){
f.el = document.getElementById(id);
f.xmlHttp.open("GET",url,true);
f.xmlHttp.onreadystatechange = function(){f.stateChanged();};
f.xmlHttp.send(null);
}
}
loadXmlHttp.prototype.stateChanged=function () {
if (this.xmlHttp.readyState == 4 && (this.xmlHttp.status == 200 || !/^http/.test(window.location.href)))
//this.el.innerHTML = this.xmlHttp.responseText;
document.getElementById('ajax_reponse').innerHTML = this.xmlHttp.responseText;
}
var requestTime = function() {
new loadXmlHttp(source_url + '&group=' + ((document.getElementById('group')) ? document.getElementById('group').options[document.getElementById('group').selectedIndex].value : '') <?php if (isset($_GET['debug'])) { echo "+ '&debug'"; } ?>, 'ajax_reponse');
refresh_start();
}
if (window.addEventListener) {
window.addEventListener('load', requestTime, false);
}
else if (window.attachEvent) {
window.attachEvent('onload', requestTime);
}
//drag/drop functionality
function drag(ev, from_ext) {
ev.dataTransfer.setData("Call", ev.target.id);
ev.dataTransfer.setData("From", from_ext);
refresh_stop();
}
function allowDrop(ev, target_id) {
ev.preventDefault();
}
function discardDrop(ev, target_id) {
ev.preventDefault();
}
function drop(ev, to_ext) {
ev.preventDefault();
var call_id = ev.dataTransfer.getData("Call");
var from_ext = ev.dataTransfer.getData("From");
var to_ext = to_ext;
var cmd;
if (call_id != '') {
cmd = get_transfer_cmd(call_id, to_ext); //transfer a call
}
else {
if (from_ext != to_ext) { // prevent user from dragging extention onto self
cmd = get_originate_cmd(from_ext+'@<?=$_SESSION["domain_name"]?>', to_ext); //make a call
}
}
if (cmd != '') { send_cmd('exec.php?cmd='+escape(cmd)); }
refresh_start();
}
//refresh controls
function refresh_stop() {
clearInterval(interval_timer_id);
}
function refresh_start() {
interval_timer_id = setInterval(function(){new loadXmlHttp(source_url + '&group=' + ((document.getElementById('group')) ? document.getElementById('group').options[document.getElementById('group').selectedIndex].value : '') <?php if (isset($_GET['debug'])) { echo "+ '&debug'"; } ?>, 'ajax_reponse');}, refresh);
}
//call destination
function call_destination(from_ext, destination) {
if (destination != '') {
cmd = get_originate_cmd(from_ext+'@<?=$_SESSION["domain_name"]?>', destination); //make a call
}
if (cmd != '') { send_cmd('exec.php?cmd='+escape(cmd)); }
refresh_start();
}
//used by call control and ajax refresh functions
function send_cmd(url) {
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET",url,false);
xmlhttp.send(null);
document.getElementById('cmd_reponse').innerHTML=xmlhttp.responseText;
}
<?php
//hide/show destination input field
echo "function toggle_destination(ext) {\n";
echo " refresh_stop();\n";
echo " $('#destination_'+ext).fadeToggle(200, function(){\n";
echo " if ($('#destination_'+ext).is(':visible')) {\n";
echo " $('#destination_'+ext).focus();\n";
echo " }\n";
echo " else {\n";
echo " $('#destination_'+ext).val('');\n";
echo " refresh_start();\n";
echo " }\n";
echo " });\n";
echo "}\n";
echo "function get_transfer_cmd(uuid, destination) {\n";
echo " cmd = \"uuid_transfer \"+uuid+\" \"+destination+\" XML ".trim($_SESSION['user_context'])."\";\n";
echo " return cmd;\n";
echo "}\n";
echo "function get_originate_cmd(source, destination) {\n";
echo " cmd = \"bgapi originate {origination_caller_id_number=\"+destination+\"}user/\"+source+\" \"+destination+\" XML ".trim($_SESSION['user_context'])."\";\n";
echo " return cmd;\n";
echo "}\n";
echo "function get_record_cmd(uuid) {\n";
echo " cmd = \"uuid_record \"+uuid+\" start ".$_SESSION['switch']['recordings']['dir']."/archive/".date("Y")."/".date("M")."/".date("d")."/\"+uuid+\".wav\";\n";
echo " return cmd;\n";
echo "}\n";
?>
</script>
<style type="text/css">
DIV.ext {
float: left;
width: 235px;
margin: 0px 10px 10px 0px;
padding: 0px;
border-style: solid;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
-webkit-box-shadow: 0 0 3px #e5e9f0;
-moz-box-shadow: 0 0 3px #e5e9f0;
box-shadow: 0 0 3px #e5e9f0;
border-width: 1px 3px;
border-color: #b9c5d8 #c5d1e5;
background-color: #e5eaf5;
cursor: default;
}
DIV.state_active {
background-color: #baf4bb;
border-width: 1px 3px;
border-color: #77d779;
}
DIV.state_ringing {
background-color: #a8dbf0;
border-width: 1px 3px;
border-color: #41b9eb;
}
TABLE {
border-spacing: 0px;
border-collapse: collapse; //or 'separate'
border: none;
}
TABLE.ext {
width: 100%;
height: 60px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
background-color: #e5eaf5;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
TD.ext_icon {
vertical-align: middle;
/*background: rgba(255, 255, 255, 0.5); */
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
IMG.ext_icon {
cursor: move;
width: 39px;
height: 42px;
border: none;
}
TD.ext_info {
text-align: left;
vertical-align: top;
font-family: arial;
font-size: 10px;
overflow: auto;
width: 100%;
padding: 3px 5px 3px 7px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
background-color: #f0f2f6;
}
TD.state_ringing {
background-color: #d1f1ff;
}
TD.state_active {
background-color: #e1ffe2;
}
TABLE.state_ringing {
background-color: #a8dbf0;
}
TABLE.state_active {
background-color: #baf4bb;
}
.user_info {
font-family: arial;
font-size: 10px;
display: inline-block;
}
.user_info strong {
color: #3164AD;
}
.caller_info {
display: block;
margin-top: 7px;
font-family: arial;
font-size: 10px;
}
.call_info {
display: inline-block;
padding: 0px;
font-family: arial;
font-size: 10px;
}
</style>
<?php
//create simple array of users own extensions
foreach ($_SESSION['user']['extension'] as $assigned_extensions) {
$_SESSION['user']['extensions'][] = $assigned_extensions['user'];
}
if (isset($_GET['debug'])) {
echo "<div id='drop_action' style='display: none;'></div>";
echo "<div id='cmd_reponse' style='display: none;'></div>";
}
echo "<div id='ajax_reponse'>";
// include("index_inc.php");
echo "</div>\n";
echo "<br><br>";
require_once "resources/footer.php";
?>

View File

@@ -0,0 +1,267 @@
<?php
/*
FusionPBX
Version: MPL 1.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is FusionPBX
The Initial Developer of the Original Code is
Mark J Crane <markjcrane@fusionpbx.com>
Portions created by the Initial Developer are Copyright (C) 2008-2012
the Initial Developer. All Rights Reserved.
Contributor(s):
Mark J Crane <markjcrane@fusionpbx.com>
*/
include "root.php";
require_once "resources/require.php";
require_once "resources/check_auth.php";
require_once "resources/functions/get_call_activity.php";
if (permission_exists('extensions_active_view')) {
//access granted
}
else {
echo "access denied";
exit;
}
//add multi-lingual support
include "app_languages.php";
foreach($text as $key => $value) {
$text[$key] = $value[$_SESSION['domain']['language']['code']];
}
$activity = get_call_activity();
foreach ($activity as $extension => $fields) {
if (substr_count($fields['call_group'], ',')) {
$tmp = explode(',', $fields['call_group']);
foreach ($tmp as $tmp_index => $tmp_value) {
if (trim($tmp_value) == '') { unset($tmp[$tmp_index]); }
else { $groups[] = $tmp_value; }
}
}
else if ($fields['call_group'] != '') {
$groups[] = $fields['call_group'];
}
}
$groups = array_unique($groups);
sort($groups);
echo "<table cellpadding='0' cellspacing='0' border='0' align='right'>";
echo " <tr>";
echo " <td>";
if (sizeof($groups) > 0) {
echo $text['label-call_group']." ";
echo " <select id='group' class='formfld' onchange='refresh_start();' onfocus='refresh_stop();' onblur='refresh_start();'>\n";
echo " <option value=''></option>";
foreach ($groups as $group) {
echo " <option value='".$group."' ".(($_REQUEST['group'] == $group) ? "selected" : null).">".$group."</option>\n";
}
echo " </select>\n";
}
echo " </td>";
echo " </tr>";
echo "</table>";
echo "<b>".$text['title-operator_panel']."</b>";
echo "<br><br><br>";
foreach ($activity as $extension => $ext) {
unset($block);
//filter by group, if defined
if ($_REQUEST['group'] != '' && substr_count($ext['call_group'], $_REQUEST['group']) == 0 && !in_array($extension, $_SESSION['user']['extensions'])) { continue; }
//check if feature code being called
$format_number = (substr($ext['dest'], 0, 1) == '*') ? false : true;
//determine extension state, direction icon, and displayed name/number for caller/callee
if ($ext['state'] == 'CS_EXECUTE') {
if (($ext['callstate'] == 'RINGING' || $ext['callstate'] == 'EARLY' || $ext['callstate'] == 'RING_WAIT') && $ext['direction'] == 'inbound') {
$ext_state = 'ringing';
}
else if ($ext['callstate'] == 'ACTIVE' && $ext['direction'] == 'outbound') {
$ext_state = 'active';
}
else if ($ext['callstate'] == 'RING_WAIT' && $ext['direction'] == 'outbound') {
$ext_state = 'ringing';
}
else if ($ext['callstate'] == 'ACTIVE' && $ext['direction'] == 'inbound') {
$ext_state = 'active';
}
if (!$format_number) {
$call_name = 'System';
$call_number = $ext['dest'];
}
else {
$call_name = $activity[(int) $ext['dest']]['effective_caller_id_name'];
$call_number = format_phone((int) $ext['dest']);
}
$dir_icon = 'outbound';
}
else if ($ext['state'] == 'CS_CONSUME_MEDIA' || $ext['state'] == 'CS_EXCHANGE_MEDIA') {
if ($ext['state'] == 'CS_CONSUME_MEDIA' && $ext['callstate'] == 'RINGING' && $ext['direction'] == 'outbound') {
$ext_state = 'ringing';
}
else if ($ext['state'] == 'CS_EXCHANGE_MEDIA' && $ext['callstate'] == 'ACTIVE' && $ext['direction'] == 'outbound') {
$ext_state = 'active';
}
$dir_icon = 'inbound';
$call_name = $activity[(int) $ext['cid_num']]['effective_caller_id_name'];
$call_number = format_phone((int) $ext['cid_num']);
}
else {
unset($ext_state, $dir_icon, $call_name, $call_number);
}
//determine block style by state (if any)
$style = ($ext_state != '') ? "state_".$ext_state : null;
//determine the call identifier passed on drop
if ($ext['uuid'] == $ext['call_uuid'] && $ext['variable_bridge_uuid'] == '') { // transfer an outbound internal call
$call_identifier = $activity[$call_number]['uuid'];
}
else if (($ext['variable_call_direction'] == 'outbound' || $ext['variable_call_direction'] == 'local') && $ext['variable_bridge_uuid'] != '') { // transfer an outbound external call
$call_identifier = $ext['variable_bridge_uuid'];
}
else {
$call_identifier = $ext['call_uuid']; // transfer all other call types
}
//determine extension draggable state
if (!in_array($extension, $_SESSION['user']['extensions']) && $ext_state != "ringing") {
$draggable = false;
}
else if ($ext['uuid'] != '' && $ext['call_uuid'] == $ext['uuid'] && $ext['variable_bridge_uuid'] == '') {
$draggable = false;
}
else if ($ext_state == 'ringing' && $ext['variable_call_direction'] == 'local') {
$draggable = false;
}
else if ($ext_state != '' && !$format_number) {
$draggable = false;
}
else {
$draggable = true;
}
$block .= "<div id='".$extension."' class='ext ".$style."' ".(($ext_state != 'active' && $ext_state != 'ringing') ? "ondrop='drop(event, this.id);' ondragover='allowDrop(event, this.id);' ondragleave='discardDrop(event, this.id);'" : null).">"; // TO
$block .= "<table class='ext ".$style."'>";
$block .= " <tr>";
$block .= " <td class='ext_icon'>";
$block .= " <span id='".$extension."'>"; // FROM
$block .= "<img id='".$call_identifier."' class='ext_icon' src='resources/images/person.png' ".(($draggable) ? "draggable='true' ondragstart='drag(event, this.parentNode.id);' " : "draggable='false' style='cursor: not-allowed;'").">";
$block .= "</span>";
$block .= " </td>";
$block .= " <td class='ext_info ".$style."'>";
if ($dir_icon != '') {
$block .= " <img src='resources/images/".$dir_icon.".png' align='right' style='margin-top: 2px; width: 12px; height: 12px;' draggable='false'>";
}
$block .= " <span class='user_info'>";
if ($ext['effective_caller_id_name'] != '' && $ext['effective_caller_id_name'] != $extension) {
$block .= " <strong class='strong'>".$ext['effective_caller_id_name']."</strong> (".$extension.")";
}
else {
$block .= " <strong class='strong'>".$extension."</strong>";
}
$block .= " </span><br>";
if ($ext_state != '') {
$block .= " <span class='caller_info'>";
$block .= " <table align='right'><tr><td><span class='call_info'>".$ext['call_length']."</span></td></tr></table>";
$block .= " <strong>".$call_name."</strong><br>".$call_number;
$block .= " </span>";
}
else {
if (in_array($extension, $_SESSION['user']['extensions'])) {
$block .= " <img src='resources/images/keypad.png' style='width: 12px; height: 12px; border: none; margin-top: 26px; cursor: pointer;' align='right' onclick=\"toggle_destination('".$extension."');\">";
$block .= " <form onsubmit=\"call_destination('".$extension."', document.getElementById('destination_".$extension."').value); return false;\">";
$block .= " <input type='text' class='formfld' name='destination' id='destination_".$extension."' style='width: 110px; min-width: 110px; max-width: 110px; margin-top: 10px; text-align: center; display: none;' onblur=\"if (this.value == '') { refresh_start(); }\">";
$block .= " </form>";
}
}
$block .= " </td>";
$block .= " </tr>";
$block .= "</table>";
if (isset($_GET['debug'])) {
$block .= "<span style='font-size: 10px;'>";
$block .= "From ID<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong style='color: maroon'>".$extension."</strong><br>";
$block .= "uuid<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong style='color: ".($call_identifier == $ext['uuid'] ? 'blue' : 'black').";'>".$ext['uuid']."</strong><br>";
$block .= "call_uuid<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong style='color: ".($call_identifier == $ext['call_uuid'] ? 'blue' : 'black').";'>".$ext['call_uuid']."</strong><br>";
$block .= "variable_bridge_uuid<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong style='color: ".($call_identifier == $ext['variable_bridge_uuid'] ? 'blue' : 'black').";'>".$ext['variable_bridge_uuid']."</strong><br>";
$block .= "direction<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong style='color: black;'>".$ext['direction']."</strong><br>";
$block .= "variable_call_direction<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong style='color: black;'>".$ext['variable_call_direction']."</strong><br>";
$block .= "state<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong style='color: black;'>".$ext['state']."</strong><br>";
$block .= "cid_num<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong style='color: black;'>".$ext['cid_num']."</strong><br>";
$block .= "dest<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong style='color: black;'>".$ext['dest']."</strong><br>";
$block .= "context<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong style='color: black;'>".$ext['context']."</strong><br>";
$block .= "presence_id<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong style='color: black;'>".$ext['presence_id']."</strong><br>";
$block .= "callstate<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong style='color: black;'>".$ext['callstate']."</strong><br>";
$block .= "</span>";
}
$block .= "</div>";
if (in_array($extension, $_SESSION['user']['extensions'])) {
$user_extensions[] = $block;
}
else {
$other_extensions[] = $block;
}
}
if (sizeof($user_extensions) > 0) {
echo "<table width='100%'><tr><td>";
foreach ($user_extensions as $ext_block) {
echo $ext_block;
}
echo "</td></tr></table>";
}
if ($_REQUEST['group'] != '') {
echo "<br>";
echo "<strong style='color: black;'>".ucwords($_REQUEST['group'])."</strong>";
echo "<br><br>";
}
else if (sizeof($user_extensions) > 0) {
echo "<br>";
echo "<strong style='color: black;'>".$text['label-other_extensions']."</strong>";
echo "<br><br>";
}
if (sizeof($other_extensions) > 0) {
echo "<table width='100%'><tr><td>";
foreach ($other_extensions as $ext_block) {
echo $ext_block;
}
echo "</td></tr></table>";
}
else {
echo $text['label-no_extensions_found'];
}
echo "<br><br>";
if (isset($_GET['debug'])) {
echo "<textarea style='width: 100%; height: 600px; overflow: scroll;' onfocus='refresh_stop();' onblur='refresh_start();'>";
print_r($activity);
echo "</textarea>";
echo "<br><br>";
echo '$_SESSION...';
echo "<textarea style='width: 100%; height: 600px; overflow: scroll;' onfocus='refresh_stop();' onblur='refresh_start();'>";
print_r($_SESSION);
echo "</textarea>";
}
?>

View File

@@ -0,0 +1,150 @@
<?
function get_call_activity() {
global $db;
//get the extensions
$sql = "select extension, number_alias, effective_caller_id_name, effective_caller_id_number, call_group, description from v_extensions ";
$sql .= "where domain_uuid = '".$_SESSION['domain_uuid']."' ";
$sql .= "order by extension asc ";
$prep_statement = $db->prepare($sql);
$prep_statement->execute();
$extensions = $prep_statement->fetchAll(PDO::FETCH_NAMED);
unset ($prep_statement, $sql);
//send the command
$fp = event_socket_create($_SESSION['event_socket_ip_address'], $_SESSION['event_socket_port'], $_SESSION['event_socket_password']);
if ($fp) {
$switch_cmd = 'show channels as json';
$switch_result = event_socket_request($fp, 'api '.$switch_cmd);
$json_array = json_decode($switch_result, true);
}
//build the response
$x = 0;
foreach($extensions as &$row) {
//add the extension details
$array[$x] = $row;
//set the call detail defaults
$array[$x]["uuid"] = null;
$array[$x]["direction"] = null;
$array[$x]["created"] = null;
$array[$x]["created_epoch"] = null;
$array[$x]["name"] = null;
$array[$x]["state"] = null;
$array[$x]["cid_name"] = null;
$array[$x]["cid_num"] = null;
$array[$x]["ip_addr"] = null;
$array[$x]["dest"] = null;
$array[$x]["application"] = null;
$array[$x]["application_data"] = null;
$array[$x]["dialplan"] = null;
$array[$x]["context"] = null;
$array[$x]["read_codec"] = null;
$array[$x]["read_rate"] = null;
$array[$x]["read_bit_rate"] = null;
$array[$x]["write_codec"] = null;
$array[$x]["write_rate"] = null;
$array[$x]["write_bit_rate"] = null;
$array[$x]["secure"] = null;
$array[$x]["hostname"] = null;
$array[$x]["presence_id"] = null;
$array[$x]["presence_data"] = null;
$array[$x]["callstate"] = null;
$array[$x]["callee_name"] = null;
$array[$x]["callee_num"] = null;
$array[$x]["callee_direction"] = null;
$array[$x]["call_uuid"] = null;
$array[$x]["sent_callee_name"] = null;
$array[$x]["sent_callee_num"] = null;
//add the active call details
$found = false;
foreach($json_array['rows'] as &$field) {
$presence_id = $field['presence_id'];
$presence = explode("@", $presence_id);
$presence_id = $presence[0];
$presence_domain = $presence[1];
if ($row['extension'] == $presence_id) {
if ($presence_domain == $_SESSION['domain_name']) {
$found = true;
break;
}
}
}
//normalize the array
if ($found) {
$array[$x]["uuid"] = $field['uuid'];
$array[$x]["direction"] = $field['direction'];
$array[$x]["created"] = $field['created'];
$array[$x]["created_epoch"] = $field['created_epoch'];
$array[$x]["name"] = $field['name'];
$array[$x]["state"] = $field['state'];
$array[$x]["cid_name"] = $field['cid_name'];
$array[$x]["cid_num"] = $field['cid_num'];
$array[$x]["ip_addr"] = $field['ip_addr'];
$array[$x]["dest"] = $field['dest'];
$array[$x]["application"] = $field['application'];
$array[$x]["application_data"] = $field['application_data'];
$array[$x]["dialplan"] = $field['dialplan'];
$array[$x]["context"] = $field['context'];
$array[$x]["read_codec"] = $field['read_codec'];
$array[$x]["read_rate"] = $field['read_rate'];
$array[$x]["read_bit_rate"] = $field['read_bit_rate'];
$array[$x]["write_codec"] = $field['write_codec'];
$array[$x]["write_rate"] = $field['write_rate'];
$array[$x]["write_bit_rate"] = $field['write_bit_rate'];
$array[$x]["secure"] = $field['secure'];
$array[$x]["hostname"] = $field['hostname'];
$array[$x]["presence_id"] = $field['presence_id'];
$array[$x]["presence_data"] = $field['presence_data'];
$array[$x]["callstate"] = $field['callstate'];
$array[$x]["callee_name"] = $field['callee_name'];
$array[$x]["callee_num"] = $field['callee_num'];
$array[$x]["callee_direction"] = $field['callee_direction'];
$array[$x]["call_uuid"] = $field['call_uuid'];
$array[$x]["sent_callee_name"] = $field['sent_callee_name'];
$array[$x]["sent_callee_num"] = $field['sent_callee_num'];
//calculate and set the call length
$call_length_seconds = time() - $array[$x]["created_epoch"];
$call_length_hour = floor($call_length_seconds/3600);
$call_length_min = floor($call_length_seconds/60 - ($call_length_hour * 60));
$call_length_sec = $call_length_seconds - (($call_length_hour * 3600) + ($call_length_min * 60));
$call_length_min = sprintf("%02d", $call_length_min);
$call_length_sec = sprintf("%02d", $call_length_sec);
$call_length = $call_length_hour.':'.$call_length_min.':'.$call_length_sec;
$array[$x]['call_length'] = $call_length;
//send the command
if ($field['state'] != '') {
if ($fp) {
$switch_cmd = 'uuid_dump '.$field['uuid'].' json';
$dump_result = event_socket_request($fp, 'api '.$switch_cmd);
$dump_array = json_decode($dump_result, true);
foreach ($dump_array as $dump_var_name => $dump_var_value) {
$array[$x][$dump_var_name] = trim($dump_var_value);
}
}
}
}
//increment the row
$x++;
}
//reindex array using extension instead of auto-incremented value
foreach ($array as $index => $subarray) {
foreach ($subarray as $field => $value) {
$array[$subarray['extension']][$field] = $array[$index][$field];
unset($array[$index][$field]);
}
unset($array[$subarray['extension']]['extension']);
unset($array[$index]);
}
//return array
return $array;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,50 @@
<?php
/*
FusionPBX
Version: MPL 1.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is FusionPBX
The Initial Developer of the Original Code is
Mark J Crane <markjcrane@fusionpbx.com>
Portions created by the Initial Developer are Copyright (C) 2008-2012
the Initial Developer. All Rights Reserved.
Contributor(s):
Mark J Crane <markjcrane@fusionpbx.com>
*/
// make sure the PATH_SEPARATOR is defined
if (!defined("PATH_SEPARATOR")) {
if ( strpos( $_ENV[ "OS" ], "Win" ) !== false ) { define("PATH_SEPARATOR", ";"); } else { define("PATH_SEPARATOR", ":"); }
}
// make sure the document_root is set
$_SERVER["SCRIPT_FILENAME"] = str_replace("\\", "/", $_SERVER["SCRIPT_FILENAME"]);
$_SERVER["DOCUMENT_ROOT"] = str_replace($_SERVER["PHP_SELF"], "", $_SERVER["SCRIPT_FILENAME"]);
$_SERVER["DOCUMENT_ROOT"] = realpath($_SERVER["DOCUMENT_ROOT"]);
//echo "DOCUMENT_ROOT: ".$_SERVER["DOCUMENT_ROOT"]."<br />\n";
//echo "PHP_SELF: ".$_SERVER["PHP_SELF"]."<br />\n";
//echo "SCRIPT_FILENAME: ".$_SERVER["SCRIPT_FILENAME"]."<br />\n";
// if the project directory exists then add it to the include path otherwise add the document root to the include path
if (is_dir($_SERVER["DOCUMENT_ROOT"].'/fusionpbx')){
if(!defined('PROJECT_PATH')) { define('PROJECT_PATH', '/fusionpbx'); }
set_include_path( get_include_path() . PATH_SEPARATOR . $_SERVER["DOCUMENT_ROOT"].'/fusionpbx' );
}
else {
if(!defined('PROJECT_PATH')) { define('PROJECT_PATH', ''); }
set_include_path( get_include_path() . PATH_SEPARATOR . $_SERVER['DOCUMENT_ROOT'] );
}
?>