first refonte

This commit is contained in:
osaajani 2019-10-29 14:57:13 +01:00
commit 9e9cd47b91
226 changed files with 34307 additions and 0 deletions

174
controllers/publics/Account.php Executable file
View file

@ -0,0 +1,174 @@
<?php
namespace controllers\publics;
class Account extends \Controller
{
public $internal_user;
public function __construct ()
{
$bdd = Model::connect(DATABASE_HOST, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD);
$this->internal_user = new \controllers\internals\User($bdd);
\controllers\internals\Tool::verify_connect();
}
/**
* Show profile page
*/
public function show ()
{
$this->render('account/show');
}
/**
* Update connected user password
* @param $csrf : Le jeton CSRF
* @param string $_POST['password'] : The new password
* @return void;
*/
public function update_password ($csrf)
{
$password = $_POST['password'] ?? false;
if (!$this->verifyCSRF($csrf))
{
\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('Account', 'show'));
}
if (!$password)
{
\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Vous devez renseigner un mot de passe.');
return header('Location: ' . \Router::url('Account', 'show'));
}
$update_password_result = $this->internal_user->update_password($_SESSION['user']['id'], $password);
if (!$update_password_result)
{
\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Impossible de mettre à jour le mot de passe.');
return header('Location: ' . \Router::url('Account', 'show'));
}
\DescartesSessionMessages\internals\DescartesSessionMessages::push('success', 'Le mot de passe a bien été mis à jour.');
return header('Location: ' . \Router::url('Account', 'show'));
}
/**
* Update user mail transfer property
* @param $csrf : CSRF token
* @param string $_POST['transfer'] : New transfer property value
*/
public function update_transfer ($csrf)
{
$transfer = $_POST['transfer'] ?? false;
if (!$this->verifyCSRF($csrf))
{
\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('Account', 'show'));
}
if ($transfer === false)
{
\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Vous devez choisir une option parmis celles de la liste déroulante.');
return header('Location: ' . \Router::url('Account', 'show'));
}
$transfer_update_result = $this->internal_user->update_transfer($_SESSION['user']['id'], $transfer);
if (!$transfer_update_result)
{
\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Impossible de mettre à jour.');
return header('Location: ' . \Router::url('Account', 'show'));
}
$_SESSION['user']['transfer'] = $transfer;
\DescartesSessionMessages\internals\DescartesSessionMessages::push('success', 'Le transfert a bien été ' . ($transfer ? 'activé' : 'désactivé') . '.');
return header('Location: ' . \Router::url('Account', 'show'));
}
/**
* Update user email
* @param $csrf : Le jeton CSRF
* @param string $_POST['email'] : User new email
* @param string $_POST['verif_email'] : Verif email
*/
public function update_email ($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('Account', 'show'));
}
$email = $_POST['email'] ?? false;
if (!$email)
{
\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Vous devez fournir une adresse e-mail !');
return header('Location: ' . \Router::url('Account', 'show'));
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL))
{
\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'L\'adresse e-mail n\'est pas une adresse valide.');
return header('Location: ' . \Router::url('Account', 'show'));
}
$update_email_result = $this->internal_user->update_email($_SESSION['user']['id'], $email);
if (!$update_email_result)
{
\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Impossible de mettre à jour.');
return header('Location: ' . \Router::url('Account', 'show'));
}
$_SESSION['user']['email'] = $email;
\DescartesSessionMessages\internals\DescartesSessionMessages::push('success', 'L\'email a bien été mis à jour.');
return header('Location: ' . \Router::url('Account', 'show'));
}
/**
* Delete a user
* @param string $_POST['delete_account'] : Boolean to see if we want to delete
* @return boolean;
*/
public function delete ($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('Account', 'show'));
}
$delete_account = $_POST['delete_account'] ?? false;
if (!$delete_account)
{
\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Pour supprimer le compte, vous devez cocher la case correspondante.');
return header('Location: ' . \Router::url('Account', 'show'));
}
$delete_account_result = $this->internal_user->delete($_SESSION['user']['id']);
if (!$delete_account_result)
{
\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Impossible de supprimer le compte.');
return header('Location: ' . \Router::url('Account', 'show'));
}
return $this->logout();
}
/**
* Logout a user and redirect to login page
* @return void
*/
public function logout()
{
session_unset();
session_destroy();
return header('Location: ' . \Router::url('Connect', 'login'));
}
}

150
controllers/publics/Command.php Executable file
View file

@ -0,0 +1,150 @@
<?php
namespace controllers\publics;
/**
* Page des commandes
*/
class Command extends \Controller
{
public $bdd;
public function __construct ()
{
$bdd = Model::connect(DATABASE_HOST, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD);
$this->internal_command = new \Controller\internals\Command($bdd);
$this->internal_event = new \Controller\internals\Event($bdd);
\controllers\internals\Tool::verify_connect();
}
/**
* Cette fonction retourne tous les users, sous forme d'un tableau permettant l'administration de ces users
*/
public function list ($page = 0)
{
$page = (int) $page;
$commands = $this->internal_command->list(25, $page);
$this->render('command/list', ['commands' => $commands]);
}
/**
* Cette fonction va supprimer une liste de commands
* @param array int $_GET['ids'] : Les id des commandes à supprimer
* @return boolean;
*/
public function delete($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
header('Location: ' . \Router::url('Command', 'list'));
return false;
}
$ids = $_GET['ids'] ?? [];
foreach ($ids as $id)
{
$this->internalCommand->delete($id);
}
header('Location: ' . \Router::url('Command', 'list'));
return true;
}
/**
* Cette fonction retourne la page d'ajout d'une commande
*/
public function add()
{
$this->render('command/add');
}
/**
* Cette fonction retourne la page d'édition des commandes
* @param array int $_GET['ids'] : Les id des commandes à editer
*/
public function edit()
{
global $db;
$ids = $_GET['ids'] ?? [];
$commands = $this->internalCommand->get_by_ids($ids);
$this->render('command/edit', array(
'commands' => $commands,
));
}
/**
* Cette fonction insert une nouvelle commande
* @param $csrf : Le jeton CSRF
* @param string $_POST['name'] : Le nom de la commande
* @param string $_POST['script'] : Le script a appeler
* @param boolean $_POST['admin'] : Si la commande necessite les droits d'admin (par défaut non)
* @return boolean;
*/
public function create($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
header('Location: ' . \Router::url('Command', 'list'));
return false;
}
$name = $_POST['name'] ?? false;
$script = $_POST['script'] ?? false;
$admin = (isset($_POST['admin']) ? $_POST['admin'] : false);
if (!$name || !$script)
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Renseignez au moins un nom et un script.');
return header('Location: ' . \Router::url('Command', 'list'));
}
if (!$this->internalCommand->create($name, $script, $admin))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Impossible créer cette commande.');
return header('Location: ' . \Router::url('commands', 'add'));
}
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('success', 'La commande a bien été crée.');
return header('Location: ' . \Router::url('Command', 'list'));
}
/**
* Cette fonction met à jour une commande
* @param $csrf : Le jeton CSRF
* @param array $_POST['commands'] : Un tableau des commandes avec leur nouvelle valeurs
* @return boolean;
*/
public function update($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
header('Location: ' . \Router::url('Command', 'list'));
return false;
}
$nb_commands_update = 0;
foreach ($_POST['commands'] as $command)
{
$update_command = $this->internalCommand->update($command['id'], $command['name'], $command['script'], $command['admin']);
$nb_commands_update += (int) $update_command;
}
if ($nb_commands_update != count($_POST['commands']))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Certaines commandes n\'ont pas pu êtres mises à jour.');
header('Location: ' . \Router::url('Command', 'list'));
return false;
}
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('success', 'Toutes les commandes ont été modifiées avec succès.');
header('Location: ' . \Router::url('Command', 'list'));
return true;
}
}

136
controllers/publics/Connect.php Executable file
View file

@ -0,0 +1,136 @@
<?php
namespace controllers\publics;
/**
* Page de connexion
*/
class Connect extends \Controller
{
/**
* Cette fonction est appelée avant toute les autres :
* @return void;
*/
public function _before()
{
global $bdd;
global $model;
$this->bdd = $bdd;
$this->model = $model;
$this->internal_user = new \controllers\internals\User($this->bdd);
}
/**
* Cette fonction retourne la fenetre de connexion
*/
public function login ()
{
$this->render('connect/login');
}
/**
* Cette fonction connecte un utilisateur, et le redirige sur la page d'accueil
* @param string $_POST['mail'] : L'email de l'utilisateur
* @param string $_POST['password'] : Le mot de passe de l'utilisateur
* @return void
*/
public function connection()
{
$email = $_POST['mail'] ?? false;
$password = $_POST['password'] ?? false;
$user = $this->internal_user->check_credentials($email, $password);
if (!$user)
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Email ou mot de passe invalide.');
return header('Location: ' . \Router::url('Connect', 'login'));
}
$_SESSION['connect'] = true;
$_SESSION['user'] = $user;
$_SESSION['csrf'] = str_shuffle(uniqid().uniqid());
return header('Location: ' . \Router::url('Dashboard', 'show'));
}
/**
* Cette fonction retourne la fenetre de changement de password
* @return void;
*/
public function forget_password()
{
$this->render('connect/forget-password');
}
/**
* Cette fonction envoi un email contenant un lien pour re-générer un password oublié
* @param string $csrf : jeton csrf
* @param string $_POST['email'] : L'email pour lequel on veut envoyer un nouveau password
*/
public function send_reset_password ($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
header('Location: ' . \Router::url('Connect', 'forget_password'));
return false;
}
$email = $_POST['email'] ?? false;
$user = $this->internal_user->get_by_email($email);
if (!$email || !$user)
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Aucun utilisateur n\'existe pour cette adresse mail.');
header('Location: ' . \Router::url('Connect', 'forget_password'));
return false;
}
$Tokenista = new \Ingenerator\Tokenista(APP_SECRET);
$token = $Tokenista->generate(3600, ['user_id' => $user['id']]);
$reset_link = \Router::url('Connect', 'reset_password', ['user_id' => $user['id'], 'token' => $token]);
\controllers\internals\Tool::send_email($email, EMAIL_RESET_PASSWORD, ['reset_link' => $reset_link]);
return $this->render('connect/send-reset-password');
}
/**
* Cette fonction permet à un utilisateur de re-définir son mot de passe
* @param int $user_id : L'id du user dont on veut modifier le password
* @param string $token : Le token permetttant de vérifier que l'opération est légitime
* @param optionnal $_POST['password'] : Le nouveau password à utiliser
*/
public function reset_password ($user_id, $token)
{
$password = $_POST['password'] ?? false;
$Tokenista = new \Ingenerator\Tokenista(APP_SECRET);
if (!$Tokenista->isValid($token, ['user_id' => $user_id]))
{
return $this->render('connect/reset-password-invalid');
}
if (!$password)
{
return $this->render('connect/reset-password');
}
$this->internal_user->update_password($user_id, $password);
return $this->render('connect/reset-password-done');
}
/**
* Cette fonction déconnecte un utilisateur et le renvoie sur la page d'accueil
* @return void
*/
public function logout()
{
session_unset();
session_destroy();
header('Location: ' . \Router::url('Connect', 'login'));
}
}

160
controllers/publics/Contact.php Executable file
View file

@ -0,0 +1,160 @@
<?php
namespace controllers\publics;
/**
* Page des contacts
*/
class Contact extends \Controller
{
/**
* Cette fonction est appelée avant toute les autres :
* Elle vérifie que l'utilisateur est bien connecté
* @return void;
*/
public function _before()
{
global $bdd;
$this->bdd = $bdd;
$this->internalContact = new \controllers\internals\Contact($this->bdd);
$this->internalEvent = new \controllers\internals\Event($this->bdd);
\controllers\internals\Tool::verify_connect();
}
/**
* Cette fonction retourne tous les contacts, sous forme d'un tableau permettant l'administration de ces contacts
*/
public function list ($page = 0)
{
$page = (int) $page;
$contacts = $this->internalContact->get_list(25, $page);
$this->render('contact/list', ['contacts' => $contacts]);
}
/**
* Cette fonction va supprimer une liste de contacts
* @param array int $_GET['ids'] : Les id des contactes à supprimer
* @return boolean;
*/
public function delete ($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('Contact', 'list'));
}
$ids = $_GET['ids'] ?? [];
foreach ($ids as $id)
{
$this->internalContact->delete($id);
}
header('Location: ' . \Router::url('Contact', 'list'));
return true;
}
/**
* Cette fonction retourne la page d'ajout d'un contact
*/
public function add()
{
$this->render('contact/add');
}
/**
* Cette fonction retourne la page d'édition des contacts
* @param int... $ids : Les id des contactes à supprimer
*/
public function edit()
{
global $db;
$ids = $_GET['ids'] ?? [];
$contacts = $this->internalContact->get_by_ids($ids);
$this->render('contact/edit', array(
'contacts' => $contacts,
));
}
/**
* Cette fonction insert un nouveau contact
* @param $csrf : Le jeton CSRF
* @param string $_POST['name'] : Le nom du contact
* @param string $_POST['phone'] : Le numero de téléphone du contact
*/
public function create($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('Contact', 'add'));
}
$name = $_POST['name'] ?? false;
$number = $_POST['number'] ?? false;
if (!$name || !$number)
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Des champs sont manquants !');
return header('Location: ' . \Router::url('Contact', 'add'));
}
$number = \controllers\internals\Tool::parse_phone($number);
if (!$number)
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Numéro de téléphone incorrect.');
return header('Location: ' . \Router::url('Contact', 'add'));
}
if (!$this->internalContact->create($number, $name))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Impossible de créer ce contact.');
return header('Location: ' . \Router::url('Contact', 'add'));
}
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('success', 'Le contact a bien été créé.');
return header('Location: ' . \Router::url('Contact', 'list'));
}
/**
* Cette fonction met à jour une contacte
* @param $csrf : Le jeton CSRF
* @param array $_POST['contacts'] : Un tableau des contactes avec leur nouvelle valeurs
* @return boolean;
*/
public function update($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('Contact', 'list'));
}
$nb_contacts_update = 0;
foreach ($_POST['contacts'] as $contact)
{
$nb_contacts_update += $this->internalContact->update($contact['id'], $contact['number'], $contact['name']);
}
if ($nb_contacts_update != count($_POST['contacts']))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Certais contacts n\'ont pas pu êtres mis à jour.');
return header('Location: ' . \Router::url('Contact', 'list'));
}
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('success', 'Tous les contacts ont été modifiés avec succès.');
return header('Location: ' . \Router::url('Contact', 'list'));
}
/**
* Cette fonction retourne la liste des contacts sous forme JSON
*/
public function json_list()
{
header('Content-Type: application/json');
echo json_encode($this->internalContact->get_list());
}
}

120
controllers/publics/Dashboard.php Executable file
View file

@ -0,0 +1,120 @@
<?php
namespace controllers\publics;
/**
* Page d'index, qui gère l'affichage par défaut temporairement
*/
class Dashboard extends \Controller
{
/**
* Cette fonction est appelée avant toute les autres :
* Elle vérifie que l'utilisateur est bien connecté
* @return void;
*/
public function _before()
{
global $bdd;
$this->bdd = $bdd;
$this->internalSended = new \controllers\internals\Sended($this->bdd);
$this->internalReceived = new \controllers\internals\Received($this->bdd);
$this->internalContact = new \controllers\internals\Contact($this->bdd);
$this->internalGroupe = new \controllers\internals\Groupe($this->bdd);
$this->internalScheduled = new \controllers\internals\Scheduled($this->bdd);
$this->internalCommand = new \controllers\internals\Command($this->bdd);
$this->internalEvent = new \controllers\internals\Event($this->bdd);
\controllers\internals\Tool::verify_connect();
}
/**
* Cette fonction est un alias de show
* @return void;
*/
public function show ()
{
//Creation de l'object de base de données
global $db;
//Recupération des nombres des 4 panneaux d'accueil
$nb_contacts = $this->internalContact->count();
$nb_groupes = $this->internalGroupe->count();
$nb_scheduleds = $this->internalScheduled->count();
$nb_commands = $this->internalCommand->count();
$nb_sendeds = $this->internalSended->count();
$nb_receiveds = $this->internalReceived->count();
//Création de la date d'il y a une semaine
$now = new \DateTime();
$one_week = new \DateInterval('P7D');
$date = $now->sub($one_week);
$formated_date = $date->format('Y-m-d');
//Récupération des 10 derniers SMS envoyés, SMS reçus et evenements enregistrés. Par date.
$sendeds = $this->internalSended->get_lasts_by_date(10);
$receiveds = $this->internalReceived->get_lasts_by_date(10);
$events = $this->internalEvent->get_lasts_by_date(10);
//Récupération du nombre de SMS envoyés et reçus depuis les 7 derniers jours
$nb_sendeds_by_day = $this->internalSended->count_by_day_since($formated_date);
$nb_receiveds_by_day = $this->internalReceived->count_by_day_since($formated_date);
//On va traduire ces données pour les afficher en graphique
$array_area_chart = array();
$today_less_7_day = new \DateTime();
$today_less_7_day->sub(new \DateInterval('P7D'));
$increment_day = new \DateInterval('P1D');
$i = 0;
//On va construire un tableau avec la date en clef, et les données pour chaque date
while ($i < 7)
{
$today_less_7_day->add($increment_day);
$i ++;
$date_f = $today_less_7_day->format('Y-m-d');
$array_area_chart[$date_f] = array(
'period' => $date_f,
'sendeds' => 0,
'receiveds' => 0,
);
}
$total_sendeds = 0;
$total_receiveds = 0;
//0n remplie le tableau avec les données adaptées
foreach ($nb_sendeds_by_day as $date => $nb_sended)
{
$array_area_chart[$date]['sendeds'] = $nb_sended;
$total_sendeds += $nb_sended;
}
foreach ($nb_receiveds_by_day as $date => $nb_received)
{
$array_area_chart[$date]['receiveds'] = $nb_received;
$total_receiveds += $nb_received;
}
$avg_sendeds = round($total_sendeds / 7, 2);
$avg_receiveds = round($total_receiveds / 7, 2);
$array_area_chart = array_values($array_area_chart);
$this->render('dashboard/show', array(
'nb_contacts' => $nb_contacts,
'nb_groupes' => $nb_groupes,
'nb_scheduleds' => $nb_scheduleds,
'nb_commands' => $nb_commands,
'nb_sendeds' => $nb_sendeds,
'nb_receiveds' => $nb_receiveds,
'avg_sendeds' => $avg_sendeds,
'avg_receiveds' => $avg_receiveds,
'sendeds' => $sendeds,
'receiveds' => $receiveds,
'events' => $events,
'datas_area_chart' => json_encode($array_area_chart),
));
}
}

View file

@ -0,0 +1,239 @@
<?php
namespace controllers\publics;
/**
* Page des discussions
*/
class Discussion extends \Controller
{
/**
* Cette fonction est appelée avant toute les autres :
* Elle vérifie que l'utilisateur est bien connecté
* @return void;
*/
public function _before()
{
global $bdd;
global $model;
$this->bdd = $bdd;
$this->model = $model;
$this->internalSended = new \controllers\internals\Sended($this->bdd);
$this->internalScheduled = new \controllers\internals\Scheduled($this->bdd);
$this->internalReceived = new \controllers\internals\Received($this->bdd);
$this->internalContact = new \controllers\internals\Contact($this->bdd);
\controllers\internals\Tool::verify_connect();
}
/**
* Cette fonction retourne toutes les discussions, sous forme d'un tableau permettant l'administration de ces contacts
*/
public function list ()
{
$discussions = $this->internalReceived->get_discussions();
foreach ($discussions as $key => $discussion)
{
if (!$contact = $this->internalContact->get_by_number($discussion['number']))
{
continue;
}
$discussions[$key]['contact'] = $contact['name'];
}
$this->render('discussion/list', array(
'discussions' => $discussions,
));
}
/**
* 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->internalContact->get_by_number($number);
$this->render('discussion/show', array(
'number' => $number,
'contact' => $contact,
));
}
/**
* Cette fonction récupère l'ensemble des messages pour un numéro, recç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)
*/
function get_messages($number, $transaction_id)
{
$now = new \DateTime();
$now = $now->format('Y-m-d H:i:s');
$sendeds = $this->internalSended->get_by_target($number);
$receiveds = $this->internalReceived->get_by_send_by($number);
$scheduleds = $this->internalScheduled->get_before_date_for_number($now, $number);
$messages = [];
foreach ($sendeds as $sended)
{
$messages[] = array(
'date' => htmlspecialchars($sended['at']),
'text' => htmlspecialchars($sended['content']),
'type' => 'sended',
'status' => ($sended['delivered'] ? 'delivered' : ($sended['failed'] ? 'failed' : '')),
);
}
foreach ($receiveds as $received)
{
$messages[] = array(
'date' => htmlspecialchars($received['at']),
'text' => htmlspecialchars($received['content']),
'type' => 'received',
'md5' => md5($received['at'] . $received['content']),
);
}
foreach ($scheduleds as $scheduled)
{
$messages[] = array(
'date' => htmlspecialchars($scheduled['at']),
'text' => htmlspecialchars($scheduled['content']),
'type' => 'inprogress',
);
}
//On va trier le tableau des messages
usort($messages, function($a, $b) {
return strtotime($a["date"]) - strtotime($b["date"]);
});
//On récupère uniquement les 25 derniers messages sur l'ensemble
$messages = array_slice($messages, -25);
echo json_encode(['transaction_id' => $transaction_id, 'messages' => $messages]);
return true;
}
/**
* Cette fonction permet d'envoyer facilement un sms à un numéro donné
* @param string $csrf : Le jeton csrf
* @param string $_POST['content'] : Le contenu du SMS
* @param string $_POST['numbers'] : Un tableau avec le numero des gens auxquel envoyer le sms
* @return json : Le statut de l'envoi
*/
function send ($csrf)
{
$return = ['success' => true, 'message' => ''];
//On vérifie que le jeton csrf est bon
if (!$this->verifyCSRF($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');
$scheduled = [];
$scheduled['at'] = $now;
$scheduled['content'] = $_POST['content'] ?? '';
$numbers = $_POST['numbers'] ?? false;
if (!$numbers)
{
$return['success'] = false;
$return['message'] = 'Vous devez renseigner un numéro valide';
echo json_encode($return);
return false;
}
if (!$this->internalScheduled->create($scheduled, $numbers))
{
$return['success'] = false;
$return['message'] = 'Impossible de créer le SMS';
echo json_encode($return);
return false;
}
echo json_encode($return);
return true;
}
/**
* Cette fonction retourne les id des sms qui sont envoyés
* @return json : Tableau des ids des sms qui sont envoyés
*/
function checksendeds ()
{
$_SESSION['discussion_wait_progress'] = isset($_SESSION['discussion_wait_progress']) ? $_SESSION['discussion_wait_progress'] : [];
$scheduleds = $this->internalScheduled->get_by_ids($_SESSION['discussion_wait_progress']);
//On va chercher à chaque fois si on a trouvé le sms. Si ce n'est pas le cas c'est qu'il a été envoyé
$sendeds = [];
foreach ($_SESSION['discussion_wait_progress'] as $key => $id_scheduled)
{
$found = false;
foreach ($scheduleds as $scheduled)
{
if ($id == $scheduled['id'])
{
$found = true;
}
}
if (!$found)
{
unset($_SESSION['discussion_wait_progress'][$key]);
$sendeds[] = $id;
}
}
echo json_encode($sendeds);
return true;
}
/**
* Cette fonction retourne les messages reçus pour un numéro après la date $_SESSION['discussion_last_checkreceiveds']
* @param string $number : Le numéro de téléphone pour lequel on veux les messages
* @return json : Un tableau avec les messages
*/
function checkreceiveds ($number)
{
$now = new \DateTime();
$now = $now->format('Y-m-d H:i');
$_SESSION['discussion_last_checkreceiveds'] = isset($_SESSION['discussion_last_checkreceiveds']) ? $_SESSION['discussion_last_checkreceiveds'] : $now;
$receiveds = $internalReceived->get_since_for_number_by_date($_SESSION['discussion_last_checkreceiveds'], $number);
//On va gérer le cas des messages en double en stockant ceux déjà reçus et en eliminant les autres
$_SESSION['discussion_already_receiveds'] = isset($_SESSION['discussion_already_receiveds']) ? $_SESSION['discussion_already_receiveds'] : [];
foreach ($receiveds as $key => $received)
{
//Sms jamais recu
if (array_search($received['id'], $_SESSION['discussion_already_receiveds']) === false)
{
$_SESSION['discussion_already_receiveds'][] = $received['id'];
continue;
}
//Sms déjà reçu => on le supprime des resultats
unset($receiveds[$key]);
}
//On met à jour la date de dernière verif
$_SESSION['discussion_last_checkreceiveds'] = $now;
echo json_encode($receiveds);
}
}

61
controllers/publics/Event.php Executable file
View file

@ -0,0 +1,61 @@
<?php
namespace controllers\publics;
/**
* Page des events
*/
class Event extends \Controller
{
/**
* Cette fonction est appelée avant toute les autres :
* Elle vérifie que l'utilisateur est bien connecté
* @return void;
*/
public function _before()
{
global $bdd;
$this->bdd = $bdd;
$this->internalEvent = new \controllers\internals\Event($this->bdd);
\controllers\internals\Tool::verify_connect();
}
/**
* Cette fonction retourne tous les events, sous forme d'un tableau permettant l'administration de ces events
*/
public function list ($page = 0)
{
$page = (int) $page;
$limit = 25;
$events = $this->internalEvent->get_list($limit, $page);
$this->render('event/list', ['events' => $events, 'limit' => $limit, 'page' => $page, 'nb_results' => count($events)]);
}
/**
* Cette fonction va supprimer une liste de events
* @param array int $_GET['ids'] : Les id des eventes à supprimer
* @return boolean;
*/
public function delete ($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('Event', 'list'));
}
if (!\controllers\internals\Tool::is_admin())
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Vous devez être admin pour pouvoir supprimer des events.');
return header('Location: ' . \Router::url('Event', 'list'));
}
$ids = $_GET['ids'] ?? [];
foreach ($ids as $id)
{
$this->internalEvent->delete($id);
}
return header('Location: ' . \Router::url('Event', 'list'));
}
}

167
controllers/publics/Groupe.php Executable file
View file

@ -0,0 +1,167 @@
<?php
namespace controllers\publics;
/**
* Page des groupes
*/
class Groupe extends \Controller
{
/**
* Cette fonction est appelée avant toute les autres :
* Elle vérifie que l'utilisateur est bien connecté
* @return void;
*/
public function _before()
{
global $bdd;
$this->bdd = $bdd;
$this->internalGroupe = new \controllers\internals\Groupe($this->bdd);
$this->internalContact = new \controllers\internals\Contact($this->bdd);
$this->internalEvent = new \controllers\internals\Event($this->bdd);
\controllers\internals\Tool::verify_connect();
}
/**
* Cette fonction retourne tous les groupes, sous forme d'un tableau permettant l'administration de ces groupes
*/
public function list ($page = 0)
{
$page = (int) $page;
$groupes = $this->internalGroupe->get_list(25, $page);
foreach ($groupes as $key => $groupe)
{
$contacts = $this->internalGroupe->get_contact($groupe['id']);
$groupes[$key]['nb_contacts'] = count($contacts);
}
$this->render('groupe/list', ['groupes' => $groupes]);
}
/**
* Cette fonction va supprimer une liste de groupes
* @param array int $_GET['ids'] : Les id des groupes à supprimer
* @return boolean;
*/
public function delete($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
header('Location: ' . \Router::url('Groupe', 'list'));
return false;
}
$ids = $_GET['ids'] ?? [];
$this->internalGroupe->delete($ids);
header('Location: ' . \Router::url('Groupe', 'list'));
return true;
}
/**
* Cette fonction retourne la page d'ajout d'un groupe
*/
public function add()
{
$this->render('groupe/add');
}
/**
* Cette fonction retourne la page d'édition des groupes
* @param int... $ids : Les id des groupes à supprimer
*/
public function edit()
{
$ids = $_GET['ids'] ?? [];
$groupes = $this->internalGroupe->get_by_ids
($ids);
foreach ($groupes as $key => $groupe)
{
$groupes[$key]['contacts'] = $this->internalGroupe->get_contact($groupe['id']);
}
$this->render('groupe/edit', array(
'groupes' => $groupes,
));
}
/**
* Cette fonction insert un nouveau groupe
* @param $csrf : Le jeton CSRF
* @param string $_POST['name'] : Le nom du groupe
* @param array $_POST['contacts'] : Les ids des contacts à mettre dans le groupe
*/
public function create ($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('Groupe', 'add'));
}
$name = $_POST['name'] ?? false;
$contacts_ids = $_POST['contacts'] ?? false;
if (!$name || !$contacts_ids)
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Des champs sont manquants !');
return header('Location: ' . \Router::url('Groupe', 'add'));
}
$id_groupe = $this->internalGroupe->create($name, $contacts_ids);
if (!$id_groupe)
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Impossible de créer ce groupe.');
return header('Location: ' . \Router::url('Groupe', 'add'));
}
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('success', 'Le groupe a bien été créé.');
return header('Location: ' . \Router::url('Groupe', 'list'));
}
/**
* Cette fonction met à jour une groupe
* @param $csrf : Le jeton CSRF
* @param array $_POST['groupes'] : Un tableau des groupes avec leur nouvelle valeurs & une entrée 'contacts_id' avec les ids des contacts pour chaque groupe
* @return boolean;
*/
public function update ($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
header('Location: ' . \Router::url('Groupe', 'list'));
return false;
}
$groupes = $_POST['groupes'] ?? [];
$nb_groupes_update = 0;
foreach ($groupes as $id => $groupe)
{
$nb_groupes_update += (int) $this->internalGroupe->update($id, $groupe['name'], $groupe['contacts_ids']);
}
if ($nb_groupes_update != count($groupes))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Certains groupes n\'ont pas pu êtres mis à jour.');
return header('Location: ' . \Router::url('Groupe', 'list'));
}
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('success', 'Tous les groupes ont été modifiés avec succès.');
return header('Location: ' . \Router::url('Groupe', 'list'));
}
/**
* Cette fonction retourne la liste des groupes sous forme JSON
*/
public function json_list()
{
header('Content-Type: application/json');
echo json_encode($this->internalGroupe->get_list());
}
}

107
controllers/publics/Received.php Executable file
View file

@ -0,0 +1,107 @@
<?php
namespace controllers\publics;
/**
* Page des receiveds
*/
class Received extends \Controller
{
/**
* Cette fonction est appelée avant toute les autres :
* Elle vérifie que l'utilisateur est bien connecté
* @return void;
*/
public function _before()
{
global $bdd;
$this->bdd = $bdd;
$this->internalReceived = new \controllers\internals\Received($this->bdd);
$this->internalContact = new \controllers\internals\Contact($this->bdd);
\controllers\internals\Tool::verify_connect();
}
/**
* Cette fonction retourne tous les receiveds, sous forme d'un tableau permettant l'administration de ces receiveds
*/
public function list ($page = 0)
{
$page = (int) $page;
$limit = 25;
$receiveds = $this->internalReceived->get_list($limit, $page);
foreach ($receiveds as $key => $received)
{
if (!$contact = $this->internalContact->get_by_number($received['origin']))
{
continue;
}
$receiveds[$key]['send_by'] = $contact['name'] . ' (' . $received['origin'] . ')';
}
$this->render('received/list', ['receiveds' => $receiveds, 'page' => $page, 'limit' => $limit, 'nb_results' => count($receiveds)]);
}
/**
* Cette fonction retourne tous les SMS reçus aujourd'hui pour la popup
* @return json : Un tableau des SMS reçus
*/
public function popup ()
{
$now = new \DateTime();
$receiveds = $this->internalReceived->get_since_by_date($now->format('Y-m-d'));
foreach ($receiveds as $key => $received)
{
if (!$contact = $this->internalContact->get_by_number($received['origin']))
{
continue;
}
$receiveds[$key]['origin'] = $contact['name'] . ' (' . $received['origin'] . ')';
}
$nb_received = count($receiveds);
if (!isset($_SESSION['popup_nb_receiveds']) || $_SESSION['popup_nb_receiveds'] > $nb_receiveds)
{
$_SESSION['popup_nb_receiveds'] = $nb_received;
}
$newly_receiveds = array_slice($receiveds, $_SESSION['popup_nb_receiveds']);
$_SESSION['popup_nb_receiveds'] = $nb_receiveds;
echo json_encode($newly_receiveds);
return true;
}
/**
* Cette fonction va supprimer une liste de receiveds
* @param array int $_GET['ids'] : Les id des receivedes à supprimer
* @return boolean;
*/
public function delete ($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('Received', 'list'));
}
if (!\controllers\internals\Tool::is_admin())
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Vous devez être administrateur pour effectuer cette action.');
return header('Location: ' . \Router::url('Received', 'list'));
}
$ids = $_GET['ids'] ?? [];
foreach ($ids as $id)
{
$this->internalReceived->delete($id);
}
return header('Location: ' . \Router::url('Received', 'list'));
}
}

146
controllers/publics/SMSAPI.php Executable file
View file

@ -0,0 +1,146 @@
<?php
namespace controllers\publics;
/**
* Page des smsapis
*/
class SMSAPI extends \Controller
{
//On défini les constantes qui servent pour les retours d'API
const API_ERROR_NO = 0;
const API_ERROR_BAD_ID = 1;
const API_ERROR_CREATION_FAILED = 2;
const API_ERROR_MISSING_FIELD = 3;
/**
* Cette fonction est appelée avant toute les autres :
* Elle vérifie que l'utilisateur est bien connecté
* @return void;
*/
public function _before()
{
global $bdd;
global $model;
$this->bdd = $bdd;
$this->model = $model;
$this->internal_user = new \controllers\internals\User($this->bdd);
$this->internalContact = new \controllers\internals\Contact($this->bdd);
\controllers\internals\Tool::verify_connect();
}
/**
* Cette fonction permet d'envoyer un SMS, en passant simplement des arguments à l'URL (ou pas $_GET)
* @param string text = Le contenu du SMS
* @param mixed numbers = Les numéros auxquels envoyer les SMS. Soit un seul numéro, et il s'agit d'un string. Soit plusieurs numéros, et il s'agit d'un tableau
* @param mixed contacts = Les noms des contacts auxquels envoyer les SMS. Soit un seul et il s'agit d'un string. Soit plusieurs, et il s'agit d'un tableau
* @param mixed groupes = Les noms des groupes auxquels envoyer les SMS. Soit un seul et il s'agit d'un string. Soit plusieurs, et il s'agit d'un tableau
* @param optionnal string date = La date à laquelle doit être envoyé le SMS. Au format 'Y-m-d H:i'. Si non fourni, le SMS sera envoyé dans 2 minutes
*/
public function api ()
{
//On récupère l'email et le password
$email = isset($_GET['email']) ? $_GET['email'] : NULL;
$email = isset($_POST['email']) ? $_POST['email'] : $email;
$password = isset($_GET['password']) ? $_GET['password'] : NULL;
$password = isset($_POST['password']) ? $_POST['password'] : $password;
//Si les identifiants sont incorrect on retourne une erreur
$user = $internal_user->check_credentials($email, $password);
if (!$user)
{
echo json_encode(array(
'error' => self::API_ERROR_BAD_ID,
));
return true;
}
//On map les variables $_GET
$get_numbers = isset($_GET['numbers']) ? $_GET['numbers'] : array();
$get_contacts = isset($_GET['contacts']) ? $_GET['contacts'] : array();
$get_groupes = isset($_GET['groupes']) ? $_GET['groupes'] : array();
//On map les variables POST
$post_numbers = isset($_POST['numbers']) ? $_POST['numbers'] : array();
$post_contacts = isset($_POST['contacts']) ? $_POST['contacts'] : array();
$post_groupes = isset($_POST['groupes']) ? $_POST['groupes'] : array();
//On map le texte et la date à part car c'est les seuls arguments qui ne sera jamais un tableau
$text = isset($_GET['text']) ? $_GET['text'] : NULL;
$text = isset($_POST['text']) ? $_POST['text'] : $text;
$date = isset($_GET['date']) ? $_GET['date'] : NULL;
$date = isset($_POST['date']) ? $_POST['date'] : $date;
//On passe tous les paramètres GET en tableau
$get_numbers = is_array($get_numbers) ? $get_numbers : ($get_numbers ? array($get_numbers) : array());
$get_contacts = is_array($get_contacts) ? $get_contacts : array($get_contacts);
$get_groupes = is_array($get_groupes) ? $get_groupes : array($get_groupes);
//On passe tous les paramètres POST en tableau
$post_numbers = is_array($post_numbers) ? $post_numbers : array($post_numbers);
$post_contacts = is_array($post_contacts) ? $post_contacts : array($post_contacts);
$post_groupes = is_array($post_groupes) ? $post_groupes : array($post_groupes);
//On merge les données reçus en GET, et celles en POST
$numbers = array_merge($get_numbers, $post_numbers);
$contacts = array_merge($get_contacts, $post_contacts);
$groupes = array_merge($get_groupes, $post_groupes);
//Pour chaque contact, on récupère l'id du contact
foreach ($contacts as $key => $contact)
{
if (!$contact = $internalContact->get_by_name($contact))
{
unset($contacts[$key]);
continue;
}
$contacts[$key] = $contact['id'];
}
//Pour chaque groupe, on récupère l'id du groupe
foreach ($groupes as $key => $name)
{
if (!$groupe = $internalContact->get_by_name($groupe))
{
unset($groupes[$key]);
continue;
}
$groupes[$key] = $groupe['id'];
}
//Si la date n'est pas définie, on la met à la date du jour
if (!$date)
{
$now = new \DateTime();
$date = $now->format('Y-m-d H:i');
}
//Si il manque des champs essentiels, on leve une erreur
if (!$text || (!$numbers && !$contacts && !$groupes))
{
echo json_encode(array(
'error' => self::API_ERROR_MISSING_FIELD,
));
return false;
}
//On assigne les variable POST (après avoir vidé $_POST) en prévision de la création du SMS
if (!$this->internalScheduled->create(['at' => $date, 'content' => $text], $numbers, $contacts, $groupes))
{
echo json_encode(array(
'error' => self::API_ERROR_CREATION_FAILED,
));
return false;
}
echo json_encode(array(
'error' => self::API_ERROR_NO,
));
return true;
}
}

62
controllers/publics/SMSStop.php Executable file
View file

@ -0,0 +1,62 @@
<?php
namespace controllers\publics;
/**
* Page des smsstops
*/
class SMSStop extends \Controller
{
/**
* Cette fonction est appelée avant toute les autres :
* Elle vérifie que l'utilisateur est bien connecté
* @return void;
*/
public function _before()
{
global $bdd;
$this->bdd = $bdd;
$this->internalSMSStop = new \controllers\internals\SMSStop($this->bdd);
\controllers\internals\Tool::verify_connect();
}
/**
* Cette fonction retourne tous les smsstops, sous forme d'un tableau permettant l'administration de ces smsstops
*/
public function list ($page = 0)
{
$page = (int) $page;
$limit = 25;
$smsstops = $this->internalSMSStop->get_list($limit, $page);
$this->render('smsstop/list', ['page' => $page, 'smsstops' => $smsstops, 'limit' => $limit, 'nb_results' => count($smsstops)]);
}
/**
* Cette fonction va supprimer une liste de smsstops
* @param array int $_GET['ids'] : Les id des smsstopes à supprimer
* @return boolean;
*/
public function delete($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('SMSStop', 'list'));
}
if (!\controllers\internals\Tool::is_admin())
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Vous devez être administrateur pour pouvoir supprimer un "STOP SMS" !');
return header('Location: ' . \Router::url('SMSStop', 'list'));
}
$ids = $_GET['ids'] ?? [];
foreach ($ids as $id)
{
$this->internalSMSStop->delete($id);
}
return header('Location: ' . \Router::url('SMSStop', 'list'));
}
}

271
controllers/publics/Scheduled.php Executable file
View file

@ -0,0 +1,271 @@
<?php
namespace controllers\publics;
/**
* Page des scheduleds
*/
class Scheduled extends \Controller
{
/**
* Cette fonction est appelée avant toute les autres :
* Elle vérifie que l'utilisateur est bien connecté
* @return void;
*/
public function _before()
{
global $bdd;
$this->bdd = $bdd;
$this->internalScheduled = new \controllers\internals\Scheduled($this->bdd);
$this->internalEvent = new \controllers\internals\Event($this->bdd);
\controllers\internals\Tool::verify_connect();
}
/**
* Cette fonction retourne tous les scheduleds, sous forme d'un tableau permettant l'administration de ces scheduleds
*/
public function list ($page = 0)
{
$page = (int) $page;
$scheduleds = $this->internalScheduled->get_list(25, $page);
$this->render('scheduled/list', ['scheduleds' => $scheduleds]);
}
/**
* Cette fonction va supprimer une liste de scheduleds
* @param array int $_GET['ids'] : Les id des scheduledes à supprimer
* @return boolean;
*/
public function delete ($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('Scheduled', 'list'));
}
$ids = $_GET['ids'] ?? [];
foreach ($ids as $id)
{
$this->internalScheduled->delete($id);
}
return header('Location: ' . \Router::url('Scheduled', 'list'));
}
/**
* Cette fonction retourne la page d'ajout d'un scheduled
*/
public function add()
{
$now = new \DateTime();
$less_one_minute = new \DateInterval('PT1M');
$now->sub($less_one_minute);
$this->render('scheduled/add', [
'now' => $now->format('Y-m-d H:i'),
]);
}
/**
* Cette fonction retourne la page d'édition des scheduleds
* @param int... $ids : Les id des scheduledes à supprimer
*/
public function edit()
{
$ids = $_GET['ids'] ?? [];
$scheduleds = $this->internalScheduled->get_by_ids($ids);
//Pour chaque message on ajoute les numéros, les contacts & les groupes
foreach ($scheduleds as $key => $scheduled)
{
$scheduleds[$key]['numbers'] = [];
$scheduleds[$key]['contacts'] = [];
$scheduleds[$key]['groupes'] = [];
$numbers = $this->internalScheduled->get_numbers($scheduled['id']);
foreach ($numbers as $number)
{
$scheduleds[$key]['numbers'][] = $number['number'];
}
$contacts = $this->internalScheduled->get_contacts($scheduled['id']);
foreach ($contacts as $contact)
{
$scheduleds[$key]['contacts'][] = (int) $contact['id'];
}
$groupes = $this->internalScheduled->get_groupes($scheduled['id']);
foreach ($groupes as $groupe)
{
$scheduleds[$key]['groupes'][] = (int) $groupe['id'];
}
}
$this->render('scheduled/edit', array(
'scheduleds' => $scheduleds,
));
}
/**
* Cette fonction insert un nouveau scheduled
* @param $csrf : Le jeton CSRF
* @param string $_POST['name'] : Le nom du scheduled
* @param string $_POST['date'] : La date d'envoie du scheduled
* @param string $_POST['numbers'] : Les numeros de téléphone du scheduled
* @param string $_POST['contacts'] : Les contacts du scheduled
* @param string $_POST['groupes'] : Les groupes du scheduled
*/
public function create($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('Scheduled', 'add'));
}
$date = $_POST['date'] ?? false;
$content = $_POST['content'] ?? false;
$numbers = $_POST['numbers'] ?? [];
$contacts = $_POST['contacts'] ?? [];
$groupes = $_POST['groupes'] ?? [];
if (!$content)
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Vous ne pouvez pas créer un SMS sans message.');
return header('Location: ' . \Router::url('Scheduled', 'add'));
}
if (!\controllers\internals\Tool::validate_date($date, 'Y-m-d H:i:s') && !\controllers\internals\Tool::validate_date($date, 'Y-m-d H:i'))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Vous devez fournir une date valide.');
return header('Location: ' . \Router::url('Scheduled', 'add'));
}
foreach ($numbers as $key => $number)
{
$number = \controllers\internals\Tool::parse_phone($number);
if (!$number)
{
unset($numbers[$key]);
continue;
}
$numbers[$key] = $number;
}
if (!$numbers && !$contacts && !$groupes)
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Vous devez renseigner au moins un destinataire pour le SMS.');
return header('Location: ' . \Router::url('Scheduled', 'add'));
}
$scheduled = [
'at' => $date,
'content' => $content,
'flash' => false,
'progress' => false,
];
if (!$scheduled_id = $this->internalScheduled->create($scheduled, $numbers, $contacts, $groupes))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Impossible de créer le SMS.');
return header('Location: ' . \Router::url('Scheduled', 'add'));
}
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('success', 'Le SMS a bien été créé pour le ' . $date . '.');
return header('Location: ' . \Router::url('Scheduled', 'list'));
}
/**
* Cette fonction met à jour une schedulede
* @param $csrf : Le jeton CSRF
* @param array $_POST['scheduleds'] : Un tableau des scheduledes avec leur nouvelle valeurs + les numbers, contacts et groupes liées
* @return boolean;
*/
public function update($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('Scheduled', 'list'));
}
$scheduleds = $_POST['scheduleds'] ?? [];
$all_update_ok = true;
foreach ($scheduleds as $id_scheduled => $scheduled)
{
$date = $scheduled['date'] ?? false;
$content = $scheduled['content'] ?? false;
$numbers = $scheduled['numbers'] ?? [];
$contacts = $scheduled['contacts'] ?? [];
$groupes = $scheduled['groupes'] ?? [];
if (!$content)
{
$all_update_ok = false;
continue;
}
if (!\controllers\internals\Tool::validate_date($date, 'Y-m-d H:i:s') && !\controllers\internals\Tool::validate_date($date, 'Y-m-d H:i'))
{
$all_update_ok = false;
continue;
}
foreach ($numbers as $key => $number)
{
$number = \controllers\internals\Tool::parse_phone($number);
if (!$number)
{
unset($numbers[$key]);
continue;
}
$numbers[$key] = $number;
}
if (!$numbers && !$contacts && !$groupes)
{
$all_update_ok = false;
continue;
}
$scheduled = [
'scheduled' => [
'id' => $id_scheduled,
'at' => $date,
'content' => $content,
'flash' => false,
'progress' => false,
],
'numbers' => $numbers,
'contacts_ids' => $contacts,
'groupes_ids' => $groupes,
];
if (!$this->internalScheduled->update([$scheduled]))
{
$all_update_ok = false;
continue;
}
}
if (!$all_update_ok)
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Certains SMS n\'ont pas pu êtres mis à jour.');
return header('Location: ' . \Router::url('Scheduled', 'list'));
}
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('success', 'Tous les SMS ont été mis à jour.');
return header('Location: ' . \Router::url('Scheduled', 'list'));
}
}

55
controllers/publics/Sended.php Executable file
View file

@ -0,0 +1,55 @@
<?php
namespace controllers\publics;
/**
* Page des sendeds
*/
class Sended extends \Controller
{
/**
* Cette fonction est appelée avant toute les autres :
* Elle vérifie que l'utilisateur est bien connecté
* @return void;
*/
public function _before()
{
global $bdd;
$this->bdd = $bdd;
$this->internalSended = new \controllers\internals\Sended($this->bdd);
\controllers\internals\Tool::verify_connect();
}
/**
* Cette fonction retourne tous les sendeds, sous forme d'un tableau permettant l'administration de ces sendeds
*/
public function list ($page = 0)
{
$page = (int) $page;
$limit = 25;
$sendeds = $this->internalSended->get_list($limit, $page);
$this->render('sended/list', ['sendeds' => $sendeds, 'page' => $page, 'limit' => $limit, 'nb_results' => count($sendeds)]);
}
/**
* Cette fonction va supprimer une liste de sendeds
* @param array int $_GET['ids'] : Les id des sendedes à supprimer
* @return boolean;
*/
public function delete($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('Sended', 'list'));
}
$ids = $_GET['ids'] ?? [];
foreach ($ids as $id)
{
$this->internalSended->delete($id);
}
return header('Location: ' . \Router::url('Sended', 'list'));
}
}

67
controllers/publics/Setting.php Executable file
View file

@ -0,0 +1,67 @@
<?php
namespace controllers\publics;
/**
* Page des settings
*/
class Setting extends \Controller
{
private $internal_setting;
public function __construct ()
{
$bdd = Model::connect(DATABASE_HOST, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD);
$this->internal_setting = new \controllers\internals\Setting($bdd);
\controllers\internals\Tool::verify_connect();
}
/**
* Return all settings to administrate them
*/
public function show ()
{
return $this->render('setting/show');
}
/**
* Update a setting value identified by his name
* @param string $setting_name : Name of the setting to modify
* @param $csrf : CSRF token
* @param string $_POST['setting_value'] : Setting's new value
* @return boolean;
*/
public function update (string $setting_name, string $csrf)
{
if (!$this->verifyCSRF($csrf))
{
\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('Setting', 'show'));
}
if (!\controllers\internals\Tool::is_admin())
{
\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Vous devez être administrateur pour pouvoir modifier un réglage.');
return header('Location: ' . \Router::url('Setting', 'show'));
}
$setting_value = $_POST['setting_value'] ?? false;
if ($setting_value === false)
{
\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Vous devez renseigner une valeure pour le réglage.');
return header('Location: ' . \Router::url('Setting', 'show'));
}
$update_setting_result = $this->internal_setting->update($setting_name, $setting_value);
if ($update_setting_result === false)
{
\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Impossible de mettre à jour ce réglage.');
return header('Location: ' . \Router::url('Setting', 'show'));
}
\DescartesSessionMessages\internals\DescartesSessionMessages::push('success', 'Le réglage a bien été mis à jour.');
return header('Location: ' . \Router::url('Setting', 'show'));
}
}

117
controllers/publics/User.php Executable file
View file

@ -0,0 +1,117 @@
<?php
namespace controllers\publics;
/**
* Page des users
*/
class User extends \Controller
{
/**
* Cette fonction est appelée avant toute les autres :
* Elle vérifie que l'utilisateur est bien connecté
* @return void;
*/
public function _before()
{
$bdd = Model::connect(DATABASE_HOST, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD);
$this->internal_user = new \controllers\internals\User($bdd);
\controllers\internals\Tool::verify_connect();
}
/**
* Cette fonction retourne tous les users, sous forme d'un tableau permettant l'administration de ces users
*/
public function list ($page = 0)
{
$page = (int) $page;
$users = $this->internal_user->list(25, $page);
$this->render('user/list', ['users' => $users]);
}
/**
* Cette fonction va supprimer une liste de users
* @param array int $_GET['ids'] : Les id des useres à supprimer
* @return boolean;
*/
public function delete ($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('User', 'list'));
}
if (!\controllers\internals\Tool::is_admin())
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Vous devez être administrateur pour supprimer un utilisateur !');
return header('Location: ' . \Router::url('User', 'list'));
}
$ids = $_GET['ids'] ?? [];
foreach ($ids as $id)
{
$this->internal_user->delete($id);
}
return header('Location: ' . \Router::url('User', 'list'));
}
/**
* Cette fonction retourne la page d'ajout d'un user
*/
public function add()
{
return $this->render('user/add');
}
/**
* Cette fonction insert un nouveau user
* @param $csrf : Le jeton CSRF
* @param string $_POST['email'] : L'email de l'utilisateur
* @param string $_POST['email_confirm'] : Verif de l'email de l'utilisateur
* @param optional string $_POST['password'] : Le mot de passe de l'utilisateur (si vide, généré automatiquement)
* @param optional string $_POST['password_confirm'] : Confirmation du mot de passe de l'utilisateur
* @param optional boolean $_POST['admin'] : Si vrai, l'utilisateur est admin, si vide non
*/
public function create($csrf)
{
if (!$this->verifyCSRF($csrf))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Jeton CSRF invalid !');
return header('Location: ' . \Router::url('User', 'add'));
}
$email = $_POST['email'] ?? false;
$password = $_POST['password'] ?? \controllers\internals\Tool::generate_password(rand(6,12));
$admin = $_POST['admin'] ?? false;
if (!$email)
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Vous devez au moins fournir une adresse e-mail pour l\'utilisateur.');
return header('Location: ' . \Router::url('User', 'add'));
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL))
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'L\'adresse e-mail n\'est pas valide.');
return header('Location: ' . \Router::url('User', 'add'));
}
$email_send = \controllers\internals\Tool::send_email($email, EMAIL_CREATE_USER, ['email' => $email, 'password' => $password]);
if (!$email_send)
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Impossible d\'envoyer l\'e-mail à l\'utilisateur, le compte n\'a donc pas été créé.');
return header('Location: ' . \Router::url('User', 'add'));
}
$user_id = $this->internal_user->create($email, $password, $admin);
if (!$user_id)
{
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('danger', 'Impossible de créer ce user.');
return header('Location: ' . \Router::url('User', 'add'));
}
\modules\DescartesSessionMessages\internals\DescartesSessionMessages::push('success', 'L\'utilisateur a bien été créé.');
return header('Location: ' . \Router::url('User', 'list'));
}
}