add page for calls
This commit is contained in:
parent
41c3b3b86e
commit
c63f3bebba
|
@ -149,12 +149,12 @@ namespace adapters;
|
||||||
|
|
||||||
public static function meta_support_inbound_call_callback(): bool
|
public static function meta_support_inbound_call_callback(): bool
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function meta_support_end_call_callback(): bool
|
public static function meta_support_end_call_callback(): bool
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function send(string $destination, string $text, bool $flash = false, bool $mms = false, array $medias = []) : array
|
public function send(string $destination, string $text, bool $flash = false, bool $mms = false, array $medias = []) : array
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of RaspiSMS.
|
||||||
|
*
|
||||||
|
* (c) Pierre-Lin Bonnemaison <plebwebsas@gmail.com>
|
||||||
|
*
|
||||||
|
* This source file is subject to the GPL-3.0 license that is bundled
|
||||||
|
* with this source code in the file LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace controllers\publics;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page des calls.
|
||||||
|
*/
|
||||||
|
class Call extends \descartes\Controller
|
||||||
|
{
|
||||||
|
private $internal_call;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cette fonction est appelée avant toute les autres :
|
||||||
|
* Elle vérifie que l'utilisateur est bien connecté.
|
||||||
|
*
|
||||||
|
* @return void;
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$bdd = \descartes\Model::_connect(DATABASE_HOST, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD);
|
||||||
|
|
||||||
|
$this->internal_call = new \controllers\internals\Call($bdd);
|
||||||
|
|
||||||
|
\controllers\internals\Tool::verifyconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page for showing calls list
|
||||||
|
*/
|
||||||
|
public function list()
|
||||||
|
{
|
||||||
|
$this->render('call/list');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return calls list as json.
|
||||||
|
*/
|
||||||
|
public function list_json()
|
||||||
|
{
|
||||||
|
$entities = $this->internal_call->list_for_user($_SESSION['user']['id']);
|
||||||
|
foreach ($entities as &$entity)
|
||||||
|
{
|
||||||
|
switch ($entity['direction'])
|
||||||
|
{
|
||||||
|
case \models\Call::DIRECTION_INBOUND :
|
||||||
|
$entity['origin_formatted'] = \controllers\internals\Tool::phone_link($entity['origin']);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case \models\Call::DIRECTION_OUTBOUND :
|
||||||
|
$entity['destination_formatted'] = \controllers\internals\Tool::phone_link($entity['destination']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
echo json_encode(['data' => $entities]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a list of calls
|
||||||
|
*
|
||||||
|
* @param array int $_GET['ids'] : Ids of calls to delete
|
||||||
|
* @param string $csrf : csrf token
|
||||||
|
*
|
||||||
|
* @return boolean;
|
||||||
|
*/
|
||||||
|
public function delete(string $csrf)
|
||||||
|
{
|
||||||
|
if (!$this->verify_csrf($csrf))
|
||||||
|
{
|
||||||
|
\FlashMessage\FlashMessage::push('danger', 'Jeton CSRF invalid !');
|
||||||
|
|
||||||
|
return $this->redirect(\descartes\Router::url('Call', 'list'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$ids = $_GET['ids'] ?? [];
|
||||||
|
foreach ($ids as $id)
|
||||||
|
{
|
||||||
|
$this->internal_call->delete_for_user($_SESSION['user']['id'], $id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->redirect(\descartes\Router::url('Call', 'list'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,43 +33,7 @@ class Phone extends \descartes\Controller
|
||||||
*/
|
*/
|
||||||
public function list()
|
public function list()
|
||||||
{
|
{
|
||||||
$id_user = $_SESSION['user']['id'];
|
$this->render('phone/list');
|
||||||
$api_key = $_SESSION['user']['api_key'];
|
|
||||||
$phones = $this->internal_phone->list_for_user($id_user);
|
|
||||||
|
|
||||||
$adapters = [];
|
|
||||||
$adapters = $this->internal_adapter->list_adapters();
|
|
||||||
foreach ($adapters as $key => $adapter)
|
|
||||||
{
|
|
||||||
unset($adapters[$key]);
|
|
||||||
$adapters[$adapter['meta_classname']] = $adapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($phones as &$phone)
|
|
||||||
{
|
|
||||||
$adapter = $adapters[$phone['adapter']] ?? false;
|
|
||||||
|
|
||||||
if (!$adapter)
|
|
||||||
{
|
|
||||||
$phone['adapter'] = 'Inconnu';
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$phone['adapter'] = $adapter['meta_name'];
|
|
||||||
|
|
||||||
if ($adapter['meta_support_reception'])
|
|
||||||
{
|
|
||||||
$phone['callback_reception'] = \descartes\Router::url('Callback', 'reception', ['adapter_uid' => $adapter['meta_uid'], 'id_phone' => $phone['id']], ['api_key' => $api_key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($adapter['meta_support_status_change'])
|
|
||||||
{
|
|
||||||
$phone['callback_status'] = \descartes\Router::url('Callback', 'update_sended_status', ['adapter_uid' => $adapter['meta_uid']], ['api_key' => $api_key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->render('phone/list', ['phones' => $phones]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,6 +75,16 @@ class Phone extends \descartes\Controller
|
||||||
{
|
{
|
||||||
$phone['callback_status'] = \descartes\Router::url('Callback', 'update_sended_status', ['adapter_uid' => $adapter['meta_uid']], ['api_key' => $api_key]);
|
$phone['callback_status'] = \descartes\Router::url('Callback', 'update_sended_status', ['adapter_uid' => $adapter['meta_uid']], ['api_key' => $api_key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($adapter['meta_support_inbound_call_callback'])
|
||||||
|
{
|
||||||
|
$phone['callback_inbound_call'] = \descartes\Router::url('Callback', 'inbound_call', ['id_phone' => $phone['id']], ['api_key' => $api_key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($adapter['meta_support_end_call_callback'])
|
||||||
|
{
|
||||||
|
$phone['callback_end_call'] = \descartes\Router::url('Callback', 'end_call', ['id_phone' => $phone['id']], ['api_key' => $api_key]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
|
|
|
@ -19,6 +19,48 @@ namespace models;
|
||||||
const DIRECTION_INBOUND = 'inbound';
|
const DIRECTION_INBOUND = 'inbound';
|
||||||
const DIRECTION_OUTBOUND = 'outbound';
|
const DIRECTION_OUTBOUND = 'outbound';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of call for a user.
|
||||||
|
* Add a column contact_name and phone_name when available.
|
||||||
|
*
|
||||||
|
* @param int $id_user : user id
|
||||||
|
* @param ?int $limit : Number of entry to return or null
|
||||||
|
* @param ?int $offset : Number of entry to ignore or null
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function list_for_user(int $id_user, $limit, $offset)
|
||||||
|
{
|
||||||
|
$query = '
|
||||||
|
SELECT `call`.*, contact.name as contact_name, phone.name as phone_name
|
||||||
|
FROM `call`
|
||||||
|
LEFT JOIN contact
|
||||||
|
ON contact.number = `call`.destination
|
||||||
|
OR contact.number = `call`.origin
|
||||||
|
LEFT JOIN phone
|
||||||
|
ON phone.id = `call`.id_phone
|
||||||
|
WHERE `call`.id_user = :id_user
|
||||||
|
';
|
||||||
|
|
||||||
|
if (null !== $limit)
|
||||||
|
{
|
||||||
|
$limit = (int) $limit;
|
||||||
|
|
||||||
|
$query .= ' LIMIT ' . $limit;
|
||||||
|
if (null !== $offset)
|
||||||
|
{
|
||||||
|
$offset = (int) $offset;
|
||||||
|
$query .= ' OFFSET ' . $offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$params = [
|
||||||
|
'id_user' => $id_user,
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->_run_query($query, $params);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a call for a user by his phone and uid
|
* Get a call for a user by his phone and uid
|
||||||
*
|
*
|
||||||
|
|
12
routes.php
12
routes.php
|
@ -58,10 +58,7 @@
|
||||||
],
|
],
|
||||||
|
|
||||||
'Event' => [
|
'Event' => [
|
||||||
'list' => [
|
'list' => '/event/',
|
||||||
'/event/',
|
|
||||||
'/event/p/{page}/',
|
|
||||||
],
|
|
||||||
'list_json' => '/event/json/',
|
'list_json' => '/event/json/',
|
||||||
'delete' => '/event/delete/{csrf}/',
|
'delete' => '/event/delete/{csrf}/',
|
||||||
],
|
],
|
||||||
|
@ -155,6 +152,12 @@
|
||||||
'delete' => '/phone/delete/{csrf}/',
|
'delete' => '/phone/delete/{csrf}/',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'Call' => [
|
||||||
|
'list' => '/call/',
|
||||||
|
'list_json' => '/call/json/',
|
||||||
|
'delete' => '/call/delete/{csrf}/',
|
||||||
|
],
|
||||||
|
|
||||||
'Webhook' => [
|
'Webhook' => [
|
||||||
'list' => '/webhook/',
|
'list' => '/webhook/',
|
||||||
'list_json' => '/webhook/json/',
|
'list_json' => '/webhook/json/',
|
||||||
|
@ -169,6 +172,7 @@
|
||||||
'update_sended_status' => '/callback/status/{adapter_uid}/',
|
'update_sended_status' => '/callback/status/{adapter_uid}/',
|
||||||
'reception' => '/callback/reception/{adapter_uid}/{id_phone}/',
|
'reception' => '/callback/reception/{adapter_uid}/{id_phone}/',
|
||||||
'inbound_call' => '/callback/inbound_call/{id_phone}/',
|
'inbound_call' => '/callback/inbound_call/{id_phone}/',
|
||||||
|
'end_call' => '/callback/end_call/{id_phone}/',
|
||||||
],
|
],
|
||||||
|
|
||||||
'Api' => [
|
'Api' => [
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
<?php
|
||||||
|
//Template dashboard
|
||||||
|
|
||||||
|
$this->render('incs/head', ['title' => 'Appels - Show All'])
|
||||||
|
?>
|
||||||
|
<div id="wrapper">
|
||||||
|
<?php
|
||||||
|
$this->render('incs/nav', ['page' => 'calls'])
|
||||||
|
?>
|
||||||
|
<div id="page-wrapper">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<!-- Page Heading -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<h1 class="page-header">
|
||||||
|
Dashboard <small>Appels</small>
|
||||||
|
</h1>
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li>
|
||||||
|
<i class="fa fa-dashboard"></i> <a href="<?php echo \descartes\Router::url('Dashboard', 'show'); ?>">Dashboard</a>
|
||||||
|
</li>
|
||||||
|
<li class="active">
|
||||||
|
<i class="fa fa-clock-o"></i> Appels
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /.row -->
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title"><i class="fa fa-clock-o fa-fw"></i> Liste des appels</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<form method="GET">
|
||||||
|
<div class="table-events">
|
||||||
|
<table class="table table-bordered table-hover table-striped datatable" id="table-calls">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Origine</th>
|
||||||
|
<th>Destinataire</th>
|
||||||
|
<th>Début de l'appel</th>
|
||||||
|
<th>Fin de l'appel</th>
|
||||||
|
<th>Direction</th>
|
||||||
|
<th class="checkcolumn">✓</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="text-right col-xs-12 no-padding">
|
||||||
|
<strong>Action pour la séléction :</strong>
|
||||||
|
<button class="btn btn-default btn-confirm" type="submit" formaction="<?php echo \descartes\Router::url('Call', 'delete', ['csrf' => $_SESSION['csrf']]); ?>"><span class="fa fa-trash-o"></span> Supprimer</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
jQuery(document).ready(function ()
|
||||||
|
{
|
||||||
|
jQuery('.datatable').DataTable({
|
||||||
|
"pageLength": 25,
|
||||||
|
"bLengthChange": false,
|
||||||
|
"language": {
|
||||||
|
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
||||||
|
},
|
||||||
|
"columnDefs": [{
|
||||||
|
'targets': 'checkcolumn',
|
||||||
|
'orderable': false,
|
||||||
|
}],
|
||||||
|
|
||||||
|
"ajax": {
|
||||||
|
'url': '<?php echo \descartes\Router::url('Call', 'list_json'); ?>',
|
||||||
|
'dataSrc': 'data',
|
||||||
|
},
|
||||||
|
"columns" : [
|
||||||
|
{
|
||||||
|
data: 'origin',
|
||||||
|
render: function (data, type, row, meta) {
|
||||||
|
if (row.direction === 'outbound') {
|
||||||
|
return row.phone_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row.contact_name) {
|
||||||
|
return row.origin_formatted + ' (' + jQuery.fn.dataTable.render.text().display(row.contact_name) + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
return row.origin_formatted;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'destination',
|
||||||
|
render: function (data, type, row, meta) {
|
||||||
|
if (row.direction === 'inbound') {
|
||||||
|
return row.phone_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row.contact_name) {
|
||||||
|
return row.destination_formatted + ' (' + jQuery.fn.dataTable.render.text().display(row.contact_name) + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
return row.destination_formatted;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{data: 'start', render: jQuery.fn.dataTable.render.text()},
|
||||||
|
{data: 'end', render: jQuery.fn.dataTable.render.text()},
|
||||||
|
{
|
||||||
|
data: 'direction',
|
||||||
|
render: function (data, type, row, meta) {
|
||||||
|
switch (data) {
|
||||||
|
case 'inbound':
|
||||||
|
return 'Appel entrant';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'outbound':
|
||||||
|
return 'Appel sortant';
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 'Inconnu';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'id',
|
||||||
|
render: function (data, type, row, meta) {
|
||||||
|
return '<input name="ids[]" type="checkbox" value="' + data + '">';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"deferRender": true
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<?php
|
||||||
|
$this->render('incs/footer');
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
//Template dashboard
|
//Template dashboard
|
||||||
|
|
||||||
$this->render('incs/head', ['title' => 'ConditionalGroupes Conditionnels - Show All'])
|
$this->render('incs/head', ['title' => 'Groupes Conditionnels - Show All'])
|
||||||
?>
|
?>
|
||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
<?php
|
<?php
|
||||||
|
|
|
@ -71,10 +71,13 @@
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="javascript:;" data-toggle="collapse" data-target="#logs"><i class="fa fa-fw fa-file-text"></i> Logs <i class="fa fa-fw fa-caret-down"></i></a>
|
<a href="javascript:;" data-toggle="collapse" data-target="#logs"><i class="fa fa-fw fa-file-text"></i> Logs <i class="fa fa-fw fa-caret-down"></i></a>
|
||||||
<ul id="logs" class="collapse <?php echo in_array($page, array('events', 'smsstop')) ? 'in' : ''; ?>">
|
<ul id="logs" class="collapse <?php echo in_array($page, array('events', 'smsstop', 'calls')) ? 'in' : ''; ?>">
|
||||||
<li <?php echo $page == 'smsstop' ? 'class="active"' : ''; ?>>
|
<li <?php echo $page == 'smsstop' ? 'class="active"' : ''; ?>>
|
||||||
<a href="<?php echo \descartes\Router::url('SmsStop', 'list'); ?>"><i class="fa fa-fw fa-ban"></i> SMS STOP</a>
|
<a href="<?php echo \descartes\Router::url('SmsStop', 'list'); ?>"><i class="fa fa-fw fa-ban"></i> SMS STOP</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li <?php echo $page == 'calls' ? 'class="active"' : ''; ?>>
|
||||||
|
<a href="<?php echo \descartes\Router::url('Call', 'list'); ?>"><i class="fa fa-fw fa-file-audio-o"></i> Appels</a>
|
||||||
|
</li>
|
||||||
<li <?php echo $page == 'events' ? 'class="active"' : ''; ?>>
|
<li <?php echo $page == 'events' ? 'class="active"' : ''; ?>>
|
||||||
<a href="<?php echo \descartes\Router::url('Event', 'list'); ?>"><i class="fa fa-fw fa-clock-o"></i> Évènements</a>
|
<a href="<?php echo \descartes\Router::url('Event', 'list'); ?>"><i class="fa fa-fw fa-clock-o"></i> Évènements</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -109,6 +109,23 @@ jQuery(document).ready(function ()
|
||||||
html += '<div>Non disponible.</div>';
|
html += '<div>Non disponible.</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html += '<br/>';
|
||||||
|
html += '<div class="bold">Notification d\'appel entrant : </div>';
|
||||||
|
|
||||||
|
if (row.callback_inbound_call) {
|
||||||
|
html += '<div><code>' + row.callback_inbound_call + '</code></div>';
|
||||||
|
} else {
|
||||||
|
html += '<div>Non disponible.</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '<br/>';
|
||||||
|
html += '<div class="bold">Notification de fin d\'appel : </div>';
|
||||||
|
console.log(row);
|
||||||
|
if (row.callback_end_call) {
|
||||||
|
html += '<div><code>' + row.callback_end_call + '</code></div>';
|
||||||
|
} else {
|
||||||
|
html += '<div>Non disponible.</div>';
|
||||||
|
}
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue