added webphone by default
This commit is contained in:
parent
dac32573d0
commit
96f7216c1f
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
//application details
|
||||
$apps[$x]['name'] = "webphone";
|
||||
$apps[$x]['uuid'] = "29ad51b0-6ab0-4d65-9394-629d1a34580b";
|
||||
$apps[$x]['category'] = "Vendor";
|
||||
$apps[$x]['subcategory'] = "";
|
||||
$apps[$x]['version'] = "1.0";
|
||||
$apps[$x]['license'] = "Mozilla Public License 1.1";
|
||||
$apps[$x]['url'] = "http://www.fusionpbx.com";
|
||||
$apps[$x]['description']['en-us'] = "Web Phone";
|
||||
$apps[$x]['description']['en-gb'] = "";
|
||||
$apps[$x]['description']['ar-eg'] = "";
|
||||
$apps[$x]['description']['de-at'] = "";
|
||||
$apps[$x]['description']['de-ch'] = "";
|
||||
$apps[$x]['description']['de-de'] = "";
|
||||
$apps[$x]['description']['es-cl'] = "";
|
||||
$apps[$x]['description']['es-mx'] = "";
|
||||
$apps[$x]['description']['fr-ca'] = "";
|
||||
$apps[$x]['description']['fr-fr'] = "";
|
||||
$apps[$x]['description']['he-il'] = "";
|
||||
$apps[$x]['description']['it-it'] = "";
|
||||
$apps[$x]['description']['nl-nl'] = "";
|
||||
$apps[$x]['description']['pl-pl'] = "";
|
||||
$apps[$x]['description']['pt-br'] = "";
|
||||
$apps[$x]['description']['pt-pt'] = "";
|
||||
$apps[$x]['description']['ro-ro'] = "";
|
||||
$apps[$x]['description']['ru-ru'] = "";
|
||||
$apps[$x]['description']['sv-se'] = "";
|
||||
$apps[$x]['description']['uk-ua'] = "";
|
||||
|
||||
//permission details
|
||||
$y=0;
|
||||
$apps[$x]['permissions'][$y]['name'] = "webphone_view";
|
||||
//$apps[$x]['permissions'][$y]['menu']['uuid'] = "000ed55e-7fbc-40b5-9631-506d0b6056b4";
|
||||
$apps[$x]['permissions'][$y]['groups'][] = "superadmin";
|
||||
$apps[$x]['permissions'][$y]['groups'][] = "admin";
|
||||
$apps[$x]['permissions'][$y]['groups'][] = "user";
|
||||
$apps[$x]['permissions'][$y]['groups'][] = "agent";
|
||||
|
||||
?>
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
$text['title-webphone']['en-us'] = "WebPhone";
|
||||
$text['title-webphone']['ar-eg'] = "ة";
|
||||
$text['title-webphone']['de-at'] = ""; //copied from de-de
|
||||
$text['title-webphone']['de-ch'] = ""; //copied from de-de
|
||||
$text['title-webphone']['de-de'] = "";
|
||||
$text['title-webphone']['es-cl'] = "";
|
||||
$text['title-webphone']['es-mx'] = ""; //copied from es-cl
|
||||
$text['title-webphone']['fr-ca'] = ""; //copied from fr-fr
|
||||
$text['title-webphone']['fr-fr'] = "";
|
||||
$text['title-webphone']['he-il'] = "";
|
||||
$text['title-webphone']['it-it'] = "";
|
||||
$text['title-webphone']['nl-nl'] = "";
|
||||
$text['title-webphone']['pl-pl'] = "";
|
||||
$text['title-webphone']['pt-br'] = ""; //copied from pt-pt
|
||||
$text['title-webphone']['pt-pt'] = "";
|
||||
$text['title-webphone']['ro-ro'] = "";
|
||||
$text['title-webphone']['ru-ru'] = "";
|
||||
$text['title-webphone']['sv-se'] = "";
|
||||
$text['title-webphone']['uk-ua'] = "";
|
||||
|
||||
|
||||
$text['title-description-webphone']['en-us'] = "Webphone is a simple browser-based phone. Select an extension and click 'Launch'";
|
||||
$text['title-description-webphone']['ar-eg'] = "ة";
|
||||
$text['title-description-webphone']['de-at'] = ""; //copied from de-de
|
||||
$text['title-description-webphone']['de-ch'] = ""; //copied from de-de
|
||||
$text['title-description-webphone']['de-de'] = "";
|
||||
$text['title-description-webphone']['es-cl'] = "";
|
||||
$text['title-description-webphone']['es-mx'] = ""; //copied from es-cl
|
||||
$text['title-description-webphone']['fr-ca'] = ""; //copied from fr-fr
|
||||
$text['title-description-webphone']['fr-fr'] = "";
|
||||
$text['title-description-webphone']['he-il'] = "";
|
||||
$text['title-description-webphone']['it-it'] = "";
|
||||
$text['title-description-webphone']['nl-nl'] = "";
|
||||
$text['title-description-webphone']['pl-pl'] = "";
|
||||
$text['title-description-webphone']['pt-br'] = ""; //copied from pt-pt
|
||||
$text['title-description-webphone']['pt-pt'] = "";
|
||||
$text['title-description-webphone']['ro-ro'] = "";
|
||||
$text['title-description-webphone']['ru-ru'] = "";
|
||||
$text['title-description-webphone']['sv-se'] = "";
|
||||
$text['title-description-webphone']['uk-ua'] = "";
|
||||
|
||||
$text['label-select_extension']['en-us'] = "Select Extension";
|
||||
$text['label-select_extension']['ar-eg'] = "ة";
|
||||
$text['label-select_extension']['de-at'] = ""; //copied from de-de
|
||||
$text['label-select_extension']['de-ch'] = ""; //copied from de-de
|
||||
$text['label-select_extension']['de-de'] = "";
|
||||
$text['label-select_extension']['es-cl'] = "";
|
||||
$text['label-select_extension']['es-mx'] = ""; //copied from es-cl
|
||||
$text['label-select_extension']['fr-ca'] = ""; //copied from fr-fr
|
||||
$text['label-select_extension']['fr-fr'] = "";
|
||||
$text['label-select_extension']['he-il'] = "";
|
||||
$text['label-select_extension']['it-it'] = "";
|
||||
$text['label-select_extension']['nl-nl'] = "";
|
||||
$text['label-select_extension']['pl-pl'] = "";
|
||||
$text['label-select_extension']['pt-br'] = ""; //copied from pt-pt
|
||||
$text['label-select_extension']['pt-pt'] = "";
|
||||
$text['label-select_extension']['ro-ro'] = "";
|
||||
$text['label-select_extension']['ru-ru'] = "";
|
||||
$text['label-select_extension']['sv-se'] = "";
|
||||
$text['label-select_extension']['uk-ua'] = "";
|
||||
|
||||
|
||||
$text['label-webphone_launch']['en-us'] = "Launch";
|
||||
$text['label-webphone_launch']['ar-eg'] = "ة";
|
||||
$text['label-webphone_launch']['de-at'] = ""; //copied from de-de
|
||||
$text['label-webphone_launch']['de-ch'] = ""; //copied from de-de
|
||||
$text['label-webphone_launch']['de-de'] = "";
|
||||
$text['label-webphone_launch']['es-cl'] = "";
|
||||
$text['label-webphone_launch']['es-mx'] = ""; //copied from es-cl
|
||||
$text['label-webphone_launch']['fr-ca'] = ""; //copied from fr-fr
|
||||
$text['label-webphone_launch']['fr-fr'] = "";
|
||||
$text['label-webphone_launch']['he-il'] = "";
|
||||
$text['label-webphone_launch']['it-it'] = "";
|
||||
$text['label-webphone_launch']['nl-nl'] = "";
|
||||
$text['label-webphone_launch']['pl-pl'] = "";
|
||||
$text['label-webphone_launch']['pt-br'] = ""; //copied from pt-pt
|
||||
$text['label-webphone_launch']['pt-pt'] = "";
|
||||
$text['label-webphone_launch']['ro-ro'] = "";
|
||||
$text['label-webphone_launch']['ru-ru'] = "";
|
||||
$text['label-webphone_launch']['sv-se'] = "";
|
||||
$text['label-webphone_launch']['uk-ua'] = "";
|
||||
?>
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
$apps[$x]['menu'][0]['title']['en-us'] = "WebPhone";
|
||||
$apps[$x]['menu'][0]['uuid'] = "b08f5f87-8a66-4c29-b1e6-eb0c374d58f2";
|
||||
$apps[$x]['menu'][0]['parent_uuid'] = "";
|
||||
$apps[$x]['menu'][0]['category'] = "internal";
|
||||
$apps[$x]['menu'][0]['icon'] = "fa-phone";
|
||||
$apps[$x]['menu'][0]['path'] = "/app/webphone/webphone.php";
|
||||
$apps[$x]['menu'][0]['order'] = "28";
|
||||
$apps[$x]['menu'][0]['groups'][] = "admin";
|
||||
$apps[$x]['menu'][0]['groups'][] = "superadmin";
|
||||
$apps[$x]['menu'][0]['groups'][] = "user";
|
||||
$apps[$x]['menu'][0]['groups'][] = "agent";
|
||||
|
||||
?>
|
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
Binary file not shown.
After Width: | Height: | Size: 438 B |
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
|
@ -0,0 +1,85 @@
|
|||
#sipClient {
|
||||
background-color: #333;
|
||||
font-size: 13px;
|
||||
line-height: 1.42857143;
|
||||
/* firefox 19+ */
|
||||
/* ie */
|
||||
}
|
||||
#sipClient p {
|
||||
margin: 0;
|
||||
padding: 0 0 10px 0;
|
||||
line-height: 18px;
|
||||
}
|
||||
#sipClient .sipStatus {
|
||||
margin: 0 -15px 15px -15px;
|
||||
padding: 5px 15px;
|
||||
background-color: #111;
|
||||
color: #999;
|
||||
}
|
||||
#sipClient #txtCallStatus {
|
||||
color: #fff;
|
||||
}
|
||||
#sipClient #sip-dialpad {
|
||||
width: 292px;
|
||||
padding: 16px 20px;
|
||||
}
|
||||
#sipClient #sip-dialpad .col-xs-4 {
|
||||
text-align: center;
|
||||
}
|
||||
#sipClient .digit {
|
||||
height: 66px;
|
||||
width: 66px;
|
||||
margin: 0 8px 14px !important;
|
||||
background-color: #f8f8f8;
|
||||
font-weight: 300;
|
||||
font-size: 24px;
|
||||
border-radius: 100px;
|
||||
line-height: 21px;
|
||||
padding-top: 9px;
|
||||
float: left;
|
||||
}
|
||||
#sipClient .digit span {
|
||||
display: block;
|
||||
color: #999;
|
||||
font-size: 10px;
|
||||
font-weight: normal;
|
||||
}
|
||||
#sipClient .sip-panel h3 {
|
||||
margin-top: 22px;
|
||||
}
|
||||
#sipClient #sip-splash {
|
||||
height: 371px;
|
||||
}
|
||||
#sipClient #sip-splash .fa {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
#sipClient #sip-splash .fa-circle {
|
||||
color: #5cb85c;
|
||||
}
|
||||
#sipClient #sip-log .panel-heading {
|
||||
padding: 10px 8px;
|
||||
}
|
||||
#sipClient #sip-logitems {
|
||||
height: 332px;
|
||||
overflow: auto;
|
||||
}
|
||||
#sipClient #sldVolume {
|
||||
width: 140px;
|
||||
margin: 0 auto;
|
||||
box-shadow: none;
|
||||
}
|
||||
#sipClient .sip-logitem {
|
||||
padding: 4px;
|
||||
}
|
||||
#sipClient #numDisplay::-webkit-input-placeholder {
|
||||
color: #bbb;
|
||||
}
|
||||
#sipClient #numDisplay::-moz-placeholder {
|
||||
color: #bbb;
|
||||
}
|
||||
#sipClient #numDisplay::-ms-input-placeholder {
|
||||
color: #bbb;
|
||||
}
|
||||
#sipClient #numDisplay::-moz-placeholder {
|
||||
color: #bbb;
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
#sipClient {
|
||||
|
||||
background-color : #333;
|
||||
font-size : 13px;
|
||||
line-height : 1.42857143;
|
||||
|
||||
p {
|
||||
margin : 0;
|
||||
padding : 0 0 10px 0;
|
||||
line-height : 18px;
|
||||
}
|
||||
|
||||
.sipStatus {
|
||||
margin : 0 -15px 15px -15px;
|
||||
padding : 5px 15px;
|
||||
background-color : #111;
|
||||
color : #999;
|
||||
}
|
||||
|
||||
#txtCallStatus { color : #fff; }
|
||||
|
||||
#sip-dialpad {
|
||||
width : 292px;
|
||||
padding : 16px 20px;
|
||||
}
|
||||
|
||||
#sip-dialpad .col-xs-4 { text-align : center; }
|
||||
|
||||
.digit {
|
||||
height : 66px;
|
||||
width : 66px;
|
||||
margin : 0 8px 14px !important;
|
||||
background-color : #f8f8f8;
|
||||
font-weight : 300;
|
||||
font-size : 24px;
|
||||
border-radius : 100px;
|
||||
line-height : 21px;
|
||||
padding-top : 9px;
|
||||
float : left;
|
||||
|
||||
span {
|
||||
display : block;
|
||||
color : #999;
|
||||
font-size : 10px;
|
||||
font-weight : normal;
|
||||
}
|
||||
}
|
||||
|
||||
.sip-panel h3 { margin-top : 22px; }
|
||||
|
||||
#sip-splash {
|
||||
height : 371px;
|
||||
|
||||
.fa {
|
||||
margin-bottom : 15px;
|
||||
}
|
||||
|
||||
.fa-circle {
|
||||
color: #5cb85c;
|
||||
}
|
||||
}
|
||||
|
||||
#sip-log .panel-heading {
|
||||
padding : 10px 8px;
|
||||
}
|
||||
#sip-logitems {
|
||||
height : 332px;
|
||||
overflow : auto;
|
||||
}
|
||||
|
||||
#sldVolume {
|
||||
width : 140px;
|
||||
margin : 0 auto;
|
||||
box-shadow : none;
|
||||
}
|
||||
|
||||
.sip-logitem {
|
||||
padding : 4px;
|
||||
}
|
||||
|
||||
#numDisplay::-webkit-input-placeholder { color:#bbb; }
|
||||
#numDisplay::-moz-placeholder { color:#bbb; }
|
||||
#numDisplay::-ms-input-placeholder { color:#bbb; }
|
||||
#numDisplay::-moz-placeholder { color:#bbb; }
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<title>ctxSip</title>
|
||||
<link rel="icon" type="image/gif" href="img/favicon.ico" />
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css">
|
||||
<link href="css/ctxSip.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body id="sipClient">
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="clearfix sipStatus">
|
||||
<div id="txtCallStatus" class="pull-right"> </div>
|
||||
<div id="txtRegStatus"></div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" id="phoneUI">
|
||||
<div class="input-group">
|
||||
<div class="input-group-btn">
|
||||
<button class="btn btn-sm btn-primary dropdown-toggle" data-toggle="dropdown" title="Show Keypad">
|
||||
<i class="fa fa-th"></i>
|
||||
</button>
|
||||
<div id="sip-dialpad" class="dropdown-menu">
|
||||
<button type="button" class="btn btn-default digit" data-digit="1">1<span> </span></button>
|
||||
<button type="button" class="btn btn-default digit" data-digit="2">2<span>ABC</span></button>
|
||||
<button type="button" class="btn btn-default digit" data-digit="3">3<span>DEF</span></button>
|
||||
<button type="button" class="btn btn-default digit" data-digit="4">4<span>GHI</span></button>
|
||||
<button type="button" class="btn btn-default digit" data-digit="5">5<span>JKL</span></button>
|
||||
<button type="button" class="btn btn-default digit" data-digit="6">6<span>MNO</span></button>
|
||||
<button type="button" class="btn btn-default digit" data-digit="7">7<span>PQRS</span></button>
|
||||
<button type="button" class="btn btn-default digit" data-digit="8">8<span>TUV</span></button>
|
||||
<button type="button" class="btn btn-default digit" data-digit="9">9<span>WXYZ</span></button>
|
||||
<button type="button" class="btn btn-default digit" data-digit="*">*<span> </span></button>
|
||||
<button type="button" class="btn btn-default digit" data-digit="0">0<span>+</span></button>
|
||||
<button type="button" class="btn btn-default digit" data-digit="#">#<span> </span></button>
|
||||
<div class="clearfix"> </div>
|
||||
<button class="btn btn-success btn-block btnCall" title="Send">
|
||||
<i class="fa fa-play"></i> Send
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" name="number" id="numDisplay" class="form-control text-center input-sm" value="" placeholder="Enter number..." autocomplete="off" />
|
||||
<div class="input-group-btn input-group-btn-sm">
|
||||
<button class="btn btn-sm btn-primary dropdown-toggle" id="btnVol" data-toggle="dropdown" title="Volume">
|
||||
<i class="fa fa-fw fa-volume-up"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-right">
|
||||
<input type="range" min="0" max="100" value="100" step="1" id="sldVolume" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="well-sip">
|
||||
<div id="sip-splash" class="text-muted text-center panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h3 class="page-header">
|
||||
<span class="fa-stack fa-2x">
|
||||
<i class="fa fa-circle fa-stack-2x text-success"></i>
|
||||
<i class="fa fa-phone fa-stack-1x fa-inverse"></i>
|
||||
</span><br>
|
||||
This is your phone.</h3>
|
||||
<p class="lead">To make a call enter a number or SIP address in the box above.</p>
|
||||
<small>Closing this window will cause calls to go to voicemail.</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="sip-log" class="panel panel-default hide">
|
||||
<div class="panel-heading">
|
||||
<h4 class="text-muted panel-title">Recent Calls <span class="pull-right"><i class="fa fa-trash text-muted sipLogClear" title="Clear Log"></i></span></h4>
|
||||
</div>
|
||||
<div id="sip-logitems" class="list-group">
|
||||
<p class="text-muted text-center">No recent calls from this browser.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="mdlError" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Sip Error</h4>
|
||||
</div>
|
||||
<div class="modal-body text-center text-danger">
|
||||
<h3><i class="fa fa-3x fa-ban"></i></h3>
|
||||
<p class="lead">Sip registration failed. No calls can be handled.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<audio id="ringtone" src="sounds/incoming.mp3" loop></audio>
|
||||
<audio id="ringbacktone" src="sounds/outgoing.mp3" loop></audio>
|
||||
<audio id="dtmfTone" src="sounds/dtmf.mp3"></audio>
|
||||
<audio id="audioRemote"></audio>
|
||||
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="scripts/moment.js/moment.min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="scripts/SIP.js/sip.min.js"></script>
|
||||
<script type="text/javascript" src="scripts/config.js"></script>
|
||||
<script type="text/javascript" src="scripts/app.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,162 @@
|
|||
<?php
|
||||
|
||||
//includes
|
||||
require_once "root.php";
|
||||
require_once "resources/require.php";
|
||||
require_once "resources/check_auth.php";
|
||||
|
||||
//check permissions
|
||||
if (permission_exists('webphone_view')) {
|
||||
//access granted
|
||||
}
|
||||
else {
|
||||
echo "access denied";
|
||||
exit;
|
||||
}
|
||||
|
||||
//add multi-lingual support
|
||||
$language = new text;
|
||||
$text = $language->get();
|
||||
|
||||
|
||||
if (is_uuid($_GET['id'])) {
|
||||
$extension_uuid = $_GET['id'];
|
||||
}
|
||||
|
||||
//get the user ID
|
||||
$sql = "SELECT extension, password,effective_caller_id_name ";
|
||||
$sql .= "FROM v_extensions ";
|
||||
$sql .= "WHERE extension_uuid = '" . $extension_uuid . "' ";
|
||||
$sql .= "AND v_extensions.domain_uuid = '" . $_SESSION["domain_uuid"] . "' LIMIT 1";
|
||||
|
||||
$prep_statement = $db->prepare($sql);
|
||||
if ($prep_statement) {
|
||||
$prep_statement->execute();
|
||||
$row = $prep_statement->fetch(PDO::FETCH_ASSOC);
|
||||
$user_extension = $row['extension'];
|
||||
$user_password = $row['password'];
|
||||
$effective_caller_id_name = $row['effective_caller_id_name'];
|
||||
}
|
||||
|
||||
echo "<html lang='en'>\n";
|
||||
echo "<head>\n";
|
||||
echo " <meta charset='utf-8' />\n";
|
||||
echo " <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'>\n";
|
||||
echo " <title>ctxSip</title>\n";
|
||||
echo " <link rel='icon' type='image/gif' href='img/favicon.ico' />\n";
|
||||
echo " <link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css'>\n";
|
||||
echo " <link rel='stylesheet' href='//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css'>\n";
|
||||
echo " <link href='css/ctxSip.css' rel='stylesheet' type='text/css' />\n";
|
||||
echo "</head>\n";
|
||||
echo "<body id='sipClient'>\n";
|
||||
echo "<div class='container-fluid'>\n";
|
||||
|
||||
echo " <div class='clearfix sipStatus'>\n";
|
||||
echo " <div id='txtCallStatus' class='pull-right'> </div>\n";
|
||||
echo " <div id='txtRegStatus'></div>\n";
|
||||
echo " </div>\n";
|
||||
|
||||
echo " <div class='form-group' id='phoneUI'>\n";
|
||||
echo " <div class='input-group'>\n";
|
||||
echo " <div class='input-group-btn'>\n";
|
||||
echo " <button class='btn btn-sm btn-primary dropdown-toggle' data-toggle='dropdown' title='Show Keypad'>\n";
|
||||
echo " <i class='fa fa-th'></i>\n";
|
||||
echo " </button>\n";
|
||||
echo " <div id='sip-dialpad' class='dropdown-menu'>\n";
|
||||
echo " <button type='button' class='btn btn-default digit' data-digit='1'>1<span> </span></button>\n";
|
||||
echo " <button type='button' class='btn btn-default digit' data-digit='2'>2<span>ABC</span></button>\n";
|
||||
echo " <button type='button' class='btn btn-default digit' data-digit='3'>3<span>DEF</span></button>\n";
|
||||
echo " <button type='button' class='btn btn-default digit' data-digit='4'>4<span>GHI</span></button>\n";
|
||||
echo " <button type='button' class='btn btn-default digit' data-digit='5'>5<span>JKL</span></button>\n";
|
||||
echo " <button type='button' class='btn btn-default digit' data-digit='6'>6<span>MNO</span></button>\n";
|
||||
echo " <button type='button' class='btn btn-default digit' data-digit='7'>7<span>PQRS</span></button>\n";
|
||||
echo " <button type='button' class='btn btn-default digit' data-digit='8'>8<span>TUV</span></button>\n";
|
||||
echo " <button type='button' class='btn btn-default digit' data-digit='9'>9<span>WXYZ</span></button>\n";
|
||||
echo " <button type='button' class='btn btn-default digit' data-digit='*'>*<span> </span></button>\n";
|
||||
echo " <button type='button' class='btn btn-default digit' data-digit='0'>0<span>+</span></button>\n";
|
||||
echo " <button type='button' class='btn btn-default digit' data-digit='#'>#<span> </span></button>\n";
|
||||
echo " <div class='clearfix'> </div>\n";
|
||||
echo " <button class='btn btn-success btn-block btnCall' title='Send'>\n";
|
||||
echo " <i class='fa fa-play'></i> Send\n";
|
||||
echo " </button>\n";
|
||||
echo " </div>\n";
|
||||
echo " </div>\n";
|
||||
echo " <input type='text' name='number' id='numDisplay' class='form-control text-center input-sm' value='' placeholder='Enter number...' autocomplete='off' />\n";
|
||||
echo " <div class='input-group-btn input-group-btn-sm'>\n";
|
||||
echo " <button class='btn btn-sm btn-primary dropdown-toggle' id='btnVol' data-toggle='dropdown' title='Volume'>\n";
|
||||
echo " <i class='fa fa-fw fa-volume-up'></i>\n";
|
||||
echo " </button>\n";
|
||||
echo " <div class='dropdown-menu dropdown-menu-right'>\n";
|
||||
echo " <input type='range' min='0' max='100' value='100' step='1' id='sldVolume' />\n";
|
||||
echo " </div>\n";
|
||||
echo " </div>\n";
|
||||
echo " </div>\n";
|
||||
echo " </div>\n";
|
||||
|
||||
echo " <div class=well-sip'>\n";
|
||||
echo " <div id='sip-splash' class='text-muted text-center panel panel-default'>\n";
|
||||
echo " <div class='panel-body'>\n";
|
||||
echo " <h3 class='page-header'>\n";
|
||||
echo " <span class='fa-stack fa-2x'>\n";
|
||||
echo " <i class='fa fa-circle fa-stack-2x text-success'></i>\n";
|
||||
echo " <i class='fa fa-phone fa-stack-1x fa-inverse'></i>\n";
|
||||
echo " </span><br>\n";
|
||||
echo " This is your phone.</h3>\n";
|
||||
echo " <p class='lead'>To make a call enter a number in the box above.</p>\n";
|
||||
echo " <small>Closing this window will cause calls to go to voicemail.</small>\n";
|
||||
echo " </div>\n";
|
||||
echo " </div>\n";
|
||||
|
||||
echo " <div id='sip-log' class='panel panel-default hide'>\n";
|
||||
echo " <div class='panel-heading'>\n";
|
||||
echo " <h4 class='text-muted panel-title'>Recent Calls <span class='pull-right'><i class='fa fa-trash text-muted sipLogClear' title='Clear Log'></i></span></h4>\n";
|
||||
echo " </div>\n";
|
||||
echo " <div id='sip-logitems' class='list-group'>\n";
|
||||
echo " <p class='text-muted text-center'>No recent calls from this browser.</p>\n";
|
||||
echo " </div>\n";
|
||||
echo " </div>\n";
|
||||
echo " </div>\n";
|
||||
|
||||
echo " <div class='modal fade' id='mdlError' tabindex='-1' role='dialog' aria-hidden='true' data-backdrop='static' data-keyboard='false'>\n";
|
||||
echo " <div class='modal-dialog modal-sm'>\n";
|
||||
echo " <div class='modal-content'>\n";
|
||||
echo " <div class='modal-header'>\n";
|
||||
echo " <h4 class='modal-title'>Sip Error</h4>\n";
|
||||
echo " </div>\n";
|
||||
echo " <div class='modal-body text-center text-danger'>\n";
|
||||
echo " <h3><i class='fa fa-3x fa-ban'></i></h3>\n";
|
||||
echo " <p class='lead'>Sip registration failed. No calls can be handled.</p>\n";
|
||||
echo " </div>\n";
|
||||
echo " </div>\n";
|
||||
echo " </div>\n";
|
||||
echo " </div>\n";
|
||||
|
||||
echo "</div>\n";
|
||||
|
||||
echo "<audio id='ringtone' src='sounds/incoming.mp3' loop></audio>\n";
|
||||
echo "<audio id='ringbacktone' src='sounds/outgoing.mp3' loop></audio>\n";
|
||||
echo "<audio id='dtmfTone' src='sounds/dtmf.mp3'></audio>\n";
|
||||
echo "<audio id='audioRemote'></audio>\n";
|
||||
|
||||
echo "<script type='text/javascript' src='https://code.jquery.com/jquery-1.11.3.min.js'></script>\n";
|
||||
echo "<script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js'></script>\n";
|
||||
echo "<script type='text/javascript' src='scripts/moment.js/moment.min.js'></script>\n";
|
||||
|
||||
//echo "<script type='text/javascript' src='scripts/SIP.js/sip.min.js'></script>\n";
|
||||
echo "<script type='text/javascript' src='scripts/SIP.js/sip.js'></script>\n";
|
||||
//echo "<script type='text/javascript' src='scripts/config.js'></script>\n";
|
||||
|
||||
echo "<script type='text/javascript'>\n";
|
||||
echo "var user = {'User' : '" . $user_extension. "', ";
|
||||
echo " 'Pass' : '".$user_password."', ";
|
||||
echo " 'Realm' : '".$_SESSION["domain_name"]."', ";
|
||||
echo " 'Display' : '".$effective_caller_id_name."', ";
|
||||
echo " 'WSServer' : 'wss://".$_SESSION["domain_name"].":7443' ";
|
||||
echo "};\n";
|
||||
echo "</script>\n";
|
||||
|
||||
echo "<script type='text/javascript' src='scripts/app.js'></script>\n";
|
||||
|
||||
echo "</body>\n";
|
||||
//</html>
|
||||
?>
|
|
@ -0,0 +1,90 @@
|
|||
<?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
|
||||
umask(2);
|
||||
if (!defined("PATH_SEPARATOR")) {
|
||||
if (strpos($_ENV["OS"], "Win") !== false) {
|
||||
define("PATH_SEPARATOR", ";");
|
||||
} else {
|
||||
define("PATH_SEPARATOR", ":");
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($output_format)) $output_format = (PHP_SAPI == 'cli') ? 'text' : 'html';
|
||||
|
||||
// make sure the document_root is set
|
||||
$_SERVER["SCRIPT_FILENAME"] = str_replace("\\", '/', $_SERVER["SCRIPT_FILENAME"]);
|
||||
if(PHP_SAPI == 'cli'){
|
||||
chdir(pathinfo(realpath($_SERVER["PHP_SELF"]), PATHINFO_DIRNAME));
|
||||
$script_full_path = str_replace("\\", '/', getcwd() . '/' . $_SERVER["SCRIPT_FILENAME"]);
|
||||
$dirs = explode('/', pathinfo($script_full_path, PATHINFO_DIRNAME));
|
||||
if (file_exists('/project_root.php')) {
|
||||
$path = '/';
|
||||
} else {
|
||||
$i = 1;
|
||||
$path = '';
|
||||
while ($i < count($dirs)) {
|
||||
$path .= '/' . $dirs[$i];
|
||||
if (file_exists($path. '/project_root.php')) {
|
||||
break;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
$_SERVER["DOCUMENT_ROOT"] = $path;
|
||||
}else{
|
||||
$_SERVER["DOCUMENT_ROOT"] = str_replace($_SERVER["PHP_SELF"], "", $_SERVER["SCRIPT_FILENAME"]);
|
||||
}
|
||||
$_SERVER["DOCUMENT_ROOT"] = realpath($_SERVER["DOCUMENT_ROOT"]);
|
||||
// try to detect if a project path is being used
|
||||
if (!defined('PROJECT_PATH')) {
|
||||
if (is_dir($_SERVER["DOCUMENT_ROOT"]. '/fusionpbx')) {
|
||||
define('PROJECT_PATH', '/fusionpbx');
|
||||
} elseif (file_exists($_SERVER["DOCUMENT_ROOT"]. '/project_root.php')) {
|
||||
define('PROJECT_PATH', '');
|
||||
} else {
|
||||
$dirs = explode('/', str_replace('\\', '/', pathinfo($_SERVER["PHP_SELF"], PATHINFO_DIRNAME)));
|
||||
$i = 1;
|
||||
$path = $_SERVER["DOCUMENT_ROOT"];
|
||||
while ($i < count($dirs)) {
|
||||
$path .= '/' . $dirs[$i];
|
||||
if (file_exists($path. '/project_root.php')) {
|
||||
break;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
if(!file_exists($path. '/project_root.php')){
|
||||
die("Failed to locate the Project Root by searching for project_root.php please contact support for assistance");
|
||||
}
|
||||
$project_path = str_replace($_SERVER["DOCUMENT_ROOT"], "", $path);
|
||||
define('PROJECT_PATH', $project_path);
|
||||
}
|
||||
$_SERVER["PROJECT_ROOT"] = realpath($_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH);
|
||||
set_include_path(get_include_path() . PATH_SEPARATOR . $_SERVER["PROJECT_ROOT"]);
|
||||
}
|
||||
|
||||
?>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,895 @@
|
|||
/* globals SIP,user,moment, Stopwatch */
|
||||
|
||||
var ctxSip;
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
|
||||
if (typeof(user) === 'undefined') {
|
||||
|
||||
|
||||
user = JSON.parse(localStorage.getItem('SIPCreds'));
|
||||
}
|
||||
ctxSip = {
|
||||
|
||||
config : {
|
||||
media : {
|
||||
remote : {
|
||||
video: document.getElementById('audioRemote'),
|
||||
audio: document.getElementById('audioRemote')
|
||||
}
|
||||
},
|
||||
peerConnectionOptions : {
|
||||
rtcConfiguration : {
|
||||
iceServers : [{urls:"stun:stun.l.google.com:19302"}]
|
||||
}
|
||||
},
|
||||
password : user.Pass,
|
||||
authorizationUser: user.User,
|
||||
displayName : user.Display,
|
||||
uri : user.User +'@'+user.Realm,
|
||||
transportOptions: {
|
||||
traceSip: true,
|
||||
wsServers: user.WSServer,
|
||||
},
|
||||
registerExpires : 30,
|
||||
ua: {}
|
||||
},
|
||||
ringtone : document.getElementById('ringtone'),
|
||||
ringbacktone : document.getElementById('ringbacktone'),
|
||||
dtmfTone : document.getElementById('dtmfTone'),
|
||||
|
||||
Sessions : [],
|
||||
callTimers : {},
|
||||
callActiveID : null,
|
||||
callVolume : 1,
|
||||
Stream : null,
|
||||
|
||||
/**
|
||||
* Parses a SIP uri and returns a formatted US phone number.
|
||||
*
|
||||
* @param {string} phone number or uri to format
|
||||
* @return {string} formatted number
|
||||
*/
|
||||
formatPhone : function(phone) {
|
||||
|
||||
var num;
|
||||
|
||||
if (phone.indexOf('@')) {
|
||||
num = phone.split('@')[0];
|
||||
} else {
|
||||
num = phone;
|
||||
}
|
||||
|
||||
num = num.toString().replace(/[^0-9]/g, '');
|
||||
|
||||
if (num.length === 10) {
|
||||
return '(' + num.substr(0, 3) + ') ' + num.substr(3, 3) + '-' + num.substr(6,4);
|
||||
} else if (num.length === 11) {
|
||||
return '0' + num.substr(2);
|
||||
} else {
|
||||
return num;
|
||||
}
|
||||
},
|
||||
|
||||
// Sound methods
|
||||
startRingTone : function() {
|
||||
try { ctxSip.ringtone.play(); } catch (e) { }
|
||||
},
|
||||
|
||||
stopRingTone : function() {
|
||||
try { ctxSip.ringtone.pause(); } catch (e) { }
|
||||
},
|
||||
|
||||
startRingbackTone : function() {
|
||||
try { ctxSip.ringbacktone.play(); } catch (e) { }
|
||||
},
|
||||
|
||||
stopRingbackTone : function() {
|
||||
try { ctxSip.ringbacktone.pause(); } catch (e) { }
|
||||
},
|
||||
|
||||
// Genereates a rendom string to ID a call
|
||||
getUniqueID : function() {
|
||||
return Math.random().toString(36).substr(2, 9);
|
||||
},
|
||||
|
||||
newSession : function(newSess) {
|
||||
|
||||
newSess.displayName = newSess.remoteIdentity.displayName || newSess.remoteIdentity.uri.user;
|
||||
newSess.ctxid = ctxSip.getUniqueID();
|
||||
|
||||
var status;
|
||||
|
||||
if (newSess.direction === 'incoming') {
|
||||
status = "Incoming: "+ newSess.displayName;
|
||||
ctxSip.startRingTone();
|
||||
|
||||
} else {
|
||||
status = "Trying: "+ newSess.displayName;
|
||||
ctxSip.startRingbackTone();
|
||||
}
|
||||
|
||||
ctxSip.logCall(newSess, 'ringing');
|
||||
|
||||
ctxSip.setCallSessionStatus(status);
|
||||
|
||||
// EVENT CALLBACKS
|
||||
|
||||
|
||||
var remoteVideo = document.getElementById('audioRemote');
|
||||
var localVideo = document.getElementById('audioRemote');
|
||||
|
||||
|
||||
|
||||
newSess.on('trackAdded', function() {
|
||||
// We need to check the peer connection to determine which track was added
|
||||
|
||||
var pc = newSess.sessionDescriptionHandler.peerConnection;
|
||||
|
||||
// Gets remote tracks
|
||||
var remoteStream = new MediaStream();
|
||||
pc.getReceivers().forEach(function(receiver) {
|
||||
remoteStream.addTrack(receiver.track);
|
||||
});
|
||||
remoteVideo.srcObject = remoteStream;
|
||||
remoteVideo.play();
|
||||
|
||||
});
|
||||
|
||||
newSess.on('progress',function(e) {
|
||||
if (e.direction === 'outgoing') {
|
||||
ctxSip.setCallSessionStatus('Calling...');
|
||||
}
|
||||
});
|
||||
|
||||
newSess.on('connecting',function(e) {
|
||||
if (e.direction === 'outgoing') {
|
||||
ctxSip.setCallSessionStatus('Connecting...');
|
||||
}
|
||||
});
|
||||
|
||||
newSess.on('accepted',function(e) {
|
||||
// If there is another active call, hold it
|
||||
if (ctxSip.callActiveID && ctxSip.callActiveID !== newSess.ctxid) {
|
||||
ctxSip.phoneHoldButtonPressed(ctxSip.callActiveID);
|
||||
}
|
||||
|
||||
|
||||
ctxSip.stopRingbackTone();
|
||||
ctxSip.stopRingTone();
|
||||
ctxSip.setCallSessionStatus('Answered');
|
||||
ctxSip.logCall(newSess, 'answered');
|
||||
ctxSip.callActiveID = newSess.ctxid;
|
||||
|
||||
});
|
||||
|
||||
newSess.on('hold', function(e) {
|
||||
ctxSip.callActiveID = null;
|
||||
ctxSip.logCall(newSess, 'holding');
|
||||
ctxSip.setCallSessionStatus("Holding");
|
||||
});
|
||||
|
||||
newSess.on('unhold', function(e) {
|
||||
ctxSip.logCall(newSess, 'resumed');
|
||||
ctxSip.callActiveID = newSess.ctxid;
|
||||
ctxSip.setCallSessionStatus("Answered");
|
||||
});
|
||||
|
||||
newSess.on('muted', function(e) {
|
||||
ctxSip.Sessions[newSess.ctxid].isMuted = true;
|
||||
ctxSip.setCallSessionStatus("Muted");
|
||||
});
|
||||
|
||||
newSess.on('unmuted', function(e) {
|
||||
ctxSip.Sessions[newSess.ctxid].isMuted = false;
|
||||
ctxSip.setCallSessionStatus("Answered");
|
||||
});
|
||||
|
||||
newSess.on('cancel', function(e) {
|
||||
ctxSip.stopRingTone();
|
||||
ctxSip.stopRingbackTone();
|
||||
ctxSip.setCallSessionStatus("Canceled");
|
||||
if (this.direction === 'outgoing') {
|
||||
ctxSip.callActiveID = null;
|
||||
newSess = null;
|
||||
ctxSip.logCall(this, 'ended');
|
||||
}
|
||||
});
|
||||
|
||||
newSess.on('bye', function(e) {
|
||||
ctxSip.stopRingTone();
|
||||
ctxSip.stopRingbackTone();
|
||||
ctxSip.setCallSessionStatus("");
|
||||
ctxSip.logCall(newSess, 'ended');
|
||||
ctxSip.callActiveID = null;
|
||||
newSess = null;
|
||||
});
|
||||
|
||||
newSess.on('failed',function(e) {
|
||||
ctxSip.stopRingTone();
|
||||
ctxSip.stopRingbackTone();
|
||||
ctxSip.setCallSessionStatus('Terminated');
|
||||
});
|
||||
|
||||
newSess.on('rejected',function(e) {
|
||||
ctxSip.stopRingTone();
|
||||
ctxSip.stopRingbackTone();
|
||||
ctxSip.setCallSessionStatus('Rejected');
|
||||
ctxSip.callActiveID = null;
|
||||
ctxSip.logCall(this, 'ended');
|
||||
newSess = null;
|
||||
});
|
||||
|
||||
|
||||
|
||||
ctxSip.Sessions[newSess.ctxid] = newSess;
|
||||
|
||||
|
||||
},
|
||||
|
||||
// getUser media request refused or device was not present
|
||||
getUserMediaFailure : function(e) {
|
||||
window.console.error('getUserMedia failed:', e);
|
||||
ctxSip.setError(true, 'Media Error.', 'You must allow access to your microphone. Check the address bar.', true);
|
||||
},
|
||||
|
||||
getUserMediaSuccess : function(stream) {
|
||||
ctxSip.Stream = stream;
|
||||
},
|
||||
|
||||
/**
|
||||
* sets the ui call status field
|
||||
*
|
||||
* @param {string} status
|
||||
*/
|
||||
setCallSessionStatus : function(status) {
|
||||
$('#txtCallStatus').html(status);
|
||||
},
|
||||
|
||||
/**
|
||||
* sets the ui connection status field
|
||||
*
|
||||
* @param {string} status
|
||||
*/
|
||||
setStatus : function(status) {
|
||||
$("#txtRegStatus").html('<i class="fa fa-signal"></i> '+status);
|
||||
},
|
||||
|
||||
/**
|
||||
* logs a call to localstorage
|
||||
*
|
||||
* @param {object} session
|
||||
* @param {string} status Enum 'ringing', 'answered', 'ended', 'holding', 'resumed'
|
||||
*/
|
||||
logCall : function(session, status) {
|
||||
|
||||
var log = {
|
||||
clid : session.displayName,
|
||||
uri : session.remoteIdentity.uri.toString(),
|
||||
id : session.ctxid,
|
||||
time : new Date().getTime()
|
||||
},
|
||||
calllog = JSON.parse(localStorage.getItem('sipCalls'));
|
||||
|
||||
if (!calllog) { calllog = {}; }
|
||||
|
||||
if (!calllog.hasOwnProperty(session.ctxid)) {
|
||||
calllog[log.id] = {
|
||||
id : log.id,
|
||||
clid : log.clid,
|
||||
uri : log.uri,
|
||||
start : log.time,
|
||||
flow : session.direction
|
||||
};
|
||||
}
|
||||
|
||||
if (status === 'ended') {
|
||||
calllog[log.id].stop = log.time;
|
||||
}
|
||||
|
||||
if (status === 'ended' && calllog[log.id].status === 'ringing') {
|
||||
calllog[log.id].status = 'missed';
|
||||
} else {
|
||||
calllog[log.id].status = status;
|
||||
}
|
||||
|
||||
localStorage.setItem('sipCalls', JSON.stringify(calllog));
|
||||
ctxSip.logShow();
|
||||
},
|
||||
|
||||
/**
|
||||
* adds a ui item to the call log
|
||||
*
|
||||
* @param {object} item log item
|
||||
*/
|
||||
logItem : function(item) {
|
||||
|
||||
var callActive = (item.status !== 'ended' && item.status !== 'missed'),
|
||||
callLength = (item.status !== 'ended')? '<span id="'+item.id+'"></span>': moment.duration(item.stop - item.start).humanize(),
|
||||
callClass = '',
|
||||
callIcon,
|
||||
i;
|
||||
|
||||
switch (item.status) {
|
||||
case 'ringing' :
|
||||
callClass = 'list-group-item-success';
|
||||
callIcon = 'fa-bell';
|
||||
break;
|
||||
|
||||
case 'missed' :
|
||||
callClass = 'list-group-item-danger';
|
||||
if (item.flow === "incoming") { callIcon = 'fa-chevron-left'; }
|
||||
if (item.flow === "outgoing") { callIcon = 'fa-chevron-right'; }
|
||||
break;
|
||||
|
||||
case 'holding' :
|
||||
callClass = 'list-group-item-warning';
|
||||
callIcon = 'fa-pause';
|
||||
break;
|
||||
|
||||
case 'answered' :
|
||||
case 'resumed' :
|
||||
callClass = 'list-group-item-info';
|
||||
callIcon = 'fa-phone-square';
|
||||
break;
|
||||
|
||||
case 'ended' :
|
||||
if (item.flow === "incoming") { callIcon = 'fa-chevron-left'; }
|
||||
if (item.flow === "outgoing") { callIcon = 'fa-chevron-right'; }
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
i = '<div class="list-group-item sip-logitem clearfix '+callClass+'" data-uri="'+item.uri+'" data-sessionid="'+item.id+'" title="Double Click to Call">';
|
||||
i += '<div class="clearfix"><div class="pull-left">';
|
||||
i += '<i class="fa fa-fw '+callIcon+' fa-fw"></i> <strong>'+ctxSip.formatPhone(item.uri)+'</strong><br><small>'+moment(item.start).format('MM/DD hh:mm:ss a')+'</small>';
|
||||
i += '</div>';
|
||||
i += '<div class="pull-left text-left"><em>'+item.clid+'</em><br>' + callLength+'</div></div>';
|
||||
|
||||
if (callActive) {
|
||||
i += '<div class="btn-group btn-group-xs pull-right">';
|
||||
if (item.status === 'ringing' && item.flow === 'incoming') {
|
||||
i += '<button class="btn btn-xs btn-success btnCall" title="Call"><i class="fa fa-phone"></i></button>';
|
||||
} else {
|
||||
i += '<button class="btn btn-xs btn-primary btnHoldResume" title="Hold"><i class="fa fa-pause"></i></button>';
|
||||
i += '<button class="btn btn-xs btn-info btnTransfer" title="Transfer"><i class="fa fa-random"></i></button>';
|
||||
i += '<button class="btn btn-xs btn-warning btnMute" title="Mute"><i class="fa fa-fw fa-microphone"></i></button>';
|
||||
}
|
||||
i += '<button class="btn btn-xs btn-danger btnHangUp" title="Hangup"><i class="fa fa-stop"></i></button>';
|
||||
i += '</div>';
|
||||
}
|
||||
i += '</div>';
|
||||
|
||||
$('#sip-logitems').append(i);
|
||||
|
||||
|
||||
// Start call timer on answer
|
||||
if (item.status === 'answered') {
|
||||
var tEle = document.getElementById(item.id);
|
||||
ctxSip.callTimers[item.id] = new Stopwatch(tEle);
|
||||
ctxSip.callTimers[item.id].start();
|
||||
}
|
||||
|
||||
if (callActive && item.status !== 'ringing') {
|
||||
ctxSip.callTimers[item.id].start({startTime : item.start});
|
||||
}
|
||||
|
||||
$('#sip-logitems').scrollTop(0);
|
||||
},
|
||||
|
||||
/**
|
||||
* updates the call log ui
|
||||
*/
|
||||
logShow : function() {
|
||||
|
||||
var calllog = JSON.parse(localStorage.getItem('sipCalls')),
|
||||
x = [];
|
||||
|
||||
if (calllog !== null) {
|
||||
|
||||
$('#sip-splash').addClass('hide');
|
||||
$('#sip-log').removeClass('hide');
|
||||
|
||||
// empty existing logs
|
||||
$('#sip-logitems').empty();
|
||||
|
||||
// JS doesn't guarantee property order so
|
||||
// create an array with the start time as
|
||||
// the key and sort by that.
|
||||
|
||||
// Add start time to array
|
||||
$.each(calllog, function(k,v) {
|
||||
x.push(v);
|
||||
});
|
||||
|
||||
// sort descending
|
||||
x.sort(function(a, b) {
|
||||
return b.start - a.start;
|
||||
});
|
||||
|
||||
$.each(x, function(k, v) {
|
||||
ctxSip.logItem(v);
|
||||
});
|
||||
|
||||
} else {
|
||||
$('#sip-splash').removeClass('hide');
|
||||
$('#sip-log').addClass('hide');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* removes log items from localstorage and updates the UI
|
||||
*/
|
||||
logClear : function() {
|
||||
|
||||
localStorage.removeItem('sipCalls');
|
||||
ctxSip.logShow();
|
||||
},
|
||||
|
||||
sipCall : function(target) {
|
||||
|
||||
try {
|
||||
var s = ctxSip.phone.invite(target, {
|
||||
media : {
|
||||
remote : {
|
||||
video: document.getElementById('audioRemote'),
|
||||
audio: document.getElementById('audioRemote')
|
||||
}
|
||||
},
|
||||
sessionDescriptionHandlerOptions : {
|
||||
constraints : { audio : true, video : false },
|
||||
rtcConfiguration : { RTCConstraints : { "optional": [{ 'DtlsSrtpKeyAgreement': 'true'} ]}, stream : ctxSip.Stream }
|
||||
|
||||
}
|
||||
});
|
||||
s.direction = 'outgoing';
|
||||
ctxSip.newSession(s);
|
||||
|
||||
var remoteVideo = document.getElementById('audioRemote');
|
||||
var localVideo = document.getElementById('audioRemote');
|
||||
|
||||
|
||||
|
||||
s.on('trackAdded', function() {
|
||||
// We need to check the peer connection to determine which track was added
|
||||
|
||||
var pc = s.sessionDescriptionHandler.peerConnection;
|
||||
|
||||
// Gets remote tracks
|
||||
var remoteStream = new MediaStream();
|
||||
pc.getReceivers().forEach(function(receiver) {
|
||||
remoteStream.addTrack(receiver.track);
|
||||
});
|
||||
remoteVideo.srcObject = remoteStream;
|
||||
remoteVideo.play();
|
||||
});
|
||||
|
||||
|
||||
} catch(e) {
|
||||
throw(e);
|
||||
}
|
||||
},
|
||||
|
||||
sipTransfer : function(sessionid) {
|
||||
|
||||
var s = ctxSip.Sessions[sessionid],
|
||||
target = window.prompt('Enter destination number', '');
|
||||
|
||||
ctxSip.setCallSessionStatus('<i>Transfering the call...</i>');
|
||||
s.refer(target);
|
||||
},
|
||||
|
||||
sipHangUp : function(sessionid) {
|
||||
|
||||
var s = ctxSip.Sessions[sessionid];
|
||||
// s.terminate();
|
||||
if (!s) {
|
||||
return;
|
||||
} else if (s.startTime) {
|
||||
s.bye();
|
||||
} else if (s.reject) {
|
||||
s.reject();
|
||||
} else if (s.cancel) {
|
||||
s.cancel();
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
sipSendDTMF : function(digit) {
|
||||
|
||||
try { ctxSip.dtmfTone.play(); } catch(e) { }
|
||||
|
||||
var a = ctxSip.callActiveID;
|
||||
if (a) {
|
||||
var s = ctxSip.Sessions[a];
|
||||
s.dtmf(digit);
|
||||
}
|
||||
},
|
||||
|
||||
phoneCallButtonPressed : function(sessionid) {
|
||||
|
||||
var s = ctxSip.Sessions[sessionid],
|
||||
target = $("#numDisplay").val();
|
||||
|
||||
if (!s) {
|
||||
|
||||
$("#numDisplay").val("");
|
||||
ctxSip.sipCall(target);
|
||||
|
||||
} else if (s.accept && !s.startTime) {
|
||||
|
||||
s.accept({
|
||||
media : {
|
||||
remote : {
|
||||
video: document.getElementById('audioRemote'),
|
||||
audio: document.getElementById('audioRemote')
|
||||
}
|
||||
},
|
||||
sessionDescriptionHandlerOptions : {
|
||||
constraints : { audio : true, video : false },
|
||||
rtcConfiguration : { RTCConstraints : { "optional": [{ 'DtlsSrtpKeyAgreement': 'true'} ]}, stream : ctxSip.Stream }
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
phoneMuteButtonPressed : function (sessionid) {
|
||||
|
||||
var s = ctxSip.Sessions[sessionid];
|
||||
|
||||
if (!s.isMuted) {
|
||||
s.mute();
|
||||
} else {
|
||||
s.unmute();
|
||||
}
|
||||
},
|
||||
|
||||
phoneHoldButtonPressed : function(sessionid) {
|
||||
|
||||
var s = ctxSip.Sessions[sessionid];
|
||||
var direction = s.sessionDescriptionHandler.getDirection();
|
||||
|
||||
if (direction === 'sendrecv') {
|
||||
console.log('Call is not on hold');
|
||||
s.hold();
|
||||
} else {
|
||||
console.log('Call is on hold');
|
||||
s.unhold();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
setError : function(err, title, msg, closable) {
|
||||
|
||||
// Show modal if err = true
|
||||
if (err === true) {
|
||||
$("#mdlError p").html(msg);
|
||||
$("#mdlError").modal('show');
|
||||
|
||||
if (closable) {
|
||||
var b = '<button type="button" class="close" data-dismiss="modal">×</button>';
|
||||
$("#mdlError .modal-header").find('button').remove();
|
||||
$("#mdlError .modal-header").prepend(b);
|
||||
$("#mdlError .modal-title").html(title);
|
||||
$("#mdlError").modal({ keyboard : true });
|
||||
} else {
|
||||
$("#mdlError .modal-header").find('button').remove();
|
||||
$("#mdlError .modal-title").html(title);
|
||||
$("#mdlError").modal({ keyboard : false });
|
||||
}
|
||||
// $('#numDisplay').prop('disabled', 'disabled');
|
||||
} else {
|
||||
$('#numDisplay').removeProp('disabled');
|
||||
$("#mdlError").modal('hide');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Tests for a capable browser, return bool, and shows an
|
||||
* error modal on fail.
|
||||
*/
|
||||
hasWebRTC : function() {
|
||||
|
||||
if (navigator.webkitGetUserMedia) {
|
||||
return true;
|
||||
} else if (navigator.mozGetUserMedia) {
|
||||
return true;
|
||||
} else if (navigator.getUserMedia) {
|
||||
return true;
|
||||
} else {
|
||||
ctxSip.setError(true, 'Unsupported Browser.', 'Your browser does not support the features required for this phone.');
|
||||
window.console.error("WebRTC support not found");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Throw an error if the browser can't hack it.
|
||||
if (!ctxSip.hasWebRTC()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ctxSip.phone = new SIP.UA(ctxSip.config);
|
||||
|
||||
|
||||
ctxSip.phone.on('connected', function(e) {
|
||||
ctxSip.setStatus("Connected");
|
||||
ctxSip.setError(false)
|
||||
});
|
||||
|
||||
ctxSip.phone.on('disconnected', function(e) {
|
||||
ctxSip.setStatus("Disconnected");
|
||||
|
||||
// disable phone
|
||||
ctxSip.setError(true, 'Websocket Disconnected.', 'An Error occurred connecting to the websocket.');
|
||||
|
||||
});
|
||||
|
||||
ctxSip.phone.on('registered', function(e) {
|
||||
ctxSip.setError(false)
|
||||
var closeEditorWarning = function() {
|
||||
return 'If you close this window, you will not be able to make or receive calls from your browser.';
|
||||
};
|
||||
|
||||
var closePhone = function() {
|
||||
// stop the phone on unload
|
||||
localStorage.removeItem('ctxPhone');
|
||||
ctxSip.phone.stop();
|
||||
};
|
||||
|
||||
window.onbeforeunload = closeEditorWarning;
|
||||
window.onunload = closePhone;
|
||||
|
||||
// This key is set to prevent multiple windows.
|
||||
localStorage.setItem('ctxPhone', 'true');
|
||||
|
||||
$("#mldError").modal('hide');
|
||||
ctxSip.setStatus("Ready");
|
||||
|
||||
|
||||
// Get the userMedia and cache the stream
|
||||
// if (SIP.WebRTC.isSupported()) {
|
||||
// SIP.WebRTC.getUserMedia({ audio : true, video : false }, ctxSip.getUserMediaSuccess, ctxSip.getUserMediaFailure);
|
||||
// }
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ctxSip.phone.on('registrationFailed', function(e) {
|
||||
console.log(e)
|
||||
ctxSip.setError(true, 'Registration Error.', 'An Error occurred registering your phone. Check your settings.');
|
||||
ctxSip.setStatus("Error: Registration Failed");
|
||||
});
|
||||
|
||||
ctxSip.phone.on('unregistered', function(e) {
|
||||
ctxSip.setError(true, 'Registration Error.', 'An Error occurred registering your phone. Please wait while we try to connect it again.');
|
||||
ctxSip.setStatus("Error: Registration Failed");
|
||||
});
|
||||
|
||||
ctxSip.phone.on('invite',
|
||||
|
||||
function (incomingSession) {
|
||||
|
||||
var s = incomingSession;
|
||||
|
||||
s.direction = 'incoming';
|
||||
ctxSip.newSession(s);
|
||||
|
||||
|
||||
},);
|
||||
|
||||
// Auto-focus number input on backspace.
|
||||
$('#sipClient').keydown(function(event) {
|
||||
if (event.which === 8) {
|
||||
$('#numDisplay').focus();
|
||||
}
|
||||
});
|
||||
|
||||
$('#numDisplay').keypress(function(e) {
|
||||
// Enter pressed? so Dial.
|
||||
if (e.which === 13) {
|
||||
ctxSip.phoneCallButtonPressed();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$('#phoneIcon').click(function(eveny) {
|
||||
// Enter pressed? so Dial.
|
||||
event.preventDefault();
|
||||
ctxSip.phoneCallButtonPressed();
|
||||
});
|
||||
|
||||
|
||||
$('.digit').click(function(event) {
|
||||
event.preventDefault();
|
||||
var num = $('#numDisplay').val(),
|
||||
dig = $(this).data('digit');
|
||||
|
||||
$('#numDisplay').val(num+dig);
|
||||
|
||||
ctxSip.sipSendDTMF(dig);
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#phoneUI .dropdown-menu').click(function(e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$('#phoneUI').delegate('.btnCall', 'click', function(event) {
|
||||
ctxSip.phoneCallButtonPressed();
|
||||
// to close the dropdown
|
||||
return true;
|
||||
});
|
||||
|
||||
$('.sipLogClear').click(function(event) {
|
||||
event.preventDefault();
|
||||
ctxSip.logClear();
|
||||
});
|
||||
|
||||
$('#sip-logitems').delegate('.sip-logitem .btnCall', 'click', function(event) {
|
||||
var sessionid = $(this).closest('.sip-logitem').data('sessionid');
|
||||
ctxSip.phoneCallButtonPressed(sessionid);
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#sip-logitems').delegate('.sip-logitem .btnHoldResume', 'click', function(event) {
|
||||
var sessionid = $(this).closest('.sip-logitem').data('sessionid');
|
||||
ctxSip.phoneHoldButtonPressed(sessionid);
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#sip-logitems').delegate('.sip-logitem .btnHangUp', 'click', function(event) {
|
||||
var sessionid = $(this).closest('.sip-logitem').data('sessionid');
|
||||
ctxSip.sipHangUp(sessionid);
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#sip-logitems').delegate('.sip-logitem .btnTransfer', 'click', function(event) {
|
||||
var sessionid = $(this).closest('.sip-logitem').data('sessionid');
|
||||
ctxSip.sipTransfer(sessionid);
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#sip-logitems').delegate('.sip-logitem .btnMute', 'click', function(event) {
|
||||
var sessionid = $(this).closest('.sip-logitem').data('sessionid');
|
||||
ctxSip.phoneMuteButtonPressed(sessionid);
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#sip-logitems').delegate('.sip-logitem', 'dblclick', function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
var uri = $(this).data('uri');
|
||||
$('#numDisplay').val(uri);
|
||||
ctxSip.phoneCallButtonPressed();
|
||||
});
|
||||
|
||||
$('#sldVolume').on('change', function() {
|
||||
|
||||
var v = $(this).val() / 100,
|
||||
// player = $('audio').get()[0],
|
||||
btn = $('#btnVol'),
|
||||
icon = $('#btnVol').find('i'),
|
||||
active = ctxSip.callActiveID;
|
||||
|
||||
// Set the object and media stream volumes
|
||||
if (ctxSip.Sessions[active]) {
|
||||
ctxSip.Sessions[active].player.volume = v;
|
||||
ctxSip.callVolume = v;
|
||||
}
|
||||
|
||||
// Set the others
|
||||
$('audio').each(function() {
|
||||
$(this).get()[0].volume = v;
|
||||
});
|
||||
|
||||
if (v < 0.1) {
|
||||
btn.removeClass(function (index, css) {
|
||||
return (css.match (/(^|\s)btn\S+/g) || []).join(' ');
|
||||
})
|
||||
.addClass('btn btn-sm btn-danger');
|
||||
icon.removeClass().addClass('fa fa-fw fa-volume-off');
|
||||
} else if (v < 0.8) {
|
||||
btn.removeClass(function (index, css) {
|
||||
return (css.match (/(^|\s)btn\S+/g) || []).join(' ');
|
||||
}).addClass('btn btn-sm btn-info');
|
||||
icon.removeClass().addClass('fa fa-fw fa-volume-down');
|
||||
} else {
|
||||
btn.removeClass(function (index, css) {
|
||||
return (css.match (/(^|\s)btn\S+/g) || []).join(' ');
|
||||
}).addClass('btn btn-sm btn-primary');
|
||||
icon.removeClass().addClass('fa fa-fw fa-volume-up');
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
// Hide the spalsh after 3 secs.
|
||||
setTimeout(function() {
|
||||
ctxSip.logShow();
|
||||
}, 3000);
|
||||
|
||||
|
||||
/**
|
||||
* Stopwatch object used for call timers
|
||||
*
|
||||
* @param {dom element} elem
|
||||
* @param {[object]} options
|
||||
*/
|
||||
var Stopwatch = function(elem, options) {
|
||||
|
||||
// private functions
|
||||
function createTimer() {
|
||||
return document.createElement("span");
|
||||
}
|
||||
|
||||
var timer = createTimer(),
|
||||
offset,
|
||||
clock,
|
||||
interval;
|
||||
|
||||
// default options
|
||||
options = options || {};
|
||||
options.delay = options.delay || 1000;
|
||||
options.startTime = options.startTime || Date.now();
|
||||
|
||||
// append elements
|
||||
elem.appendChild(timer);
|
||||
|
||||
function start() {
|
||||
if (!interval) {
|
||||
offset = options.startTime;
|
||||
interval = setInterval(update, options.delay);
|
||||
}
|
||||
}
|
||||
|
||||
function stop() {
|
||||
if (interval) {
|
||||
clearInterval(interval);
|
||||
interval = null;
|
||||
}
|
||||
}
|
||||
|
||||
function reset() {
|
||||
clock = 0;
|
||||
render();
|
||||
}
|
||||
|
||||
function update() {
|
||||
clock += delta();
|
||||
render();
|
||||
}
|
||||
|
||||
function render() {
|
||||
timer.innerHTML = moment(clock).format('mm:ss');
|
||||
}
|
||||
|
||||
function delta() {
|
||||
var now = Date.now(),
|
||||
d = now - offset;
|
||||
|
||||
offset = now;
|
||||
return d;
|
||||
}
|
||||
|
||||
// initialize
|
||||
reset();
|
||||
|
||||
// public API
|
||||
this.start = start; //function() { start; }
|
||||
this.stop = stop; //function() { stop; }
|
||||
};
|
||||
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
var user = {
|
||||
// User Name
|
||||
"User" : "sipuser",
|
||||
// Password
|
||||
"Pass" : "yourpassword",
|
||||
// Auth Realm
|
||||
"Realm" : "sip.sample.com",
|
||||
// Display Name
|
||||
"Display" : "Gob Bleuth",
|
||||
// WebSocket URL
|
||||
"WSServer" : "wss://wss.sample.com:8443"
|
||||
};
|
|
@ -0,0 +1,12 @@
|
|||
var user = {
|
||||
// User Name
|
||||
"User" : "3000",
|
||||
// Password
|
||||
"Pass" : "dP.!saZ!vv",
|
||||
// Auth Realm
|
||||
"Realm" : "proxylab.encoretg.net",
|
||||
// Display Name
|
||||
"Display" : "Gob Bleuth",
|
||||
// WebSocket URL
|
||||
"WSServer" : "wss://proxylab.encoretg.net:7443"
|
||||
};
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,90 @@
|
|||
<?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
|
||||
umask(2);
|
||||
if (!defined("PATH_SEPARATOR")) {
|
||||
if (strpos($_ENV["OS"], "Win") !== false) {
|
||||
define("PATH_SEPARATOR", ";");
|
||||
} else {
|
||||
define("PATH_SEPARATOR", ":");
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($output_format)) $output_format = (PHP_SAPI == 'cli') ? 'text' : 'html';
|
||||
|
||||
// make sure the document_root is set
|
||||
$_SERVER["SCRIPT_FILENAME"] = str_replace("\\", '/', $_SERVER["SCRIPT_FILENAME"]);
|
||||
if(PHP_SAPI == 'cli'){
|
||||
chdir(pathinfo(realpath($_SERVER["PHP_SELF"]), PATHINFO_DIRNAME));
|
||||
$script_full_path = str_replace("\\", '/', getcwd() . '/' . $_SERVER["SCRIPT_FILENAME"]);
|
||||
$dirs = explode('/', pathinfo($script_full_path, PATHINFO_DIRNAME));
|
||||
if (file_exists('/project_root.php')) {
|
||||
$path = '/';
|
||||
} else {
|
||||
$i = 1;
|
||||
$path = '';
|
||||
while ($i < count($dirs)) {
|
||||
$path .= '/' . $dirs[$i];
|
||||
if (file_exists($path. '/project_root.php')) {
|
||||
break;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
$_SERVER["DOCUMENT_ROOT"] = $path;
|
||||
}else{
|
||||
$_SERVER["DOCUMENT_ROOT"] = str_replace($_SERVER["PHP_SELF"], "", $_SERVER["SCRIPT_FILENAME"]);
|
||||
}
|
||||
$_SERVER["DOCUMENT_ROOT"] = realpath($_SERVER["DOCUMENT_ROOT"]);
|
||||
// try to detect if a project path is being used
|
||||
if (!defined('PROJECT_PATH')) {
|
||||
if (is_dir($_SERVER["DOCUMENT_ROOT"]. '/fusionpbx')) {
|
||||
define('PROJECT_PATH', '/fusionpbx');
|
||||
} elseif (file_exists($_SERVER["DOCUMENT_ROOT"]. '/project_root.php')) {
|
||||
define('PROJECT_PATH', '');
|
||||
} else {
|
||||
$dirs = explode('/', str_replace('\\', '/', pathinfo($_SERVER["PHP_SELF"], PATHINFO_DIRNAME)));
|
||||
$i = 1;
|
||||
$path = $_SERVER["DOCUMENT_ROOT"];
|
||||
while ($i < count($dirs)) {
|
||||
$path .= '/' . $dirs[$i];
|
||||
if (file_exists($path. '/project_root.php')) {
|
||||
break;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
if(!file_exists($path. '/project_root.php')){
|
||||
die("Failed to locate the Project Root by searching for project_root.php please contact support for assistance");
|
||||
}
|
||||
$project_path = str_replace($_SERVER["DOCUMENT_ROOT"], "", $path);
|
||||
define('PROJECT_PATH', $project_path);
|
||||
}
|
||||
$_SERVER["PROJECT_ROOT"] = realpath($_SERVER["DOCUMENT_ROOT"] . PROJECT_PATH);
|
||||
set_include_path(get_include_path() . PATH_SEPARATOR . $_SERVER["PROJECT_ROOT"]);
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,134 @@
|
|||
<?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-2016
|
||||
the Initial Developer. All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
KonradSC <konrd@yahoo.com>
|
||||
Mark J Crane <markjcrane@fusionpbx.com>
|
||||
*/
|
||||
|
||||
//includes
|
||||
include "root.php";
|
||||
require_once "resources/require.php";
|
||||
require_once "resources/check_auth.php";
|
||||
require_once "resources/paging.php";
|
||||
|
||||
//check permissions
|
||||
if (permission_exists('webphone_view')) {
|
||||
//access granted
|
||||
}
|
||||
else {
|
||||
echo "access denied";
|
||||
exit;
|
||||
}
|
||||
|
||||
//create token
|
||||
$object = new token;
|
||||
$token = $object->create($_SERVER['PHP_SELF']);
|
||||
|
||||
//add multi-lingual support
|
||||
$language = new text;
|
||||
$text = $language->get();
|
||||
|
||||
//verify the id is as uuid then set as a variable
|
||||
if (is_uuid($_GET['id'])) {
|
||||
$extension_uuid = $_GET['id'];
|
||||
}
|
||||
|
||||
//get the extension(s)
|
||||
if (permission_exists('extension_edit')) {
|
||||
//admin user
|
||||
$sql = "select * from v_extensions ";
|
||||
$sql .= "where domain_uuid = :domain_uuid ";
|
||||
$sql .= "and enabled = 'true' ";
|
||||
$sql .= "order by extension asc ";
|
||||
}
|
||||
else {
|
||||
//normal user
|
||||
$sql = "select e.* ";
|
||||
$sql .= "from v_extensions as e, ";
|
||||
$sql .= "v_extension_users as eu ";
|
||||
$sql .= "where e.extension_uuid = eu.extension_uuid ";
|
||||
$sql .= "and eu.user_uuid = :user_uuid ";
|
||||
$sql .= "and e.domain_uuid = :domain_uuid ";
|
||||
$sql .= "and e.enabled = 'true' ";
|
||||
$sql .= "order by e.extension asc ";
|
||||
$parameters['user_uuid'] = $_SESSION['user']['user_uuid'];
|
||||
}
|
||||
$parameters['domain_uuid'] = $_SESSION['domain_uuid'];
|
||||
$database = new database;
|
||||
$extensions = $database->select($sql, $parameters, 'all');
|
||||
unset($sql, $parameters);
|
||||
|
||||
//include the header
|
||||
$document['title'] = $text['title-webphone'];
|
||||
require_once "resources/header.php";
|
||||
|
||||
echo "<form name='frm' id='frm' method='get'>\n";
|
||||
echo "<div class='action_bar' id='action_bar'>\n";
|
||||
echo " <div class='heading'><b>".$text['title-webphone']."</b></div>\n";
|
||||
echo " <div class='actions'></div>\n";
|
||||
echo " \n";
|
||||
echo " <div style='clear: both;'></div>\n";
|
||||
echo "</div>\n";
|
||||
echo $text['title-description-webphone']."\n";
|
||||
echo "<br /><br />\n";
|
||||
|
||||
echo "<div style='text-align: center; white-space: nowrap; margin: 10px 0 40px 0;'>";
|
||||
echo $text['label-select_extension']."<br />\n";
|
||||
echo "<select name='id' class='formfld' onchange='this.form.submit();'>\n";
|
||||
echo " <option value='' >".$text['label-select']."...</option>\n";
|
||||
if (is_array($extensions) && @sizeof($extensions) != 0) {
|
||||
foreach ($extensions as $row) {
|
||||
$selected = $row['extension_uuid'] == $extension_uuid ? "selected='selected'" : null;
|
||||
echo " <option value='".escape($row['extension_uuid'])."' ".$selected.">".escape($row['extension'])." ".escape($row['number_alias'])." ".escape($row['description'])."</option>\n";
|
||||
}
|
||||
}
|
||||
echo "</select>\n";
|
||||
echo "<input type='hidden' name='".$token['name']."' value='".$token['hash']."'>\n";
|
||||
echo "</form>\n";
|
||||
|
||||
//begin the content
|
||||
if (strlen($extension_uuid) > 0 ) {
|
||||
echo " <a href=\"phone\" id=\"launchPhone\">".$text['label-webphone_launch']."</a>\n";
|
||||
}
|
||||
echo " <script>\n";
|
||||
echo " var url = 'phone/index.php?id=".escape($extension_uuid)."',\n";
|
||||
echo " features = 'menubar=no,location=no,resizable=no,scrollbars=no,status=no,addressbar=no,width=320,height=480'\n";
|
||||
echo " $('#launchPhone').on('click', function(event) { \n";
|
||||
echo " event.preventDefault() \n";
|
||||
// This is set when the phone is open and removed on close
|
||||
echo " if (!localStorage.getItem('ctxPhone')) { \n";
|
||||
echo " window.open(url, 'ctxPhone', features)\n";
|
||||
echo " return false\n";
|
||||
echo " } else { \n";
|
||||
echo " window.alert('Phone already open.')\n";
|
||||
echo " }\n";
|
||||
echo " })\n";
|
||||
echo " function updatevariable(data) { \n";
|
||||
echo " value = data;\n";
|
||||
echo " } \n";
|
||||
echo " </script>\n";
|
||||
|
||||
echo "</div>\n";
|
||||
//show the footer
|
||||
require_once "resources/footer.php";
|
||||
?>
|
Loading…
Reference in New Issue