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
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
$id_user = $_SESSION['user']['id'];
|
||||
$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]);
|
||||
$this->render('phone/list');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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]);
|
||||
}
|
||||
|
||||
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');
|
||||
|
|
|
@ -18,6 +18,48 @@ namespace models;
|
|||
{
|
||||
const DIRECTION_INBOUND = 'inbound';
|
||||
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
|
||||
|
|
12
routes.php
12
routes.php
|
@ -58,10 +58,7 @@
|
|||
],
|
||||
|
||||
'Event' => [
|
||||
'list' => [
|
||||
'/event/',
|
||||
'/event/p/{page}/',
|
||||
],
|
||||
'list' => '/event/',
|
||||
'list_json' => '/event/json/',
|
||||
'delete' => '/event/delete/{csrf}/',
|
||||
],
|
||||
|
@ -155,6 +152,12 @@
|
|||
'delete' => '/phone/delete/{csrf}/',
|
||||
],
|
||||
|
||||
'Call' => [
|
||||
'list' => '/call/',
|
||||
'list_json' => '/call/json/',
|
||||
'delete' => '/call/delete/{csrf}/',
|
||||
],
|
||||
|
||||
'Webhook' => [
|
||||
'list' => '/webhook/',
|
||||
'list_json' => '/webhook/json/',
|
||||
|
@ -169,6 +172,7 @@
|
|||
'update_sended_status' => '/callback/status/{adapter_uid}/',
|
||||
'reception' => '/callback/reception/{adapter_uid}/{id_phone}/',
|
||||
'inbound_call' => '/callback/inbound_call/{id_phone}/',
|
||||
'end_call' => '/callback/end_call/{id_phone}/',
|
||||
],
|
||||
|
||||
'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
|
||||
//Template dashboard
|
||||
|
||||
$this->render('incs/head', ['title' => 'ConditionalGroupes Conditionnels - Show All'])
|
||||
$this->render('incs/head', ['title' => 'Groupes Conditionnels - Show All'])
|
||||
?>
|
||||
<div id="wrapper">
|
||||
<?php
|
||||
|
|
|
@ -71,10 +71,13 @@
|
|||
</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>
|
||||
<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"' : ''; ?>>
|
||||
<a href="<?php echo \descartes\Router::url('SmsStop', 'list'); ?>"><i class="fa fa-fw fa-ban"></i> SMS STOP</a>
|
||||
</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"' : ''; ?>>
|
||||
<a href="<?php echo \descartes\Router::url('Event', 'list'); ?>"><i class="fa fa-fw fa-clock-o"></i> Évènements</a>
|
||||
</li>
|
||||
|
|
|
@ -108,7 +108,24 @@ jQuery(document).ready(function ()
|
|||
} else {
|
||||
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;
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue