333 lines
12 KiB
PHP
333 lines
12 KiB
PHP
<?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 discussions.
|
|
*/
|
|
class Discussion extends \descartes\Controller
|
|
{
|
|
private $internal_sended;
|
|
private $internal_scheduled;
|
|
private $internal_received;
|
|
private $internal_contact;
|
|
private $internal_phone;
|
|
private $internal_media;
|
|
|
|
/**
|
|
* 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_sended = new \controllers\internals\Sended($bdd);
|
|
$this->internal_scheduled = new \controllers\internals\Scheduled($bdd);
|
|
$this->internal_received = new \controllers\internals\Received($bdd);
|
|
$this->internal_contact = new \controllers\internals\Contact($bdd);
|
|
$this->internal_phone = new \controllers\internals\Phone($bdd);
|
|
$this->internal_media = new \controllers\internals\Media($bdd);
|
|
|
|
\controllers\internals\Tool::verifyconnect();
|
|
}
|
|
|
|
/**
|
|
* Cette fonction retourne toutes les discussions, sous forme d'un tableau permettant l'administration de ces contacts.
|
|
*/
|
|
public function list()
|
|
{
|
|
$this->render('discussion/list');
|
|
}
|
|
|
|
/**
|
|
* Return discussions as json.
|
|
*/
|
|
public function list_json()
|
|
{
|
|
$entities = $this->internal_received->get_discussions_for_user($_SESSION['user']['id']);
|
|
|
|
foreach ($entities as &$entity)
|
|
{
|
|
$entity['number_formatted'] = \controllers\internals\Tool::phone_link($entity['number']);
|
|
$entity['link'] = \descartes\Router::url('Discussion', 'show', ['number' => $entity['number']]);
|
|
}
|
|
|
|
header('Content-Type: application/json');
|
|
echo json_encode(['data' => $entities]);
|
|
}
|
|
|
|
/**
|
|
* Cette fonction permet d'afficher la discussion avec un numero.
|
|
*
|
|
* @param string $number : La numéro de téléphone avec lequel on discute
|
|
*/
|
|
public function show($number)
|
|
{
|
|
$contact = $this->internal_contact->get_by_number_and_user($_SESSION['user']['id'], $number);
|
|
|
|
$last_sended = $this->internal_sended->get_last_for_destination_and_user($_SESSION['user']['id'], $number);
|
|
$last_received = $this->internal_received->get_last_for_origin_and_user($_SESSION['user']['id'], $number);
|
|
|
|
$response_phone_id = ($last_received['id_phone'] ?? $last_sended['id_phone'] ?? false);
|
|
if ($response_phone_id)
|
|
{
|
|
$response_phone = $this->internal_phone->get_for_user($_SESSION['user']['id'], $response_phone_id);
|
|
}
|
|
|
|
$this->render('discussion/show', [
|
|
'number' => $number,
|
|
'contact' => $contact,
|
|
'response_phone' => $response_phone ?? false,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Cette fonction récupère l'ensemble des messages pour un numéro, reçus, envoyés, en cours.
|
|
*
|
|
* @param string $number : Le numéro cible
|
|
* @param string $transaction_id : Le numéro unique de la transaction ajax (sert à vérifier si la requete doit être prise en compte)
|
|
*/
|
|
public function get_messages($number, $transaction_id)
|
|
{
|
|
$now = new \DateTime();
|
|
$now = $now->format('Y-m-d H:i:s');
|
|
|
|
$id_user = $_SESSION['user']['id'];
|
|
|
|
$sendeds = $this->internal_sended->gets_by_destination_and_user($id_user, $number);
|
|
$receiveds = $this->internal_received->gets_by_origin_and_user($id_user, $number);
|
|
$scheduleds = $this->internal_scheduled->gets_before_date_for_number_and_user($id_user, $now, $number);
|
|
|
|
$messages = [];
|
|
|
|
foreach ($sendeds as $sended)
|
|
{
|
|
$medias = [];
|
|
if ($sended['mms'])
|
|
{
|
|
$medias = $this->internal_media->gets_for_sended($sended['id']);
|
|
foreach ($medias as &$media)
|
|
{
|
|
$media = HTTP_PWD_DATA_PUBLIC . '/' . $media['path'];
|
|
}
|
|
}
|
|
|
|
$message = [
|
|
'uid' => 'sended-' . $sended['id'],
|
|
'date' => htmlspecialchars($sended['at']),
|
|
'text' => htmlspecialchars($sended['text']),
|
|
'type' => 'sended',
|
|
'medias' => $medias,
|
|
'status' => $sended['status'],
|
|
];
|
|
|
|
$messages[] = $message;
|
|
}
|
|
|
|
foreach ($receiveds as $received)
|
|
{
|
|
if ('read' !== $received['status'])
|
|
{
|
|
$this->internal_received->mark_as_read_for_user($id_user, $received['id']);
|
|
}
|
|
|
|
$medias = [];
|
|
if ($received['mms'])
|
|
{
|
|
$medias = $this->internal_media->gets_for_received($received['id']);
|
|
foreach ($medias as &$media)
|
|
{
|
|
$media = HTTP_PWD_DATA_PUBLIC . '/' . $media['path'];
|
|
}
|
|
}
|
|
|
|
$messages[] = [
|
|
'uid' => 'received-' . $received['id'],
|
|
'date' => htmlspecialchars($received['at']),
|
|
'text' => htmlspecialchars($received['text']),
|
|
'type' => 'received',
|
|
'medias' => $medias,
|
|
];
|
|
}
|
|
|
|
foreach ($scheduleds as $scheduled)
|
|
{
|
|
$medias = [];
|
|
if ($scheduled['mms'])
|
|
{
|
|
$medias = $this->internal_media->gets_for_scheduled($scheduled['id']);
|
|
foreach ($medias as &$media)
|
|
{
|
|
$media = HTTP_PWD_DATA_PUBLIC . '/' . $media['path'];
|
|
}
|
|
}
|
|
|
|
$messages[] = [
|
|
'uid' => 'scheduled-' . $scheduled['id'],
|
|
'date' => htmlspecialchars($scheduled['at']),
|
|
'text' => htmlspecialchars($scheduled['text']),
|
|
'type' => 'inprogress',
|
|
'medias' => $medias,
|
|
];
|
|
}
|
|
|
|
//On va trier le tableau des messages
|
|
usort($messages, function ($a, $b)
|
|
{
|
|
return strtotime($a['date']) - strtotime($b['date']);
|
|
});
|
|
|
|
//Récupère uniquement les 25 derniers messages sur l'ensemble pour limiter la charge
|
|
$messages = \array_slice($messages, -25);
|
|
|
|
$response = [
|
|
'transaction_id' => $transaction_id,
|
|
'messages' => $messages,
|
|
];
|
|
|
|
echo json_encode($response);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Cette fonction permet d'envoyer facilement un sms à un numéro donné.
|
|
*
|
|
* @param string $csrf : Le jeton csrf
|
|
* @param string $_POST['text'] : Le contenu du Sms
|
|
* @param string $_POST['destination'] : Number to send sms to
|
|
* @param string $_POST['id_phone'] : If of phone to send sms with
|
|
* @param array $_FILES['medias'] : Medias to upload and link to sms
|
|
*
|
|
* @return string : json string Le statut de l'envoi
|
|
*/
|
|
public function send($csrf)
|
|
{
|
|
$return = ['success' => true, 'message' => ''];
|
|
|
|
//On vérifie que le jeton csrf est bon
|
|
if (!$this->verify_csrf($csrf))
|
|
{
|
|
$return['success'] = false;
|
|
$return['message'] = 'Jeton CSRF invalide';
|
|
echo json_encode($return);
|
|
|
|
return false;
|
|
}
|
|
|
|
$now = new \DateTime();
|
|
$now = $now->format('Y-m-d H:i:s');
|
|
|
|
$id_user = $_SESSION['user']['id'];
|
|
$at = $now;
|
|
$text = $_POST['text'] ?? '';
|
|
$destination = $_POST['destination'] ?? false;
|
|
$tag = $_POST['tag'] ?? null;
|
|
$id_phone = $_POST['id_phone'] ?? false;
|
|
$files = $_FILES['medias'] ?? false;
|
|
|
|
//Iterate over files to re-create individual $_FILES array
|
|
$files_arrays = [];
|
|
if ($files && is_array($files['name']))
|
|
{
|
|
foreach ($files as $property_name => $files_values)
|
|
{
|
|
foreach ($files_values as $file_key => $property_value)
|
|
{
|
|
if (!isset($files_arrays[$file_key]))
|
|
{
|
|
$files_arrays[$file_key] = [];
|
|
}
|
|
|
|
$files_arrays[$file_key][$property_name] = $property_value;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Remove empty files input
|
|
foreach ($files_arrays as $key => $file)
|
|
{
|
|
if (UPLOAD_ERR_NO_FILE === $file['error'])
|
|
{
|
|
unset($files_arrays[$key]);
|
|
}
|
|
}
|
|
|
|
if (!$text)
|
|
{
|
|
$return['success'] = false;
|
|
$return['message'] = 'Vous devez renseigner le texte de votre sms.';
|
|
echo json_encode($return);
|
|
|
|
return false;
|
|
}
|
|
|
|
if (!$destination)
|
|
{
|
|
$return['success'] = false;
|
|
$return['message'] = 'Vous devez renseigner un numéro valide';
|
|
echo json_encode($return);
|
|
|
|
return false;
|
|
}
|
|
|
|
if (!$id_phone)
|
|
{
|
|
$id_phone = null;
|
|
}
|
|
|
|
//If mms is enable and we have medias uploaded
|
|
$media_ids = [];
|
|
if ($_SESSION['user']['settings']['mms'] && $files_arrays)
|
|
{
|
|
foreach ($files_arrays as $file)
|
|
{
|
|
try
|
|
{
|
|
$new_media_id = $this->internal_media->create_from_uploaded_file_for_user($_SESSION['user']['id'], $file);
|
|
}
|
|
catch (\Exception $e)
|
|
{
|
|
$return['success'] = false;
|
|
$return['message'] = $e->getMessage();
|
|
echo json_encode($return);
|
|
|
|
return false;
|
|
}
|
|
|
|
$media_ids[] = $new_media_id;
|
|
}
|
|
}
|
|
|
|
$mms = (bool) count($media_ids);
|
|
|
|
//Destinations must be an array of number
|
|
$destinations = [['number' => $destination, 'data' => '[]']];
|
|
|
|
if (!$this->internal_scheduled->create($id_user, $at, $text, $id_phone, null, false, $mms, $tag, $destinations, [], [], [], $media_ids))
|
|
{
|
|
$return['success'] = false;
|
|
$return['message'] = 'Impossible de créer le Sms';
|
|
echo json_encode($return);
|
|
|
|
return false;
|
|
}
|
|
|
|
echo json_encode($return);
|
|
|
|
return true;
|
|
}
|
|
}
|