Merge remote-tracking branch 'RaspbianFrance/master'

This commit is contained in:
memento 2015-09-21 11:48:14 +02:00
commit 918aa990bc
59 changed files with 2265 additions and 1487 deletions

2
.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
#On force les retours UNIX
text eol=lf

0
README.md Normal file → Executable file
View file

View file

@ -15,26 +15,17 @@
}
/**
* Cette fonction est alias de showAll()
* Cette fonction retourne toutes les commandes, sous forme d'un tableau permettant l'administration de ces commandess
*/
public function byDefault()
{
$this->showAll();
}
/**
* Cette fonction retourne toutes les commandes, sous forme d'un tableau permettant l'administration de ces commandess
* @return void;
*/
public function showAll()
{
//Creation de l'object de base de données
global $db;
//Recupération des commandes
$commands = $db->getAll('commands');
$commands = $db->getFromTableWhere('commands');
$this->render('commands', array(
$this->render('commands/default', array(
'commands' => $commands,
));
@ -42,24 +33,24 @@
/**
* Cette fonction va supprimer une liste de commands
* @return void;
* @param int... $ids : Les id des commandes à supprimer
* @return boolean;
*/
public function delete()
public function delete($csrf, ...$ids)
{
if (!internalTools::verifyCSRF())
if (!internalTools::verifyCSRF($csrf))
{
header('Location: ' . $this->generateUrl('commands', 'showAll', array(
'errormessage' => 'Jeton CSRF invalide !'
)));
return true;
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('commands'));
return false;
}
//Create de l'object de base de données
global $db;
$commands_ids = $_GET;
$db->deleteCommandsIn($commands_ids);
$db->deleteCommandsIn($ids);
header('Location: ' . $this->generateUrl('commands'));
return true;
}
/**
@ -67,91 +58,87 @@
*/
public function add()
{
$this->render('addCommand');
$this->render('commands/add');
}
/**
* Cette fonction retourne la page d'édition des contacts
* Cette fonction retourne la page d'édition des commandes
* @param int... $ids : Les id des commandes à editer
*/
public function edit()
public function edit(...$ids)
{
global $db;
$commands = $db->getCommandsIn($_GET);
$this->render('editCommands', array(
$commands = $db->getCommandsIn($ids);
$this->render('commands/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()
public function create($csrf)
{
if (!internalTools::verifyCSRF())
if (!internalTools::verifyCSRF($csrf))
{
header('Location: ' . $this->generateUrl('commands', 'showAll', array(
'errormessage' => 'Jeton CSRF invalide !'
)));
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('commands'));
return true;
}
global $db;
$nom = $_POST['name'];
$script = $_POST['script'];
$admin = (isset($_POST['admin']) ? $_POST['admin'] : false);
if ($db->createCommand($nom, $script, $admin))
{
$db->createEvent('COMMAND_ADD', 'Ajout commande : ' . $nom . ' => ' . $script);
header('Location: ' . $this->generateUrl('commands', 'showAll', array(
'successmessage' => 'La commande a bien été créée.'
)));
return true;
if (!$db->insertIntoTable('commands', ['name' => $nom, 'script' => $script, 'admin' => $admin]))
{
$_SESSION['errormessage'] = 'Impossible créer cette commande.';
header('Location: ' . $this->generateUrl('commands', 'add'));
return false;
}
header('Location: ' . $this->generateUrl('commands', 'add', array(
'errormessage' => 'Impossible créer cette commande.'
)));
return false;
$db->insertIntoTable('events', ['type' => 'COMMAND_ADD', 'text' => 'Ajout commande : ' . $nom . ' => ' . $script]);
$_SESSION['successmessage'] = 'La commande a bien été créée.';
header('Location: ' . $this->generateUrl('commands'));
return true;
}
/**
* 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()
public function update($csrf)
{
if (!internalTools::verifyCSRF())
if (!internalTools::verifyCSRF($csrf))
{
header('Location: ' . $this->generateUrl('commands', 'showAll', array(
'errormessage' => 'Jeton CSRF invalide !'
)));
return true;
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('commands'));
return false;
}
global $db;
$errors = array(); //On initialise le tableau qui contiendra les erreurs rencontrés
//Pour chaque commande reçu, on boucle en récupérant son id (la clef), et la commande elle-même (la value)
foreach ($_POST['commands'] as $id => $command)
{
$db->updateCommand($id, $command['name'], $command['script'], $command['admin']);
$db->updateTableWhere('commands', $command, ['id' => $id]);
}
$message = 'Toutes les commandes ont été modifiées avec succès.';
header('Location: ' . $this->generateUrl('commands', 'showAll', array(
'successmessage' => $message,
)));
}
public function flagMeThat()
{
var_dump(internalTools::parseForFlag('[COMMAND:chauffer 35][PASSWORD:mon password qui rox][LOGin:monlogin]'));
$_SESSION['successmessage'] = 'Toutes les commandes ont été modifiées avec succès.';
header('Location: ' . $this->generateUrl('commands'));
}
}

View file

@ -5,22 +5,11 @@
class connect extends Controller
{
/**
* Cette fonction est alias de login()
* Cette fonction retourne la fenetre de connexion
*/
public function byDefault()
{
$this->login();
}
/**
* Cette fonction retourne la fenetre de connexion
* @return void;
*/
public function login()
{
//Creation de l'object de base de données
global $db;
$this->render('login');
$this->render('connect/login');
}
/**
@ -29,10 +18,6 @@
*/
public function forgetPassword()
{
//Creation de l'object de base de données
global $db;
$this->render('forgetPassword');
}
@ -48,34 +33,34 @@
//Creation de l'object de base de données
global $db;
$email = $_POST['mail'];
$password = $_POST['password'];
if ($user = $db->getUserFromEmail($email))
if (!$users = $db->getFromTableWhere('users', ['email' => $email]))
{
if (sha1($password) == $user['password'])
$_SESSION['errormessage'] = 'Identifiants incorrects.';
header('Location: ' . $this->generateUrl('connect', 'login'));
return false;
}
$user = $users[0];
if (sha1($password) != $user['password'])
{
$_SESSION['errormessage'] = 'Cet e-mail n\'existe pas.';
header('Location: ' . $this->generateUrl('connect', 'login'));
return false;
}
$_SESSION['connect'] = true;
$_SESSION['admin'] = $user['admin'];
$_SESSION['email'] = $user['email'];
$_SESSION['transfer'] = $user['transfer'];
$_SESSION['csrf'] = str_shuffle(uniqid().uniqid());
header('Location: ' . $this->generateUrl(''));
return true;
}
header('Location: ' . $this->generateUrl('connect', 'login', array(
'errormessage' => 'Identifiants incorrects.'
)));
return false;
}
header('Location: ' . $this->generateUrl('connect', 'login', array(
'errormessage' => 'Cet e-mail n\'existe pas.'
)));
return false;
}
/**
* Cette fonction change le mot de passe d'un utilisateur à partir de son email. Un mot de passe aléatoire et généré, et lui est envoyé
* @param string $_POST['mail'] : L'email de l'utilisateur cible
@ -86,38 +71,40 @@
//Creation de l'object de base de données
global $db;
$email = $_POST['mail'];
if ($user = $db->getUserFromEmail($email))
if (!$users = $db->getFromTableWhere('users', ['email' => $email]))
{
$_SESSION['errormessage'] = 'Cet e-mail n\'existe pas.';
header('Location: ' . $this->generateUrl('connect', 'forgetPassword'));
return false;
}
$password = internalTools::generatePassword(rand(8,12));
$message = "Vous avez demandé un nouveau mot de passe pour le site " . HTTP_PWD . ".\n";
$message = "Votre nouveau mot de passe a été généré aléatoirement, et n'est connu que de vous. Le voici : \n";
$message .= "Nouveau mot de passe : " . $password . "\n\n";
$message .= "-------------------------------------\n";
$message .= "Pour plus d'informations sur le système RaspiSMS, rendez-vous sur le site http://raspbian-france.fr\n";
if (mail($email, 'RaspiSMS - Recuperation de mot de passe', $message))
if (!mail($email, 'RaspiSMS - Recuperation de mot de passe', $message))
{
$new_password = sha1($password);
if ($db->updateUser($user['id'], $user['email'], $new_password, $user['admin']))
{
header('Location: ' . $this->generateUrl('connect', 'login', array(
'successmessage' => 'Un nouveau mot de passe vous a été envoyé par mail.'
)));
return true;
}
$_SESSION['errormessage'] = 'Impossible d\'envoyer les nouveaux identifiants.';
header('Location: ' . $this->generateUrl('connect', 'forgetPassword'));
return false;
}
header('Location: ' . $this->generateUrl('connect', 'forgetPassword', array(
'errormessage' => 'Impossible d\'envoyer les nouveaux identifiants.'
)));
$new_password = sha1($password);
if (!$db->updateTableWhere('users', ['email' => $user['email'], 'password' => $new_password, 'admin' => $user['admin']], ['id' => $user['id']]))
{
$_SESSION['errormessage'] = 'Impossible de mettre à jour le mot de passe.';
header('Location: ' . $this->generateUrl('connect', 'login'));
return false;
}
header('Location: ' . $this->generateUrl('connect', 'forgetPassword', array(
'errormessage' => 'Cet e-mail n\'existe pas.'
)));
return false;
$_SESSION['successmessage'] = 'Un nouveau mot de passe vous a été envoyé par mail.';
header('Location: ' . $this->generateUrl('connect', 'login'));
return true;
}
/**

View file

@ -15,51 +15,43 @@
}
/**
* Cette fonction est alias de showAll()
* Cette fonction retourne tous les contacts, sous forme d'un tableau permettant l'administration de ces contacts
*/
public function byDefault()
{
$this->showAll();
}
/**
* Cette fonction retourne tous les contacts, sous forme d'un tableau permettant l'administration de ces contacts
* @return void;
*/
public function showAll()
{
//Creation de l'object de base de données
global $db;
//Recupération des nombres des 4 panneaux d'accueil
$contacts = $db->getAll('contacts');
$contacts = $db->getFromTableWhere('contacts');
$this->render('contacts', array(
$this->render('contacts/default', array(
'contacts' => $contacts,
));
}
/**
* Cette fonction supprimer une liste de contacts
* @return void;
* @param $csrf : Le jeton CSRF
* @param int... $ids : Les id des commandes à supprimer
* @return Boolean;
*/
public function delete()
public function delete($csrf, ...$ids)
{
//On vérifie que le jeton csrf est bon
if (!internalTools::verifyCSRF())
if (!internalTools::verifyCSRF($csrf))
{
header('Location: ' . $this->generateUrl('contacts', 'showAll', array(
'errormessage' => 'Jeton CSRF invalide !'
)));
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('contacts'));
return false;
}
//Create de l'object de base de données
global $db;
$contacts_ids = $_GET;
$db->deleteContactsIn($contacts_ids);
$db->deleteContactsIn($ids);
header('Location: ' . $this->generateUrl('contacts'));
return true;
}
/**
@ -67,110 +59,112 @@
*/
public function add()
{
$this->render('addContact');
$this->render('contacts/add');
}
/**
* Cette fonction retourne la page d'édition des contacts
* @param int... $ids : Les id des commandes à supprimer
*/
public function edit()
public function edit(...$ids)
{
global $db;
$contacts = $db->getContactsIn($_GET);
$this->render('editContacts', array(
$contacts = $db->getContactsIn($ids);
$this->render('contacts/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()
public function create($csrf)
{
//On vérifie que le jeton csrf est bon
if (!internalTools::verifyCSRF())
if (!internalTools::verifyCSRF($csrf))
{
header('Location: ' . $this->generateUrl('contacts', 'showAll', array(
'errormessage' => 'Jeton CSRF invalide !'
)));
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('contacts'));
return false;
}
global $db;
if (empty($_POST['name']) || empty($_POST['phone']))
{
$_SESSION['errormessage'] = 'Des champs sont manquants.';
header('Location: ' . $this->generateUrl('contacts', 'add'));
return false;
}
$nom = $_POST['name'];
$phone = $_POST['phone'];
if ($phone = internalTools::parsePhone($phone))
{
if ($db->createContact($nom, $phone))
{
$db->createEvent('CONTACT_ADD', 'Ajout contact : ' . $nom . ' (' . internalTools::phoneAddSpace($phone) . ')');
header('Location: ' . $this->generateUrl('contacts', 'showAll', array(
'successmessage' => 'Le contact a bien été créé.'
)));
return true;
if (!$phone = internalTools::parsePhone($phone))
{
$_SESSION['errormessage'] = 'Numéro de téléphone incorrect.';
header('Location: ' . $this->generateUrl('contacts', 'add'));
return false;
}
header('Location: ' . $this->generateUrl('contacts', 'add', array(
'errormessage' => 'Impossible créer ce contact.'
)));
return true;
if (!$db->insertIntoTable('contacts', ['name' => $nom, 'number' => $phone]))
{
$_SESSION['errormessage'] = 'Impossible créer ce contact.';
header('Location: ' . $this->generateUrl('contacts', 'add'));
return false;
}
header('Location: ' . $this->generateUrl('contacts', 'add', array(
'errormessage' => 'Numéro de téléphone incorrect.'
)));
$db->insertIntoTable('events', ['type' => 'CONTACT_ADD', 'text' => 'Ajout contact : ' . $nom . ' (' . internalTools::phoneAddSpace($phone) . ')']);
$_SESSION['successmessage'] = 'Le contact a bien été créé.';
header('Location: ' . $this->generateUrl('contacts'));
return true;
}
/**
* Cette fonction met à jour une liste de contacts
* @param $csrf : Le jeton CSRF
* @param array $_POST['contacts'] : Un tableau des contacts avec leur nouvelle valeurs
* @return boolean;
*/
public function update()
public function update($csrf)
{
//On vérifie que le jeton csrf est bon
if (!internalTools::verifyCSRF())
if (!internalTools::verifyCSRF($csrf))
{
header('Location: ' . $this->generateUrl('contacts', 'showAll', array(
'errormessage' => 'Jeton CSRF invalide !'
)));
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('contacts'));
}
global $db;
$errors = array(); //On initialise le tableau qui contiendra les erreurs rencontrés
//Pour chaque contact reçu, on boucle en récupérant son id (la clef), et le contact lui-même (la value)
foreach ($_POST['contacts'] as $id => $contact)
{
if ($number = internalTools::parsePhone($contact['phone']))
{
$db->updateContact($id, $contact['name'], $number);
}
else
if (!$number = internalTools::parsePhone($contact['phone']))
{
$errors[] = $contact['id'];
continue;
}
$db->updateTableWhere('contacts', ['name' => $contact['name'], 'number' => $number], ['id' => $id]);
}
//Si on a eu des erreurs
if (count($errors))
{
$message = 'Certains contacts n\'ont pas pu êtres mis à jour. Voici leurs identifiants : ' . implode(', ', $errors);
header('Location: ' . $this->generateUrl('contacts', 'showAll', array(
'errormessage' => $message,
)));
}
else
{
$message = 'Tous les contacts ont été modifiés avec succès.';
header('Location: ' . $this->generateUrl('contacts', 'showAll', array(
'successmessage' => $message,
)));
$_SESSION['errormessage'] = 'Certains contacts n\'ont pas pu êtres mis à jour. Voici leurs identifiants : ' . implode(', ', $errors);
return header('Location: ' . $this->generateUrl('contacts'));
}
$_SESSION['successmessage'] = 'Tous les contacts ont été modifiés avec succès.';
return header('Location: ' . $this->generateUrl('contacts'));
}
/**
@ -180,6 +174,6 @@
{
global $db;
echo json_encode($db->getAll('contacts'));
echo json_encode($db->getFromTableWhere('contacts'));
}
}

View file

@ -15,25 +15,19 @@
}
/**
* Cette fonction retourne l'index temporaire du site
* Cette fonction est un alias de show
* @return void;
*/
public function byDefault()
{
$this->show();
}
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 = $db->countContacts();
$nb_groups = $db->countGroups();
$nb_scheduleds = $db->countScheduleds();
$nb_commands = $db->countCommands();
$nb_contacts = $db->countTable('contacts');;
$nb_groups = $db->countTable('groups');
$nb_scheduleds = $db->countTable('scheduleds');
$nb_commands = $db->countTable('commands');
//Création de la date d'il y a une semaine
$now = new DateTime();
@ -42,9 +36,9 @@
$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 = $db->getAll('sendeds', 'at', true, 10);
$receiveds = $db->getAll('receiveds', 'at', true, 10);
$events = $db->getAll('events', 'at', true, 10);
$sendeds = $db->getFromTableWhere('sendeds', [], 'at', true, 10);
$receiveds = $db->getFromTableWhere('receiveds', [], 'at', true, 10);
$events = $db->getFromTableWhere('events', [], 'at', true, 10);
//Récupération du nombre de SMS envoyés et reçus depuis les 7 derniers jours
$nb_sendeds = $db->getNbSendedsSinceGroupDay($formated_date);
@ -98,7 +92,7 @@
$array_area_chart = array_values($array_area_chart);
$this->render('dashboard', array(
$this->render('dashboard/default', array(
'nb_contacts' => $nb_contacts,
'nb_groups' => $nb_groups,
'nb_scheduleds' => $nb_scheduleds,

235
controllers/discussions.php Executable file
View file

@ -0,0 +1,235 @@
<?php
/**
* Page des discussions
*/
class discussions 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()
{
internalTools::verifyConnect();
}
/**
* Cette fonction retourne toutes les discussions, sous forme d'un tableau permettant l'administration de ces contacts
*/
public function byDefault()
{
//Creation de l'object de base de données
global $db;
//Recupération des nombres des 4 panneaux d'accueil
$discussions = $db->getDiscussions();
foreach ($discussions as $key => $discussion)
{
if (!$contacts = $db->getFromTableWhere('contacts', ['number' => $discussion['number']]))
{
continue;
}
$discussions[$key]['contact'] = $contacts[0]['name'];
}
$this->render('discussions/default', 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)
{
global $db;
$contact = '';
if ($contacts = $db->getFromTableWhere('contacts', ['number' => $number]))
{
$contact = $contacts[0]['name'];
}
$this->render('discussions/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 $transactionId : Le numéro unique de la transaction ajax (sert à vérifier si la requete doit être prise en compte)
*/
function getmessages($number, $transactionId)
{
global $db;
$now = new DateTime();
$now = $now->format('Y-m-d H:i:s');
$sendeds = $db->getFromTableWhere('sendeds', ['target' => $number], 'at');
$receiveds = $db->getFromTableWhere('receiveds', ['send_by' => $number], 'at');
$scheduleds = $db->getScheduledsBeforeDateForNumber($now, $number);
$messages = [];
foreach ($sendeds as $sended)
{
$messages[] = array(
'date' => htmlspecialchars($sended['at']),
'text' => htmlspecialchars($sended['content']),
'type' => 'sended',
);
}
foreach ($receiveds as $received)
{
$messages[] = array(
'date' => htmlspecialchars($received['at']),
'text' => htmlspecialchars($received['content']),
'type' => 'received',
);
}
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(['transactionId' => $transactionId, '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)
{
global $db;
$return = ['success' => true, 'message' => ''];
//On vérifie que le jeton csrf est bon
if (!internalTools::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');
$_POST['date'] = $now;
$scheduleds = new scheduleds();
if (!$scheduleds->create('', true, true))
{
$return['success'] = false;
$return['message'] = 'Impossible de créer le SMS';
echo json_encode($return);
return false;
}
$return['id'] = $_SESSION['discussion_wait_progress'][count($_SESSION['discussion_wait_progress']) - 1];
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 ()
{
global $db;
$_SESSION['discussion_wait_progress'] = isset($_SESSION['discussion_wait_progress']) ? $_SESSION['discussion_wait_progress'] : [];
$scheduleds = $db->getScheduledsIn($_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)
{
$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)
{
global $db;
$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 = $db->getReceivedsSinceForNumberOrderByDate($_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);
}
}

View file

@ -24,23 +24,22 @@
/**
* Cette fonction retourne tous les événements, sous forme d'un tableau permettant l'administration de ces événements
* @param int $page : La page à consulter. Par défaut 0
* @return void;
*/
public function showAll()
public function showAll($page = 0)
{
//Creation de l'object de base de données
global $db;
$page = (int)(isset($_GET['page']) ? $_GET['page'] : 0);
$page = (int)($page < 0 ? $page = 0 : $page);
$limit = 25;
$offset = $limit * $page;
//Récupération des évènements triés par date, du plus récent au plus ancien, par paquets de $limit, en ignorant les $offset premiers
$events = $db->getAll('events', 'at', true, $limit, $offset);
$events = $db->getFromTableWhere('events', [], 'at', true, $limit, $offset);
$this->render('events', array(
$this->render('events/default', array(
'events' => $events,
'page' => $page,
'limit' => $limit,

View file

@ -15,51 +15,41 @@
}
/**
* Cette fonction est alias de showAll()
* Cette fonction retourne tous les groupes, sous forme d'un tableau permettant l'administration de ces groupes
*/
public function byDefault()
{
$this->showAll();
}
/**
* Cette fonction retourne tous les groupes, sous forme d'un tableau permettant l'administration de ces groupes
* @return void;
*/
public function showAll()
{
//Creation de l'object de base de données
global $db;
$groups = $db->getGroupsWithContactsNb();
$this->render('groups', array(
$this->render('groups/default', array(
'groups' => $groups,
));
}
/**
* Cette fonction supprime une liste de groupes
* @param $csrf : Le jeton CSRF
* @param int... $ids : Les id des groups à supprimer
* @return void;
*/
public function delete()
public function delete($csrf, ...$ids)
{
//On vérifie que le jeton csrf est bon
if (!internalTools::verifyCSRF())
if (!internalTools::verifyCSRF($csrf))
{
header('Location: ' . $this->generateUrl('groups', 'showAll', array(
'errormessage' => 'Jeton CSRF invalide !'
)));
return true;
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('groups'));
return false;
}
//Create de l'object de base de données
global $db;
$groups_ids = $_GET;
$db->deleteGroupsIn($groups_ids);
$db->deleteGroupsIn($ids);
header('Location: ' . $this->generateUrl('groups'));
return true;
}
/**
@ -67,17 +57,18 @@
*/
public function add()
{
$this->render('addGroup');
$this->render('groups/add');
}
/**
* Cette fonction retourne la page d'édition des groupes
* @param int... $ids : Les id des groups à modifier
*/
public function edit()
public function edit(...$ids)
{
global $db;
$groups = $db->getGroupsIn($_GET);
$groups = $db->getGroupsIn($ids);
$blocks = array(); //On défini la variable qui correspondra à un bloc groupe et contacts
//Pour chaque groupe, on récupère les contacts liés
@ -86,82 +77,81 @@
$groups[$key]['contacts'] = $db->getContactsForGroup($group['id']);
}
$this->render('editGroups', array(
$this->render('groups/edit', array(
'groups' => $groups,
));
}
/**
* Cette fonction insert un nouveau contact
* @param $csrf : Le jeton CSRF
* @param string $_POST['name'] : Le nom du groupe
* @param array $_POST['contacts'] : Les id des contacts à mettre dans le du groupe
*/
public function create()
public function create($csrf)
{
//On vérifie que le jeton csrf est bon
if (!internalTools::verifyCSRF())
if (!internalTools::verifyCSRF($csrf))
{
header('Location: ' . $this->generateUrl('groups', 'showAll', array(
'errormessage' => 'Jeton CSRF invalide !'
)));
return true;
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('groups'));
return false;
}
global $db;
$nom = $_POST['name'];
if ($db->createGroup($nom))
if (!$db->insertIntoTable('groups', ['name' => $nom]))
{
$_SESSION['errormessage'] = 'Impossible de créer ce groupe.';
header('Location: ' . $this->generateUrl('groups'));
return false;
}
$id_group = $db->lastId();
$db->createEvent('GROUP_ADD', 'Ajout du groupe : ' . $nom);
$db->insertIntoTable('events', ['type' => 'GROUP_ADD', 'text' => 'Ajout du groupe : ' . $nom]);
foreach ($_POST['contacts'] as $id_contact)
{
$db->createGroups_contacts($id_group, $id_contact);
$db->insertIntoTable('groups_contacts', ['id_group' => $id_group, 'id_contact' => $id_contact]);
}
header('Location: ' . $this->generateUrl('groups', 'showAll', array(
'successmessage' => 'Le groupe a bien été créé.'
)));
$_SESSION['successmessage'] = 'Le groupe a bien été créé.';
header('Location: ' . $this->generateUrl('groups'));
return true;
}
header('Location: ' . $this->generateUrl('groups', 'showAll', array(
'errormessage' => 'Impossible de créer ce groupe.'
)));
}
/**
* Cette fonction met à jour une liste de groupes
* @param $csrf : Le jeton CSRF
* @param array $_POST['groups'] : Un tableau des groups avec leur nouvelle valeurs
* @return boolean;
*/
public function update()
public function update($csrf)
{
//On vérifie que le jeton csrf est bon
if (!internalTools::verifyCSRF())
if (!internalTools::verifyCSRF($csrf))
{
header('Location: ' . $this->generateUrl('groups', 'showAll', array(
'errormessage' => 'Jeton CSRF invalide !'
)));
return true;
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('groups'));
return false;
}
global $db;
//Pour chaque groupe reçu, on boucle en récupérant son id (la clef), et le contact le tableau du groupe (nom et liste des contacts)
foreach ($_POST['groups'] as $id_group => $group)
{
$db->updateGroup($id_group, $group['name']); //On met à jour le nom du groupe
$db->deleteGroups_contactsForGroup($id_group); //On supprime tous les contacts de ce groupe
$db->updateTableWhere('groups', $group, ['id' => $id_group]); //On met à jour le nom du groupe
$db->deleteFromTableWhere('groups_contacts', ['id_group' => $id_group]); //On supprime tous les contacts de ce groupe
foreach ($group['contacts'] as $id_contact) //Pour chaque contact on l'ajoute au groupe
{
$db->createGroups_contacts($id_group, $id_contact);
$db->insertIntoTable('groups_contacts', ['id_group' => $id_group, 'id_contact' => $id_contact]);
}
}
$message = 'Tous les groupes ont été modifiés avec succès.';
header('Location: ' . $this->generateUrl('groups', 'showAll', array(
'successmessage' => $message,
)));
$_SESSION['successmessage'] = 'Tous les groupes ont été modifiés avec succès.';
header('Location: ' . $this->generateUrl('groups'));
}
/**
@ -171,6 +161,6 @@
{
global $db;
echo json_encode($db->getAll('groups'));
echo json_encode($db->getFromTableWhere('groups'));
}
}

View file

@ -20,6 +20,11 @@
),
'optionals' => array(),
),
'sendTransfers' => array(
'description' => 'Cette commande permet d\'envoyer par mails les sms à transférés.',
'requireds' => [],
'optionals' => [],
),
);
$message = "Vous êtes ici dans l'aide de la console.\n";
@ -71,7 +76,8 @@
//On créé l'objet de base de données
global $db;
for ($i = 0; $i < 30; $i++)
{
$now = new DateTime();
$now = $now->format('Y-m-d H:i:s');
@ -134,23 +140,29 @@
$now = new DateTime();
$now = $now->format('Y-m-d H:i:s');
//On peut maintenant ajouter le SMS
$db->createSended($now, $number, $scheduled['content']);
if (!$db->insertIntoTable('sendeds', ['at' => $now, 'target' => $number, 'content' => $scheduled['content']]))
{
echo 'Impossible d\'inserer le sms pour le numero ' . $number . "\n";
}
$id_sended = $db->lastId();
//Commande qui envoie le SMS
$commande_send_sms = 'gammu-smsd-inject TEXT ' . escapeshellarg($number) . ' -len ' . mb_strlen($text_sms) . ' -text ' . $text_sms;
//Commande qui s'assure de passer le SMS dans ceux envoyés, et de lui donner le bon statut
//On va lier les deux commandes pour envoyer le SMS puis le passer en echec
//On va liée les deux commandes pour envoyer le SMS puis le passer en echec
$commande = '(' . $commande_send_sms . ') >/dev/null 2>/dev/null &';
exec($commande); //On execute la commande d'envoi d'un SMS
exec($commande); //On execute la commande d'envoie d'un SMS
}
}
echo "Tous les SMS sont en cours d'envoi.\n";
//Tous les SMS ont été envoyés.
$db->deleteScheduledsIn($ids_scheduleds);
//On dors 2 secondes
sleep(2);
}
}
/**
@ -161,6 +173,8 @@
//On créer l'objet de base de données
global $db;
for ($i = 0; $i < 30; $i++)
{
foreach (scandir(PWD_RECEIVEDS) as $dir)
{
//Si le fichier est un fichier système, on passe à l'itération suivante
@ -175,8 +189,9 @@
//On récupère le fichier, et on récupère la chaine jusqu'au premier ':' pour le numéro de téléphone source, et la fin pour le message
$content_file = file_get_contents(PWD_RECEIVEDS . $dir);
//Si on ne peut pas ouvrir le fichier, alors on quitte en logant une erreur
if (!$content_file)
//Si on peux pas ouvrir le fichier, on quitte en logant une erreur
if ($content_file == false)
{
$this->wlog('Unable to read file "' . $dir);
die(4);
@ -248,19 +263,25 @@
}
//On va supprimer le mot de passe du SMS pour pouvoir l'enregistrer sans danger
if (isset($flags['PASSWORD']))
{
$text = str_replace($flags['PASSWORD'], '*****', $text);
}
//On map les données et on créer le SMS reçu
$send_by = $number;
$content = $text;
$is_command = count($found_commands);
if (!$db->createReceived($date, $send_by, $content, $is_command))
if (!$db->insertIntoTable('receiveds', ['at' => $date, 'send_by' => $send_by, 'content' => $content, 'is_command' => $is_command]))
{
echo "Erreur lors de l'enregistrement du SMS\n";
$this->wlog('Unable to process the SMS in file "' . $dir);
die(7);
}
//On insert le SMS dans le tableau des sms à envoyer par mail
$db->insertIntoTable('transfers', ['id_received' => $db->lastId(), 'progress' => false]);
//Chaque commande sera executée.
foreach ($found_commands as $command_name => $command)
{
@ -268,5 +289,49 @@
exec($command);
}
}
//On attend 2 secondes
sleep(2);
}
}
/**
* Cette fonction permet d'envoyer par mail les sms à transférer
*/
public function sendTransfers ()
{
global $db;
$transfers = $db->getFromTableWhere('transfers', ['progress' => false]);
$ids_transfers = [];
$ids_receiveds = [];
foreach ($transfers as $transfer)
{
$ids_transfers[] = $transfer['id'];
$ids_receiveds[] = $transfer['id_received'];
}
$db->updateProgressTransfersIn($ids_transfers, true);
$receiveds = $db->getReceivedsIn($ids_receiveds);
$users = $db->getFromTableWhere('users', ['transfer' => true]);
foreach ($users as $user)
{
foreach ($receiveds as $received)
{
echo "Transfer d'un SMS du " . $received['send_by'] . " à l'email " . $user['email'];
$to = $user['email'];
$subject = '[RaspiSMS] - Transfert d\'un SMS du ' . $received['send_by'];
$message = "Le numéro " . $received['send_by'] . " vous a envoyé un SMS : \n" . $received['content'];
$ok = mail($to, $subject, $message);
echo " ... " . ($ok ? 'OK' : 'KO') . "\n";
}
}
$db->deleteTransfersIn($ids_transfers);
}
}

View file

@ -8,13 +8,24 @@
*/
public function head($title = '')
{
$title = (!empty($title)) ? $title . ' - RaspiSMS' : 'RaspiSMS';
$author = 'Ajani';
$title = (!empty($title)) ? $title . ' - ' . WEBSITE_TITLE : WEBSITE_TITLE;
$author = WEBSITE_AUTHOR;
$error_message = (isset($_GET['errormessage'])) ? $_GET['errormessage'] : '';
$success_message = (isset($_GET['successmessage'])) ? $_GET['successmessage'] : '';
$error_message = false;
$success_message = false;
if (isset($_SESSION['errormessage']))
{
$error_message = $_SESSION['errormessage'];
unset($_SESSION['errormessage']);
}
$this->render('head', array(
if (isset($_SESSION['successmessage']))
{
$success_message = $_SESSION['successmessage'];
unset($_SESSION['successmessage']);
}
$this->render('internalIncs/head', array(
'title' => $title,
'author' => $author,
'error_message' => $error_message,
@ -30,7 +41,7 @@
public function nav($page = '')
{
$email = isset($_SESSION['email']) ? $_SESSION['email'] : 'Mon compte';
$this->render('nav', array(
$this->render('internalIncs/nav', array(
'email' => $email,
'page' => $page,
));
@ -38,6 +49,14 @@
public function footer()
{
$this->render('footer');
$this->render('internalIncs/footer');
}
/**
* Cette fonction retourne une page js avec des constantes php sous forme js
*/
public function phptojs()
{
$this->render('internalIncs/phptojs');
}
}

View file

@ -8,8 +8,8 @@
*/
public static function parsePhone($number)
{
$number = preg_replace('#[^0-9+]#', '', $number);
if (preg_match('#^(0|\+33)[1-9][0-9]{8}$#', $number))
$number = preg_replace('#[^-0-9+]#', '', $number);
if (preg_match('#^(0|\+[1-9]{1,3}|\+1\-[0-9]{3})[1-9][0-9]{8}$#', $number))
{
return $number;
}

View file

@ -15,83 +15,110 @@
}
/**
* Cette fonction est alias de show()
* Cette fonction retourne la fenetre du profile
*/
public function byDefault()
{
$this->show();
}
/**
* Cette fonction retourne la fenetre du profile
* @return void;
*/
public function show()
{
//Creation de l'object de base de données
global $db;
$this->render('profile');
$this->render('profile/default');
}
/**
* Cette fonction change le mot de passe de l'utilisateur
* @param $csrf : Le jeton CSRF
* @param string $_POST['password'] : Le nouveau mot de passe de l'utilisateur
* @param string $_POST['verif_password'] : La vérification du nouveau mot de passe de l'utilisateur
* @return void;
*/
public function changePassword()
public function changePassword($csrf)
{
//On vérifie que le jeton csrf est bon
if (!internalTools::verifyCSRF())
if (!internalTools::verifyCSRF($csrf))
{
header('Location: ' . $this->generateUrl('profile', 'showAll', array(
'errormessage' => 'Jeton CSRF invalide !'
)));
return true;
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('profile'));
return false;
}
//Creation de l'object de base de données
global $db;
if (empty($_POST['password']) || empty($_POST['verif_password']) || $_POST['password'] != $_POST['verif_password'])
{
header('Location: ' . $this->generateUrl('profile', 'show', array(
'errormessage' => 'Les mots de passe ne correspondent pas.'
)));
$_SESSION['errormessage'] = 'Les mots de passe ne correspondent pas.';
header('Location: ' . $this->generateUrl('profile'));
return false;
}
$user = $db->getUserFromEmail($_SESSION['email']);
$user = $db->getFromTableWhere('users', ['email' => $_SESSION['email']]);
$password = sha1($_POST['password']);
if ($db->updateUser($user['id'], $user['email'], $password, $user['admin']))
if (!$db->updateTableWhere('users', ['password' => $password], ['id' => $user[0]['id']]))
{
header('Location: ' . $this->generateUrl('profile', 'show', array(
'successmessage' => 'Les données ont été mises à jour.'
)));
$_SESSION['errormessage'] = 'Impossible de mettre à jour le mot de passe.';
header('Location: ' . $this->generateUrl('profile'));
return false;
}
$_SESSION['successmessage'] = 'Les données ont été mises à jour.';
header('Location: ' . $this->generateUrl('profile'));
return true;
}
/**
* Cette fonction change la valeur du champ "transfer" de l'utilisateur
* @param $csrf : Le jeton CSRF
* @param string $_POST['transfer'] : Le nouveau transfer de l'utilisateur
* @return void;
*/
public function changeTransfer($csrf)
{
//On vérifie que le jeton csrf est bon
if (!internalTools::verifyCSRF($csrf))
{
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('profile'));
return false;
}
//Creation de l'object de base de données
global $db;
if (!isset($_POST['transfer']))
{
$_SESSION['errormessage'] = 'Vous devez renseigner un valeur';
header('Location: ' . $this->generateUrl('profile'));
return false;
}
$transfer = (boolean)$_POST['transfer'];
if (!$db->updateTableWhere('users', ['transfer' => $transfer], ['email' => $_SESSION['email']]))
{
$_SESSION['errormessage'] = 'Impossible de mettre les données à jour.';
header('Location: ' . $this->generateUrl('profile'));
return false;
}
$_SESSION['transfer'] = $transfer;
$_SESSION['successmessage'] = 'Les données ont été mises à jour.';
header('Location: ' . $this->generateUrl('profile'));
return true;
}
/**
* Cette fonction change l'email de l'utilisateur
* @param $csrf : Le jeton CSRF
* @param string $_POST['email'] : Le nouvel email de l'utilisateur
* @param string $_POST['verif_email'] : La vérification du nouvel email de l'utilisateur
* @return void;
*/
public function changeEmail()
public function changeEmail($csrf)
{
//On vérifie que le jeton csrf est bon
if (!internalTools::verifyCSRF())
if (!internalTools::verifyCSRF($csrf))
{
header('Location: ' . $this->generateUrl('profile', 'showAll', array(
'errormessage' => 'Jeton CSRF invalide !'
)));
return true;
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('profile'));
return false;
}
//Creation de l'object de base de données
@ -100,7 +127,8 @@
if (empty($_POST['mail']) || empty($_POST['verif_mail']) || $_POST['mail'] != $_POST['verif_mail'])
{
header('Location: ' . $this->generateUrl('profile', 'show', array(
$_SESSION['errormessage'] = 'Les e-mails ne correspondent pas.';
header('Location: ' . $this->generateUrl('profile', array(
'errormessage' => 'Les e-mails ne correspondent pas.'
)));
return false;
@ -110,64 +138,65 @@
if (!filter_var($email, FILTER_VALIDATE_EMAIL))
{
header('Location: ' . $this->generateUrl('profile', 'show', array(
'errormessage' => 'L\'adresse e-mail est invalide.'
)));
$_SESSION['errormessage'] = 'L\'adresse e-mail est invalide.';
header('Location: ' . $this->generateUrl('profile'));
return false;
}
$user = $db->getUserFromEmail($_SESSION['email']);
$user = $db->getFromTableWhere('users', ['email' => $_SESSION['email']]);
if ($db->updateUser($user['id'], $email, $user['password'], $user['admin']))
if (!$db->updateTableWhere('users', ['email' => $email], ['id' => $user[0]['id']]))
{
$_SESSION['email'] = $email;
header('Location: ' . $this->generateUrl('profile', 'show', array(
'successmessage' => 'Les données ont été mises à jour.'
)));
$_SESSION['errormessage'] = 'Cette adresse e-mail est déjà utilisée.';
header('Location: ' . $this->generateUrl('profile'));
return false;
}
header('Location: ' . $this->generateUrl('profile', 'show', array(
'errormessage' => 'Cette adresse e-mail est déjà utilisée.'
)));
return false;
$_SESSION['email'] = $email;
$_SESSION['successmessage'] = 'Les données ont été mises à jour.';
header('Location: ' . $this->generateUrl('profile'));
return true;
}
/**
* Cette fonction supprime l'utilisateur
* @param $csrf : Le jeton CSRF
* @param string $_POST['delete_account'] : La vérification que l'on veux bien supprimer l'utilisateur
* @return void;
*/
public function delete()
public function delete($csrf)
{
//On vérifie que le jeton csrf est bon
if (!internalTools::verifyCSRF())
if (!internalTools::verifyCSRF($csrf))
{
header('Location: ' . $this->generateUrl('profile', 'showAll', array(
'errormessage' => 'Jeton CSRF invalide !'
)));
return true;
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('profile'));
return false;
}
//Creation de l'object de base de données
global $db;
//Si l'utilisateur veux vraiment supprimer son compte
if (!empty($_POST['delete_account']))
if (empty($_POST['delete_account']))
{
$user = $db->getUserFromEmail($_SESSION['email']); //On récupère l'utilisateur en base
$db->deleteUsersIn(array($user['id'])); //On supprime l'utilisateur
$this->logout();
return true;
$_SESSION['errormessage'] = 'Le compte n\'a pas été supprimé';
header('Location: ' . $this->generateUrl('profile'));
return false;
}
header('Location: ' . $this->generateUrl('profile', 'show', array(
'errormessage' => 'Le compte n\'a pas été supprimé'
)));
if (!$db->deleteFromTableWhere('users', ['email' => $_SESSION['email']]))
{
$_SESSION['errormessage'] = 'Impossible de supprime le compte';
header('Location: ' . $this->generateUrl('profile'));
return false;
}
$this->logout();
return true;
}
/**
* Cette fonction déconnecte un utilisateur et le renvoie sur la page d'accueil
* @return void

View file

@ -24,27 +24,51 @@
/**
* Cette fonction retourne tous les SMS envoyés, sous forme d'un tableau
* @param int $page : La page à consulter. Par défaut 0
* @return void;
*/
public function showAll()
public function showAll($page = 0)
{
//Creation de l'object de base de données
global $db;
$page = (int)(isset($_GET['page']) ? $_GET['page'] : 0);
$page = (int)($page < 0 ? $page = 0 : $page);
$limit = 25;
$offset = $limit * $page;
//Récupération des SMS envoyés triés par date, du plus récent au plus ancien, par paquets de $limit, en ignorant les $offset premiers
$receiveds = $db->getAll('receiveds', 'at', true, $limit, $offset);
$receiveds = $db->getFromTableWhere('receiveds', [], 'at', true, $limit, $offset);
$this->render('receiveds', array(
return $this->render('receiveds/showAll', array(
'receiveds' => $receiveds,
'page' => $page,
'limit' => $limit,
'nbResults' => count($receiveds),
));
}
/**
* Cette fonction retourne tous les SMS reçus aujourd'hui pour la popup
* @return json : Un tableau des sms
*/
public function popup ()
{
global $db;
$now = new DateTime();
$receiveds = $db->getReceivedsSince($now->format('Y-m-d'));
$nbReceiveds = count($receiveds);
if (!isset($_SESSION['popup_nb_receiveds']) || ($_SESSION['popup_nb_receiveds'] > $nbReceiveds))
{
$_SESSION['popup_nb_receiveds'] = $nbReceiveds;
}
$newlyReceiveds = array_slice($receiveds, $_SESSION['popup_nb_receiveds']);
echo json_encode($newlyReceiveds);
$_SESSION['popup_nb_receiveds'] = $nbReceiveds;
return true;
}
}

View file

@ -15,50 +15,41 @@
}
/**
* Cette fonction est alias de showAll()
* Cette fonction retourne tous les sms programmés, sous forme d'un tableau permettant l'administration de ces sms
*/
public function byDefault()
{
$this->showAll();
}
/**
* Cette fonction retourne tous les sms programmés, sous forme d'un tableau permettant l'administration de ces sms
* @return void;
*/
public function showAll()
{
//Creation de l'object de base de données
global $db;
$scheduleds = $db->getAll('scheduleds');
$this->render('scheduleds', array(
$scheduleds = $db->getFromTableWhere('scheduleds');
$this->render('scheduleds/default', array(
'scheduleds' => $scheduleds,
));
}
/**
* Cette fonction supprime une liste de groupes
* @return void;
* @param $csrf : Le jeton CSRF
* @param int... $ids : Les id des commandes à supprimer
* @return boolean;
*/
public function delete()
public function delete($csrf, ...$ids)
{
//On vérifie que le jeton csrf est bon
if (!internalTools::verifyCSRF())
if (!internalTools::verifyCSRF($csrf))
{
header('Location: ' . $this->generateUrl('scheduleds', 'showAll', array(
'errormessage' => 'Jeton CSRF invalide !'
)));
return true;
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('profile'));
return false;
}
//Create de l'object de base de données
global $db;
$scheduleds_ids = $_GET;
$db->deleteScheduledsIn($scheduleds_ids);
$db->deleteScheduledsIn($ids);
header('Location: ' . $this->generateUrl('scheduleds'));
return true;
}
/**
@ -68,21 +59,22 @@
{
$now = new DateTime();
$babyonemoretime = new DateInterval('PT1M'); //Haha, i'm so a funny guy
$now->add($babyonemoretime);
$now->sub($babyonemoretime);
$now = $now->format('Y-m-d H:i');
$this->render('addScheduled', array(
return $this->render('scheduleds/add', array(
'now' => $now
));
}
/**
* Cette fonction retourne la page d'édition des sms programmés
* @param int... $ids : Les id des commandes à supprimer
*/
public function edit()
public function edit(...$ids)
{
global $db;
$scheduleds = $db->getScheduledsIn($_GET);
$scheduleds = $db->getScheduledsIn($ids);
//Pour chaque groupe, on récupère les contacts liés
foreach ($scheduleds as $key => $scheduled)
{
@ -94,32 +86,37 @@
$scheduleds[$key]['groups'] = $db->getGroupsForScheduled($scheduled['id']);
}
$this->render('editScheduleds', array(
$this->render('scheduleds/edit', array(
'scheduleds' => $scheduleds,
));
}
/**
* Cette fonction insert un nouveau SMS programmé
* @param $csrf : Le jeton CSRF
* @param optionnal boolean $api : Si vrai (faux par défaut), on retourne des réponses au lieu de rediriger
* @param string $_POST['date'] : La date a la quelle de sms devra être envoyé
* @param string $_POST['content'] : Le contenu du SMS
* @param string $_POST['numbers'] : Un tableau avec le numero des gens auxquel envoyer le sms
* @param string $_POST['contacts'] : Un tableau avec les ids des contacts auxquels envoyer le sms
* @param string $_POST['groups'] : Un tableau avec les ids des groupes auxquels envoyer le sms
* @return boolean;
*/
public function create($api = false)
public function create($csrf = '', $api = false, $discussion = false)
{
if (!$api)
{
//On vérifie que le jeton csrf est bon
if (!internalTools::verifyCSRF())
if (!internalTools::verifyCSRF($csrf))
{
header('Location: ' . $this->generateUrl('scheduleds', 'showAll', array(
'errormessage' => 'Jeton CSRF invalide !'
)));
return true;
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('profile'));
return false;
}
}
global $db;
$date = $_POST['date'];
$content = $_POST['content'];
$numbers = (isset($_POST['numbers'])) ? $_POST['numbers'] : array();
@ -131,9 +128,8 @@
{
if (!$api)
{
header('Location: ' . $this->generateUrl('scheduleds', 'showAll', array(
'errormessage' => 'Pas de texte pour ce SMS !'
)));
$_SESSION['errormessage'] = 'Pas de texte pour ce SMS !';
header('Location: ' . $this->generateUrl('scheduleds'));
}
return false;
}
@ -143,38 +139,53 @@
{
if (!$api)
{
header('Location: ' . $this->generateUrl('scheduleds', 'showAll', array(
'errormessage' => 'Pas numéro, de contacts, ni de groupes définis pour envoyer ce SMS !'
)));
$_SESSION['errormessage'] = 'Pas numéro, de contacts, ni de groupes définis pour envoyer ce SMS !';
header('Location: ' . $this->generateUrl('scheduleds'));
}
return false;
}
if (!internalTools::validateDate($date, 'Y-m-d H:i'))
if (!internalTools::validateDate($date, 'Y-m-d H:i:s') && !internalTools::validateDate($date, 'Y-m-d H:i'))
{
if (!$api)
{
header('Location: ' . $this->generateUrl('scheduleds', 'add', array(
'errormessage' => 'La date renseignée est invalide.'
)));
$_SESSION['errormessage'] = 'La date renseignée est invalide.';
header('Location: ' . $this->generateUrl('scheduleds'));
}
return false;
}
if ($db->createScheduleds($date, $content))
if (!$db->insertIntoTable('scheduleds', ['at' => $date, 'content' => $content, 'progress' => false]))
{
if (!$api)
{
$_SESSION['errormessage'] = 'Impossible de créer ce SMS.';
header('Location: ' . $this->generateUrl('scheduleds'));
}
return false;
}
$id_scheduled = $db->lastId();
$db->createEvent('SCHEDULED_ADD', 'Ajout d\'un SMS pour le ' . $date);
if ($discussion)
{
$_SESSION['discussion_wait_progress'] = isset($_SESSION['discussion_wait_progress']) ? $_SESSION['discussion_wait_progress'] : [];
$_SESSION['discussion_wait_progress'][] = $id_scheduled;
}
$db->insertIntoTable('events', ['type' => 'SCHEDULED_ADD', 'text' => 'Ajout d\'un SMS pour le ' . $date]);
$errors = false;
foreach ($numbers as $number)
{
if ($number = internalTools::parsePhone($number))
if (!$number = internalTools::parsePhone($number))
{
$db->createScheduleds_numbers($id_scheduled, $number);
$errors = true;
continue;
}
else
if (!$db->insertIntoTable('scheduleds_numbers', ['id_scheduled' => $id_scheduled, 'number' => $number]))
{
$errors = true;
}
@ -182,7 +193,7 @@
foreach ($contacts as $id_contact)
{
if (!$db->createScheduleds_contacts($id_scheduled, $id_contact))
if (!$db->insertIntoTable('scheduleds_contacts', ['id_scheduled' => $id_scheduled, 'id_contact' => $id_contact]))
{
$errors = true;
}
@ -190,7 +201,7 @@
foreach ($groups as $id_group)
{
if (!$db->createScheduleds_groups($id_scheduled, $id_group))
if (!$db->insertIntoTable('scheduleds_groups', ['id_scheduled' => $id_scheduled, 'id_group' => $id_group]))
{
$errors = true;
}
@ -200,45 +211,33 @@
{
if (!$api)
{
header('Location: ' . $this->generateUrl('scheduleds', 'showAll', array(
'errormessage' => 'Le SMS a bien été créé, mais certains numéro ne sont pas valides.'
)));
$_SESSION['errormessage'] = 'Le SMS a bien été créé, mais certains numéro ne sont pas valides.';
header('Location: ' . $this->generateUrl('scheduleds'));
}
return true;
}
else
{
if (!$api)
{
header('Location: ' . $this->generateUrl('scheduleds', 'showAll', array(
'successmessage' => 'Le SMS a bien été créé.'
)));
}
return true;
}
}
if (!$api)
{
header('Location: ' . $this->generateUrl('scheduleds', 'showAll', array(
'errormessage' => 'Impossible de créer ce SMS.'
)));
$_SESSION['successmessage'] = 'Le SMS a bien été créé.';
header('Location: ' . $this->generateUrl('scheduleds'));
}
return false;
return true;
}
/**
* Cette fonction met à jour une liste de sms
* @param $csrf : Le jeton CSRF
* @param array $_POST['scheduleds'] : Un tableau contenant les sms avec leurs nouvelles valeurs
*/
public function update()
public function update($csrf)
{
//On vérifie que le jeton csrf est bon
if (!internalTools::verifyCSRF())
if (!internalTools::verifyCSRF($csrf))
{
header('Location: ' . $this->generateUrl('scheduleds', 'showAll', array(
'errormessage' => 'Jeton CSRF invalide !'
)));
return true;
$_SESSION['successmessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('scheduleds'));
return false;
}
global $db;
@ -248,68 +247,64 @@
foreach ($_POST['scheduleds'] as $id_scheduled => $scheduled)
{
$date = $scheduled['date'];
if (!internalTools::validateDate($date, 'Y-m-d H:i'))
if (!internalTools::validateDate($date, 'Y-m-d H:i:s') && !internalTools::validateDate($date, 'Y-m-d H:i'))
{
header('Location: ' . $this->generateUrl('scheduleds', 'showAll', array(
'errormessage' => 'La date renseignée pour le SMS numéro ' . $scheduled['id'] . ' est invalide.'
)));
return true;
$_SESSION['errormessage'] = 'La date renseignée pour le SMS numéro ' . $scheduled['id'] . ' est invalide.';
header('Location: ' . $this->generateUrl('scheduleds'));
return false;
}
//Si la date fournie est passée, on la change pour dans 2 minutes
$objectDate = DateTime::createFromFormat('Y-m-d H:i', $date);
$db->updateScheduled($id_scheduled, $date, $scheduled['content'], false); //On met à jour le sms
$db->updateTableWhere('scheduleds', ['content' => $scheduled['content'], 'at' => $date], ['id' => $id_scheduled]);
$db->deleteScheduleds_numbersForScheduled($id_scheduled); //On supprime tous les numéros pour ce SMS
$db->deleteScheduleds_contactsForScheduled($id_scheduled); //On supprime tous les contacts pour ce SMS
$db->deleteScheduleds_GroupsForScheduled($id_scheduled); //On supprime tous les groupes pour ce SMS
//Pour chaque numéro, on va le vérifier et l'ajouter au sms
foreach ($scheduled['numbers'] as $number)
{
if (internalTools::parsePhone($number))
if (!$number = internalTools::parsePhone($number))
{
$db->createScheduleds_numbers($id_scheduled, $number);
$errors = true;
continue;
}
else
if (!$db->insertIntoTable('scheduleds_numbers', ['id_scheduled' => $id_scheduled, 'number' => $number]))
{
$errors = true;
}
}
//Pour chaque contact, on va l'ajouter au sms
foreach ($scheduled['contacts'] as $id_contact)
{
if (!$db->createScheduleds_contacts($id_scheduled, $id_contact))
if (!$db->insertIntoTable('scheduleds_contacts', ['id_scheduled' => $id_scheduled, 'id_contact' => $id_contact]))
{
$errors = true;
}
}
//Pour chaque groupe, on va l'ajouter au sms
foreach ($scheduled['groups'] as $id_group)
{
if (!$db->createScheduleds_groups($id_scheduled, $id_group))
if (!$db->insertIntoTable('scheduleds_groups', ['id_scheduled' => $id_scheduled, 'id_group' => $id_group]))
{
$errors = true;
}
}
}
if (!$errors)
if ($errors)
{
$message = 'Tous les SMS ont été modifiés avec succès.';
header('Location: ' . $this->generateUrl('scheduleds', 'showAll', array(
'successmessage' => $message,
)));
$_SESSION['errormessage'] = 'Tous les SMS ont été modifiés mais certaines données incorrects ont été ignorées.';
header('Location: ' . $this->generateUrl('scheduleds'));
return false;
}
else
{
$message = 'Tous les SMS ont été modifiés mais certaines données incorrects ont été ignorées.';
header('Location: ' . $this->generateUrl('scheduleds', 'showAll', array(
'errormessage' => $message,
)));
$_SESSION['successmessage'] = 'Tous les SMS ont été modifiés avec succès.';
header('Location: ' . $this->generateUrl('scheduleds'));
return true;
}
}
}

View file

@ -24,23 +24,24 @@
/**
* Cette fonction retourne tous les SMS envoyés, sous forme d'un tableau
* @param int $page : La page à consulter. Par défaut 0
* @return void;
*/
public function showAll()
public function showAll($page = 0)
{
//Creation de l'object de base de données
global $db;
$page = (int)(isset($_GET['page']) ? $_GET['page'] : 0);
$page = (int)($page < 0 ? $page = 0 : $page);
$limit = 25;
$offset = $limit * $page;
//Récupération des SMS envoyés triés par date, du plus récent au plus ancien, par paquets de $limit, en ignorant les $offset premiers
$sendeds = $db->getAll('sendeds', 'at', true, $limit, $offset);
$sendeds = $db->getFromTableWhere('sendeds', [], 'at', true, $limit, $offset);
$this->render('sendeds', array(
$this->render('sendeds/showAll', array(
'sendeds' => $sendeds,
'page' => $page,
'limit' => $limit,

View file

@ -11,14 +11,6 @@
const API_ERROR_MISSING_FIELD = 3;
/**
* Cette fonction est alias de showAll()
*/
public function byDefault()
{
$this->send();
}
/**
* Cette fonction permet d'envoyer un SMS, en passant simplement des arguments à l'URL (ou pas $_GET)
* @param string text = Le contenu du SMS
@ -27,7 +19,7 @@
* @param mixed groups = 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 send()
public function byDefault()
{
global $db;
@ -82,27 +74,25 @@
//Pour chaque contact, on récupère l'id du contact
foreach ($contacts as $key => $name)
{
if ($contact = $db->getContactFromName($name))
{
$contacts[$key] = $contact['id'];
}
else
if (!$contact = $db->getFromTableWhere('contacts', ['name' => $name]))
{
unset($contacts[$key]);
continue;
}
$contacts[$key] = $contact['id'];
}
//Pour chaque groupe, on récupère l'id du groupe
foreach ($groups as $key => $name)
{
if ($group = $db->getGroupFromName($name))
{
$groups[$key] = $group['id'];
}
else
if ($group = $db->getFromTableWhere('groups', ['name' => $name]))
{
unset($groups[$key]);
continue;
}
$groups[$key] = $group['id'];
}
//Si la date n'est pas définie, on la met à la date du jour
@ -118,8 +108,9 @@
echo json_encode(array(
'error' => self::API_ERROR_MISSING_FIELD,
));
return true;
return false;
}
//On assigne les variable POST (après avoir vidé $_POST) en prévision de la création du SMS
$_POST = array();
$_POST['content'] = $text;
@ -129,19 +120,20 @@
$_POST['groups'] = $groups;
$scheduleds = new scheduleds();
$success = $scheduleds->create(true);
$success = $scheduleds->create('', true);
if ($success)
{
echo json_encode(array(
'error' => self::API_ERROR_NO,
));
}
else
if (!$success)
{
echo json_encode(array(
'error' => self::API_ERROR_CREATION_FAILED,
));
}
return false;
}
echo json_encode(array(
'error' => self::API_ERROR_NO,
));
return true;
}
}

View file

@ -15,27 +15,18 @@
}
/**
* Cette fonction est alias de showAll()
* Cette fonction retourne tous les utilisateurs, sous forme d'un tableau permettant l'administration de ces utilisateurs
*/
public function byDefault()
{
$this->showAll();
}
/**
* Cette fonction retourne tous les utilisateurs, sous forme d'un tableau permettant l'administration de ces utilisateurs
* @return void;
*/
public function showAll()
{
//Creation de l'object de base de données
global $db;
//Récupération des utilisateurs
$users = $db->getAll('users');
$users = $db->getFromTableWhere('users');
$this->render('users', array(
$this->render('users/default', array(
'users' => $users,
));
}
@ -45,31 +36,32 @@
*/
public function add()
{
$this->render('addUser');
$this->render('users/add');
}
/**
* Cette fonction insert un nouvel utilisateur
* @param $csrf : Le jeton CSRF
* @param string $_POST['email'] : L'email de l'utilisateur
* @param string $_POST['email_confirm'] : Confirmation de l'email de l'utilisateur
* @param boolean $_POST['admin'] : Optionnel : Si l'utilisateur est admin. Par défaut non
*/
public function create()
public function create($csrf)
{
//On vérifie que le jeton csrf est bon
if (!internalTools::verifyCSRF())
if (!internalTools::verifyCSRF($csrf))
{
header('Location: ' . $this->generateUrl('users', 'showAll', array(
'errormessage' => 'Jeton CSRF invalide !'
)));
return true;
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('users', 'add'));
return false;
}
global $db;
if (!isset($_POST['email']) || !isset($_POST['email_confirm']) || $_POST['email'] != $_POST['email_confirm'])
if (!isset($_POST['email']) || !isset($_POST['email_confirm']) || ($_POST['email'] != $_POST['email_confirm']))
{
header('Location: ' . $this->generateUrl('users', 'add', array(
'errormessage' => 'Les e-mails fournis ne correspondent pas.'
)));
$_SESSION['errormessage'] = 'Les e-mails fournis ne correspondent pas.';
header('Location: ' . $this->generateUrl('users', 'add'));
return false;
}
@ -79,9 +71,8 @@
if (!filter_var($email, FILTER_VALIDATE_EMAIL))
{
header('Location: ' . $this->generateUrl('users', 'add', array(
'errormessage' => 'L\'e-mail fourni présente un format incorrect.'
)));
$_SESSION['errormessage'] = 'L\'e-mail fourni présente un format incorrect.';
header('Location: ' . $this->generateUrl('users', 'add'));
return false;
}
@ -101,44 +92,40 @@
$message .= "-------------------------------------\n";
$message .= "Pour plus d'informations sur le système RaspiSMS, rendez-vous sur le site http://raspbian-france.fr\n";
if (mail($email, 'Identifiants RaspiSMS', $message))
if (!mail($email, 'Identifiants RaspiSMS', $message))
{
if ($db->createUser($email, $password, $admin))
{
$db->createEvent('USER_ADD', 'Ajout de l\'utilisateur : ' . $email);
header('Location: ' . $this->generateUrl('users', 'showAll', array(
'successmessage' => 'L\'utilisateur a bien été créé.'
)));
return true;
$_SESSION['errormessage'] = 'Impossible d\'envoyer le mail d\'inscription à l\'utilisateur. Le compte n\'a donc pas été créé.';
header('Location: ' . $this->generateUrl('users', 'add'));
return false;
}
header('Location: ' . $this->generateUrl('users', 'add', array(
'errormessage' => 'Impossible de créer cet utilisateur.'
)));
return false;
}
else
if (!$db->insertIntoTable('users', ['email' => $email, 'password' => $password, 'admin' => $admin]))
{
header('Location: ' . $this->generateUrl('users', 'showAll', array(
'errormessage' => 'Impossible d\'envoyer le mail d\'inscription à l\'utilisateur. Le compte n\'a donc pas été créé.'
)));
$_SESSION['errormessage'] = 'Impossible de créer cet utilisateur.';
header('Location: ' . $this->generateUrl('users', 'add'));
return false;
}
$db->insertIntoTable('events', ['type' => 'USER_ADD', 'text' => 'Ajout de l\'utilisateur : ' . $email]);
$_SESSION['successmessage'] = 'L\'utilisateur a bien été créé.';
header('Location: ' . $this->generateUrl('users'));
return true;
}
/**
* Cette fonction supprimer une liste d'utilisateur
* @return void;
* @param $csrf : Le jeton CSRF
* @param int... $ids : Les id des commandes à supprimer
* @return boolean;
*/
public function delete()
public function delete($csrf, ...$ids)
{
//On vérifie que le jeton csrf est bon
if (!internalTools::verifyCSRF())
if (!internalTools::verifyCSRF($csrf))
{
header('Location: ' . $this->generateUrl('users', 'showAll', array(
'errormessage' => 'Jeton CSRF invalide !'
)));
return true;
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
header('Location: ' . $this->generateUrl('users'));
return false;
}
//Create de l'object de base de données
@ -147,14 +134,13 @@
//Si on est pas admin
if (!$_SESSION['admin'])
{
header('Location: ' . $this->generateUrl('users', 'showAll', array(
'errormessage' => 'Vous devez être administrateur pour effectuer cette action.'
)));
$_SESSION['errormessage'] = 'Vous devez être administrateur pour effectuer cette action.';
header('Location: ' . $this->generateUrl('users'));
return false;
}
$users_ids = $_GET;
$db->deleteUsersIn($users_ids);
$db->deleteUsersIn($ids);
header('Location: ' . $this->generateUrl('users'));
return true;
}
}

View file

@ -3,7 +3,7 @@
CREATE DATABASE IF NOT EXISTS raspisms;
USE raspisms;
CREATE TABLE receiveds
CREATE TABLE IF NOT EXISTS receiveds
(
id INT NOT NULL AUTO_INCREMENT,
at DATETIME NOT NULL,
@ -13,7 +13,7 @@ CREATE TABLE receiveds
PRIMARY KEY (id)
);
CREATE TABLE sendeds
CREATE TABLE IF NOT EXISTS sendeds
(
id INT NOT NULL AUTO_INCREMENT,
at DATETIME NOT NULL,
@ -22,32 +22,34 @@ CREATE TABLE sendeds
PRIMARY KEY (id)
);
CREATE TABLE scheduleds
CREATE TABLE IF NOT EXISTS scheduleds
(
id INT NOT NULL AUTO_INCREMENT,
at DATETIME NOT NULL,
content VARCHAR(1000) NOT NULL,
progress BOOLEAN NOT NULL,
progress BOOLEAN NOT NULL DEFAULT 0,
PRIMARY KEY (id)
);
CREATE TABLE contacts
CREATE TABLE IF NOT EXISTS contacts
(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
number VARCHAR(12) NOT NULL,
PRIMARY KEY (id)
PRIMARY KEY (id),
UNIQUE (name)
);
CREATE TABLE groups
CREATE TABLE IF NOT EXISTS groups
(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
PRIMARY KEY (id),
UNIQUE (name)
);
CREATE TABLE groups_contacts
CREATE TABLE IF NOT EXISTS groups_contacts
(
id INT NOT NULL AUTO_INCREMENT,
id_group INT NOT NULL,
@ -57,7 +59,7 @@ CREATE TABLE groups_contacts
FOREIGN KEY (id_contact) REFERENCES contacts (id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE scheduleds_contacts
CREATE TABLE IF NOT EXISTS scheduleds_contacts
(
id INT NOT NULL AUTO_INCREMENT,
id_scheduled INT NOT NULL,
@ -67,7 +69,7 @@ CREATE TABLE scheduleds_contacts
FOREIGN KEY (id_contact) REFERENCES contacts (id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE scheduleds_groups
CREATE TABLE IF NOT EXISTS scheduleds_groups
(
id INT NOT NULL AUTO_INCREMENT,
id_scheduled INT NOT NULL,
@ -77,7 +79,7 @@ CREATE TABLE scheduleds_groups
FOREIGN KEY (id_group) REFERENCES groups (id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE scheduleds_numbers
CREATE TABLE IF NOT EXISTS scheduleds_numbers
(
id INT NOT NULL AUTO_INCREMENT,
id_scheduled INT NOT NULL,
@ -86,7 +88,7 @@ CREATE TABLE scheduleds_numbers
FOREIGN KEY (id_scheduled) REFERENCES scheduleds (id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE commands
CREATE TABLE IF NOT EXISTS commands
(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(25) NOT NULL,
@ -96,22 +98,31 @@ CREATE TABLE commands
UNIQUE (name)
);
CREATE TABLE events
CREATE TABLE IF NOT EXISTS events
(
id INT NOT NULL AUTO_INCREMENT,
type VARCHAR(25) NOT NULL,
at DATETIME NOT NULL,
at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
text VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE users
CREATE TABLE IF NOT EXISTS users
(
id INT NOT NULL AUTO_INCREMENT,
email VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
admin BOOLEAN NOT NULL,
admin BOOLEAN NOT NULL DEFAULT FALSE,
transfer BOOLEAN NOT NULL DEFAULT FALSE,
PRIMARY KEY (id),
UNIQUE (email)
);
CREATE TABLE IF NOT EXISTS transfers
(
id INT NOT NULL AUTO_INCREMENT,
id_received INT NOT NULL,
progress BOOLEAN NOT NULL DEFAULT 0,
PRIMARY KEY (id),
FOREIGN KEY (id_received) REFERENCES receiveds (id) ON DELETE CASCADE ON UPDATE CASCADE
);

View file

@ -9,12 +9,19 @@
}
/** POPUPS ALERT **/
.popup-alert
.popup-alerts-container
{
position: fixed;
left: 0;
top: 0;
z-index: 9999;
z-index: 9998;
width: 100%;
}
.popup-alert
{
width: 50%;
position: relative;
}
/** FOOTER **/
@ -81,3 +88,103 @@ footer
color: #fff;
background-color: #000;
}
.goto:hover
{
cursor: pointer;
}
/** DISCUSSION **/
.table-discussions tbody tr:hover
{
cursor: pointer;
background-color: #999;
}
.discussion-container
{
overflow: auto;
}
.discussion-message
{
border-radius: 5px;
display: inline-block;
max-width: 90%;
padding: 10px;
position: relative;
}
.discussion-message-text
{
font-size: 1.3em;
}
.discussion-message-date
{
font-size: 0.9em;
}
.message-container
{
margin-bottom: 10px;
}
.message-received
{
background-color: #1abc9c;
float: left;
color: #fff;
}
.message-sended
{
background-color: #ddd;
float: right;
}
.message-received .discussion-message-date
{
color: #f0f0f0;
}
.message-sended .discussion-message-date
{
text-align: right;
color: #888;
}
.message-input
{
width: 100%;
max-width: 100%;
background-color: #ddd;
}
.message-input textarea
{
width: 100%;
resize: none;
height: 6em;
}
.message-input button
{
float: right;
margin-top: 8px;
}
.message-in-progress-hover
{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 900;
opacity: 0.7;
background-color: #fff;
font-size: 20px;
text-align: center;
padding-top: 10px;
}

0
fonts/glyphicons-halflings-regular.woff2 Normal file → Executable file
View file

View file

@ -17,5 +17,86 @@ function showMessage(message, type)
}
var alerthtml = '<div class="col-xs-10 col-xs-offset-1 col-md-6 col-md-offset-3 popup-alert alert ' + type + '"><button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>' + message + '</div>';
jQuery('body').prepend(alerthtml);
jQuery('body .popup-alerts-container').prepend(alerthtml);
}
/**
* Cette fonction vérifie si un message a été reçu
*/
function verifReceived()
{
jQuery('.popup-alert').fadeOut('slow');
jQuery.getJSON(HTTP_PWD + "/receiveds/popup", function( data ) {
$.each(data, function(key, val) {
showMessage('SMS reçu du ' + val.send_by.replace(/</g, "&lt;").replace(/>/g, "&gt;") + ' : ' + val.content.replace(/</g, "&lt;").replace(/>/g, "&gt;"), 1);
});
});
}
/**
* Cette fonction permet de scroller au dernier message
*/
function scrollDownDiscussion()
{
var discussion_height = jQuery('.discussion-container').innerHeight();
var discussion_scroll_height = jQuery('.discussion-container')[0].scrollHeight;
var discussion_scroll_top = jQuery('.discussion-container').scrollTop();
var scroll_before_end = discussion_scroll_height - (discussion_scroll_top + discussion_height);
//On scroll uniquement si on a pas remonté plus haut que la moitié de la fenetre de discussion
if (scroll_before_end <= discussion_height / 2)
{
jQuery('.discussion-container').animate({scrollTop: 1000000});
}
}
jQuery(document).ready(function()
{
var verifReceivedInterval = setInterval(verifReceived, 10000);
jQuery('body').on('click', '.goto', function (e) {
e.preventDefault();
if (jQuery(this).attr('url'))
{
if (jQuery(this).attr('target'))
{
window.open(jQuery(this).attr('url'), jQuery(this).attr('target'));
}
else
{
window.location = jQuery(this).attr('url');
}
}
});
jQuery('body').on('submit', '.send-message-discussion', function (e)
{
e.preventDefault();
var form = jQuery(this);
var message = form.find('textarea').val();
var formData = new FormData(form[0]);
jQuery('.discussion-container').find('#send-message-spiner').remove();
jQuery('.discussion-container').append('<div class="text-center" id="send-message-spiner"><i class="fa fa-spinner fa-spin"></i></div>');
scrollDownDiscussion();
jQuery.ajax({
url: form.attr('action'),
type: form.attr('method'),
data: formData,
contentType: false,
processData: false,
dataType: "json",
success: function (data)
{
if (!data.success)
{
showMessage(data.message.replace(/</g, "&lt;").replace(/>/g, "&gt;"), 0);
jQuery('.discussion-container').find('#send-message-spiner').remove();
}
}
}).done(function()
{
form.trigger("reset");
});
});
});

View file

@ -1,4 +1,4 @@
/**
/**
* Lithuanian translation for bootstrap-datetimepicker
* Šarūnas Gliebus <ssharunas@yahoo.co.uk>
*/

View file

@ -45,58 +45,6 @@
return $this->runQuery($query, $params);
}
/**
* Insert un nouveau SMS envoyé
* @param string $date : La date d'envoie du message
* @param string $target : Numéro auquel a été envoyé le message
* @param string $content : Texte du message
* @return int : le nombre de SMS créés
*/
public function createSended($date, $target, $content)
{
$query = '
INSERT INTO sendeds(at, target, content)
VALUES (:date, :target, :content)
';
$params = array(
'date' => $date,
'target' => $target,
'content' => $content,
);
return $this->runQuery($query, $params, self::ROWCOUNT); //On retourne le nombre de lignes ajoutés
}
/**
* update un sended
* @param int $id : L'id du sended à modifier
* @param string $date : La nouvelle date du SMS
* @param string $target : La nouvelle cible du SMS
* @param string $content : Le nouveau contenu du SMS
* @param string $success : Le nouveau statut du SMS
* @return void
*/
public function updateSended($id, $date, $target, $content)
{
$query = '
UPDATE sendeds
SET at = :date,
target = :target,
content = :content,
WHERE id = :id
';
$params = array(
'id' => $id,
'date' => $date,
'target' => $target,
'content' => $content,
);
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/*********************************/
/* PARTIE DES REQUETES RECEIVEDS */
/*********************************/
@ -147,21 +95,17 @@
return $this->runQuery($query, $params);
}
/******************************/
/* PARTIE DES REQUETES EVENTS */
/******************************/
/**
* Récupère les evenements enregistrés depuis une date
* @param $date : La date depuis laquelle on veux les evenements (au format 2014-10-25)
* @return array : Tableau avec tous les evenements depuis la date
* Récupère les SMS reçus depuis une date
* @param $date : La date depuis laquelle on veux les SMS (au format 2014-10-25 20:10:05)
* @return array : Tableau avec tous les SMS depuis la date
*/
public function getEventsSince($date)
public function getReceivedsSince($date)
{
$query = "
SELECT *
FROM events
WHERE at > STR_TO_DATE(:date, '%Y-%m-%d')
FROM receiveds
WHERE at > STR_TO_DATE(:date, '%Y-%m-%d %h:%i:%s')
";
$params = array(
@ -172,24 +116,67 @@
}
/**
* Enregistre un nouvel évenement
* @param string $type = Type d'evenement enregistré
* @param string $text = Texte de l'évenement (max 255chars)
* @return int = Nombre de lignes insérées
* Récupère les SMS reçus depuis une date pour un numero
* @param $date : La date depuis laquelle on veux les SMS (au format 2014-10-25 20:10:05)
* @param $number : Le numéro
* @return array : Tableau avec tous les SMS depuis la date
*/
public function createEvent($type = '', $text = '')
public function getReceivedsSinceForNumberOrderByDate($date, $number)
{
$query = '
INSERT INTO events(type, at, text)
VALUES (:type, NOW(), :text)
';
$query = "
SELECT *
FROM receiveds
WHERE at > STR_TO_DATE(:date, '%Y-%m-%d %h:%i:%s')
AND send_by = :number
ORDER BY at ASC
";
$params = array(
'type' => $type,
'text' => $text
'date' => $date,
'number' => $number
);
return $this->runQuery($query, $params, self::ROWCOUNT);
return $this->runQuery($query, $params);
}
/**
* Récupère les receiveds dont l'id fait partie de la liste fournie
* @param array $receiveds_ids = Tableau des id des receiveds voulus
* @return array : Retourne un tableau avec les receiveds adaptés
*/
public function getReceivedsIn($receiveds_ids)
{
$query = "
SELECT *
FROM receiveds
WHERE id ";
//On génère la clause IN et les paramètres adaptés depuis le tableau des id
$generted_in = $this->generateInFromArray($receiveds_ids);
$query .= $generted_in['QUERY'];
$params = $generted_in['PARAMS'];
return $this->runQuery($query, $params);
}
/***********************************/
/* PARTIE DES REQUETES DISCUSSIONS */
/***********************************/
/**
* Récupère les SMS reçus groupé par numéro et trié par date
* @return array : Le tablea avec les sms et la date
*/
public function getDiscussions()
{
$query = "
SELECT MAX(at) as at, number
FROM (SELECT at, target as number FROM sendeds UNION (SELECT at, send_by as number FROM receiveds)) as discussions
GROUP BY number
ORDER BY at DESC
";
return $this->runQuery($query);
}
/********************************/
@ -215,63 +202,6 @@
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* Compte le nombre de contacts
* @return int : le nombre de contacts
*/
public function countContacts()
{
$query = '
SELECT COUNT(id) as nb
FROM contacts
';
$params = array();
$donnees = $this->runQuery($query, $params, self::FETCH);
return $donnees['nb'];
}
/**
* Insert un contact
* @param string $nom : Le nom du nouveau contact
* @param string $number : Le numéro du nouveau contact
* @return int : le nombre de contacts
*/
public function createContact($name, $number)
{
$query = '
INSERT INTO contacts(name, number)
VALUES (:name, :number)
';
$params = array(
'name' => $name,
'number' => $number,
);
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* Récupère un contact à partir de son nom
* @param string $name = Le nom du contact
* @return array : Retourne le contact
*/
public function getContactFromName($name)
{
$query = "
SELECT *
FROM contacts
WHERE name = :name";
$params = array(
'name' => $name
);
return $this->runQuery($query, $params, self::FETCH);
}
/**
* Récupère les contacts dont l'id fait partie de la liste fournie
* @param array $contacts_ids = Tableau des id des contacts voulus
@ -292,54 +222,10 @@
return $this->runQuery($query, $params);
}
/**
* update un contact
* @param int $id : L'id du contact à modifier
* @param string $name : Le nouveau nom du contact
* @param string $number : Le nouveau numéro du contact
* @return void
*/
public function updateContact($id, $name, $number)
{
$query = '
UPDATE contacts
SET name = :name,
number = :number
WHERE id = :id
';
$params = array(
'id' => $id,
'name' => $name,
'number' => $number,
);
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/******************************/
/* PARTIE DES REQUETES GROUPS */
/******************************/
/**
* Récupère un group à partir de son nom
* @param string $name = Le nom du group
* @return array : Retourne le group
*/
public function getGroupFromName($name)
{
$query = "
SELECT *
FROM groups
WHERE name = :name";
$params = array(
'name' => $name
);
return $this->runQuery($query, $params, self::FETCH);
}
/**
* Insert un group
* @param string $nom : Le nom du nouveau group
@ -359,45 +245,6 @@
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* update un groupe
* @param int $id : L'id du groupe à modifier
* @param string $name : Le nouveau nom du groupe
* @return int : Le nombre de lignes modifiés
*/
public function updateGroup($id, $name)
{
$query = '
UPDATE groups
SET name = :name
WHERE id = :id
';
$params = array(
'id' => $id,
'name' => $name,
);
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* Compte le nombre de groups
* @return int : le nombre de groups
*/
public function countGroups()
{
$query = '
SELECT COUNT(id) as nb
FROM groups
';
$params = array();
$donnees = $this->runQuery($query, $params, self::FETCH);
return $donnees['nb'];
}
/**
* Récupère les groupes dont l'id fait partie de la liste fournie
* @param array $groups_ids = Tableau des id des groupes voulus
@ -463,26 +310,6 @@
return $this->runQuery($query, $params);
}
/* Insert un groups_contacts
* @param string $id_group : L'id du group
* @param string $id_contact : L'id du contact
* @return int : le nombre de lignes crées
*/
public function createGroups_contacts($id_group, $id_contact)
{
$query = '
INSERT INTO groups_contacts(id_group, id_contact)
VALUES (:id_group, :id_contact)
';
$params = array(
'id_group' => $id_group,
'id_contact' => $id_contact,
);
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* Récupère tout les groupes, avec le nombre de contact dans chacun
* @return array : Tableau avec tous les groupes et le nombre de contacts liés
@ -533,48 +360,10 @@
return $req->fetchAll();
}
/**
* Supprime tous les groups_contacts pour un groupe donné
* @param int $id : L'id du groupe pour lequel on doit supprimer les groups_contacts
* @return int Le nombre de lignes supprimées
*/
public function deleteGroups_contactsForGroup($id_group)
{
$query = '
DELETE FROM groups_contacts
WHERE id_group = :id_group
';
$params = array(
'id_group' => $id_group
);
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**********************************/
/* PARTIE DES REQUETES SCHEDULEDS */
/**********************************/
/**
* Récupère SMS programmé à partir de son id
* @param int $id = L'id du SMS programmé
* @return array : Retourne le contact
*/
public function getScheduledFromId($id)
{
$query = "
SELECT *
FROM scheduleds
WHERE id = :id";
$params = array(
'id' => $id
);
return $this->runQuery($query, $params, self::FETCH);
}
/**
* Récupère les sms programmés dont l'id fait partie de la liste fournie
* @param array $scheduleds_ids = Tableau des id des sms voulus
@ -638,34 +427,6 @@
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* update un sms programmé
* @param int $id : L'id du sms à modifier
* @param string $date : La nouvelle date du sms
* @param string $content : Le nouveau contenu du sms
* @param boolean $progress : Le nouveau statut de la progression du sms
* @return int : Le nombre de lignes modifiées
*/
public function updateScheduled($id, $date, $content, $progress)
{
$query = '
UPDATE scheduleds
SET at = :date,
content = :content,
progress = :progress
WHERE id = :id
';
$params = array(
'id' => $id,
'date' => $date,
'content' => $content,
'progress' => $progress,
);
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* Supprime tous les sms programmés dont l'id fait partie du tableau fourni
* @param $contacts_ids : Tableau des id des sms à supprimer
@ -686,20 +447,54 @@
}
/**
* Compte le nombre de sms programmés
* @return int : le nombre de sms programmés
* Cette fonction retourne les sms programmés pour un numéro donné et avant une date
* @param string $date : La date avant laquel on veux les numéros (format yyyy-mm-dd hh:mm:ss)
* @param string $number : Le numéro cible
* @return array : Les scheduleds correspondants
*/
public function countScheduleds()
public function getScheduledsBeforeDateForNumber($date, $number)
{
$query = '
SELECT COUNT(id) as nb
$query = "
SELECT *
FROM scheduleds
';
WHERE at <= :date
AND (
id IN (
SELECT id_scheduled
FROM scheduleds_numbers
WHERE number = :number
)
OR id IN (
SELECT id_scheduled
FROM scheduleds_contacts
WHERE id_contact IN (
SELECT id
FROM contacts
WHERE number = :number
)
)
OR id IN (
SELECT id_scheduled
FROM scheduleds_groups
WHERE id_group IN (
SELECT id_group
FROM groups_contacts
WHERE id_contact IN (
SELECT id
FROM contacts
WHERE number = :number
)
)
)
)
";
$params = array();
$params = array(
'date' => $date,
'number' => $number,
);
$donnees = $this->runQuery($query, $params, self::FETCH);
return $donnees['nb'];
return $this->runQuery($query, $params);
}
/********************************/
@ -726,57 +521,6 @@
return $this->runQuery($query, $params);
}
/**
* Insert un commande
* @param string $name : Le nom de la command
* @param string $script : Le chemin du script à appeler
* @param string $admin : Défini si il est nécessaire d'être admin
* @return int : le nombre de commandes ajoutées
*/
public function createCommand($name, $script, $admin)
{
$query = '
INSERT INTO commands(name, script, admin)
VALUES (:name, :script, :admin)
';
$params = array(
'name' => $name,
'script' => $script,
'admin' => $admin,
);
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* update une commande
* @param int $id : L'id de la commande à modifier
* @param string $name : Le nouveau nom de la commande
* @param string $script : Le nouveau script de la commande
* @param string $name : Nouvel état de la necessité des droits administrateur
* @return int : Le nombre de lignes modifiée
*/
public function updateCommand($id, $name, $script, $admin)
{
$query = '
UPDATE commands
SET name = :name,
script = :script,
admin = :admin
WHERE id = :id
';
$params = array(
'id' => $id,
'name' => $name,
'script' => $script,
'admin' => $admin,
);
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* Supprime tous les commands dont l'id fait partie du tableau fourni
* @param $commands_ids : Tableau des id des commands à supprimer
@ -796,48 +540,10 @@
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* Compte le nombre de commands
* @return int : le nombre de commands
*/
public function countCommands()
{
$query = '
SELECT COUNT(id) as nb
FROM commands
';
$params = array();
$donnees = $this->runQuery($query, $params, self::FETCH);
return $donnees['nb'];
}
/*******************************************/
/* PARTIE DES REQUETES SCHEDULEDS_CONTACTS */
/*******************************************/
/**
* Créer un nouveau scheduleds_contacts
* @param int $id_scheduled : L'id du SMS programmé lié
* @param int $id_contact : L'id du contact lié
* @return int : Le nombre de lignes insérées
*/
public function createScheduleds_contacts($id_scheduled, $id_contact)
{
$query = '
INSERT INTO scheduleds_contacts(id_scheduled, id_contact)
VALUES (:id_scheduled, :id_contact)
';
$params = array(
'id_scheduled' => $id_scheduled,
'id_contact' => $id_contact,
);
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* Retourne tous les contacts pour un sms programmé donnée
* @param int $id_sms : L'id du sms
@ -904,27 +610,6 @@
/* PARTIE DES REQUETES SCHEDULEDS_NUMBERS */
/******************************************/
/**
* Créer un nouveau scheduleds_numbers
* @param int $id_scheduled : L'id du SMS programmé lié
* @param string $number : Le numéro de téléphone lié
* @return int : Le nombre de lignes insérées
*/
public function createScheduleds_numbers($id_scheduled, $number)
{
$query = '
INSERT INTO scheduleds_numbers(id_scheduled, number)
VALUES (:id_scheduled, :number)
';
$params = array(
'id_scheduled' => $id_scheduled,
'number' => $number,
);
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* Supprime tous les scheduleds_numbers pour un sms donné
* @param int $id_scheduled : L'id du sms pour lequel on doit supprimer les scheduleds_numbers
@ -968,27 +653,6 @@
/* PARTIE DES REQUETES SCHEDULEDS_GROUPS */
/*****************************************/
/**
* Créer un nouveau scheduleds_groups
* @param int $id_scheduled : L'id du SMS programmé lié
* @param int $id_group : L'id du group lié
* @return int : Le nombre de lignes insérées
*/
public function createScheduleds_groups($id_scheduled, $id_group)
{
$query = '
INSERT INTO scheduleds_groups(id_scheduled, id_group)
VALUES (:id_scheduled, :id_group)
';
$params = array(
'id_scheduled' => $id_scheduled,
'id_group' => $id_group,
);
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* Supprime tous les scheduleds_groups pour un sms donné
* @param int $id_scheduled : L'id du sms pour lequel on doit supprimer les scheduleds_groups
@ -1053,57 +717,6 @@
return $this->runQuery($query, $params, self::FETCH);
}
/**
* update un user
* @param int $id : L'id du user à modifier
* @param string $email : Le nouveau email du user
* @param string $password : Le nouveau password du user
* @param string $admin : Le nouveau statut admin du user
* @return void
*/
public function updateUser($id, $email, $password, $admin)
{
$query = '
UPDATE users
SET email = :email,
password = :password,
admin = :admin
WHERE id = :id
';
$params = array(
'id' => $id,
'email' => $email,
'password' => $password,
'admin' => $admin,
);
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* Insert un utilisateur
* @param string $email : L'adresse email du nouvel utilisateur
* @param string $password : Le mot de passe de l'utilisateur
* @param boolean $admin : Le statut de l'utilisateur
* @return int : le nombre d'utilisateurs ajoutés
*/
public function createUser($email, $password, $admin)
{
$query = '
INSERT INTO users(email, password, admin)
VALUES (:email, :password, :admin)
';
$params = array(
'email' => $email,
'password' => $password,
'admin' => $admin,
);
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* Supprime tous les users dont l'id fait partie du tableau fourni
* @param $users_ids : Tableau des id des users à supprimer
@ -1123,4 +736,47 @@
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/*********************************/
/* PARTIE DES REQUETES TRANSFERS */
/*********************************/
/**
* Change le statut des tranfers dont l'id est fourni dans $transfers_id
* @param array $transfers_ids = Tableau des id des transfers voulus
* @return int : Retourne le nombre de lignes mises à jour
*/
public function updateProgressTransfersIn($transfers_ids, $progress)
{
$query = "
UPDATE transfers
SET progress = :progress
WHERE id ";
//On génère la clause IN et les paramètres adaptés depuis le tableau des id
$generted_in = $this->generateInFromArray($transfers_ids);
$query .= $generted_in['QUERY'];
$params = $generted_in['PARAMS'];
$params['progress'] = (boolean)$progress;
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* Supprime tous les transfers dont l'id fait partie du tableau fourni
* @param $transfers_ids : Tableau des id des transfers à supprimer
* @return int : Nombre de lignes supprimées
*/
public function deleteTransfersIn($transfers_ids)
{
$query = "
DELETE FROM transfers
WHERE id ";
//On génère la clause IN et les paramètres adaptés depuis le tableau des id
$generted_in = $this->generateInFromArray($transfers_ids);
$query .= $generted_in['QUERY'];
$params = $generted_in['PARAMS'];
return $this->runQuery($query, $params, self::ROWCOUNT);
}
}

1
mvc/404.php Normal file
View file

@ -0,0 +1 @@
<h1>404 Not Found</h1>

View file

@ -53,7 +53,7 @@
$chemin_template = PWD_TEMPLATES . $template . '.php';
if(file_exists($chemin_template))
{
require_once($chemin_template);
require($chemin_template);
unset($chemin_template);
return true;
}
@ -65,19 +65,31 @@
* Cette fonction permet de générer une adresse URL interne au site
* @param string $controller : Nom du controleur à employer (par défaut vide)
* @param string $method : Nom de la méthode à employer (par défaut vide)
* @param string $params : Tableau des paramètres $_GET à employer au format 'nom' => valeur (par défaut array())
* @param string $params : Tableau des paramètres à passer à la fonction, sous forme de tableau, sans clefs
* @param string $getParams : Tableau des paramètres $_GET à employer au format 'nom' => valeur (par défaut array())
* @return string, Url générée
*/
protected function generateUrl($controller = '', $method = '', $params = array())
protected function generateUrl($controller = '', $method = '', $params = array(), $getParams = array())
{
$url = HTTP_PWD;
$url .= ($controller ? $controller . '/' : '');
$url .= ($method ? $method . '/' : '');
foreach ($params as $clef => $valeur)
//On ajoute les paramètres framework
foreach ($params as $valeur)
{
$url .= $clef . '_' . rawurlencode($valeur) . '/';
$url .= rawurlencode($valeur) . '/';
}
//On calcul puis ajoute les paramètres get
$paramsToJoins = array();
foreach ($getParams as $clef => $valeur)
{
$paramsToJoins[] = $clef . '=' . rawurlencode($valeur);
}
$url .= count($getParams) ? '?' . implode('&', $paramsToJoins) : '';
return $url;
}

View file

@ -29,20 +29,164 @@
$this->bdd = $bdd;
}
/*
Fonctions relatives aux informations de la base
*/
/**
* Cette fonction vérifie si une table existe
* @param string $table : Nom de la table
* @return mixed : Vrai si la table existe, faux sinon
*/
public function tableExist($table)
{
$tables = $this->getAllTables();
return in_array($table, $tables);
}
/**
* Cette fonction vérifie si un champs existe dans une table
* @param string $field : Nom du champ
* @param string $table : Nom de la table
* @return mixed : Vrai si le champs existe, faux, si le champs ou la table n'existe pas
*/
public function fieldExist($field, $table)
{
$fields = $this->getColumnsForTable($table);
$fields = $fields ? explode(', ', $fields) : array();
return in_array($field, $fields);
}
/**
* Cette requete retourne le dernier id inséré
* return int : le dernier id inséré
*/
public function lastId()
{
return $this->bdd->lastInsertId();
}
/**
* Cette fonction permet de retourner toutes les tables de la base
* @return array : La liste des tables
*/
public function getAllTables()
{
$query = 'SHOW TABLES';
$tables = $this->runQuery($query);
$tablesNames = array();
foreach ($tables as $table)
{
$tablesNames[] = array_values($table)[0];
}
return $tablesNames;
}
/**
* Cette fonction permet de récupérer la liste de toutes les colonnes d'une table de façon propre, appelable via MySQL. Cela permet de faire des requetes plus optimisée qu'avec "*"
* @param string $table : Nom de la table pour laquelle on veux les colonnes
* @param string $prefix : Le prefix que l'on veux devant les champs, utile pour les requetes avec jointures. Par défaut null => pas de prefix. A noter, en cas d'utilisation de prefix, les champs aurons un alias de la forme $prefix_$nom_champ
* @return boolean string : Tous les noms des colonnes liées par des ", ". Ex : 'id, nom, prenom". Si la table n'existe pas, on retourne false.
*/
public function getColumnsForTable($table, $prefix = null)
{
if ($this->tableExist($table))
{
$query = 'SHOW COLUMNS FROM ' . $table;
$datas = array();
$fields = $this->runQuery($query, $datas, self::FETCHALL);
$fieldsName = array();
foreach ($fields as $field)
{
$fieldsName[] = $prefix ? $prefix . '.' . $field['Field'] . ' AS ' . $prefix . '_' . $field['Field'] : $field['Field'];
}
return implode(', ', $fieldsName);
}
return false;
}
/**
* Cette fonction décrit une table et retourne un tableau sur cette description
* @param string $table : Le nom de la table a analyser
* @return mixed : Si la table existe un tableau la décrivant, sinon false
*/
public function describeTable($table)
{
if (!$this->tableExist($table))
{
return false;
}
//On recupere tous les champs pour pouvoir apres les analyser
$query = 'DESCRIBE ' . $table;
$fields = $this->runQuery($query);
$return = array();
foreach ($fields as $field)
{
$fieldInfo = array();
$fieldInfo['NULL'] = $field['Null'] == 'NO' ? false : true;
$fieldInfo['AUTO_INCREMENT'] = $field['Extra'] == 'auto_increment' ? true : false;
$fieldInfo['PRIMARY'] = $field['Key'] == 'PRI' ? true : false;
$fieldInfo['UNIQUE'] = $field['Key'] == 'UNI' ? true : false;
$fieldInfo['TYPE'] = mb_convert_case(preg_replace('#[^a-z]#ui', '', $field['Type']), MB_CASE_UPPER);
$fieldInfo['SIZE'] = filter_var($field['Type'], FILTER_SANITIZE_NUMBER_INT);
$fieldInfo['HAS_DEFAULT'] = $field['Default'] !== NULL ? true : false;
$fieldInfo['DEFAULT'] = $field['Default'];
$return[$field['Field']] = $fieldInfo;
}
return $return;
}
/**
* Cette fonction permet de compter le nombre de ligne d'une table
* @param string $table : Le nom de la table à compter
* @return mixed : Le nombre de ligne dans la table ou false si la table n'existe pas
*/
public function countTable ($table)
{
if (!$this->tableExist($table))
{
return false;
}
$query = "SELECT COUNT(*) as nb_lignes FROM " . $table;
$return = $this->runQuery($query, array(), self::FETCH);
return $return['nb_lignes'];
}
/*
Fonctions d'execution des requetes ou de génération
*/
/**
* Cette fonction joue une requete depuis une requete et un tableau d'argument
* @param string $query : Requete à jouer
* @param array $datas : Les données pour la requete. Si non fourni, vide par défaut.
* @param const $return_type : Type de retour à utiliser. (Voir les constantes de la classe Model ici présente). Par défaut FETCHALL
* @param const $fetch_mode : Le type de récupération a effectuer. Par défaut FETCH_ASSOC
* @param boolean $debug : Par défaut à faux, si vrai retourne les infos de débug de la requete
* @return mixed : Dépend du type spécifié dans $return_type
*/
public function runQuery($query, $datas = array(), $return_type = self::FETCHALL, $fetch_mode = PDO::FETCH_ASSOC)
public function runQuery($query, $datas = array(), $return_type = self::FETCHALL, $fetch_mode = PDO::FETCH_ASSOC, $debug = false)
{
$req = $this->bdd->prepare($query);
$req->setFetchMode($return_type);
$req->execute($datas);
if ($debug)
{
return $req->errorInfo();
}
switch ($return_type)
{
case self::NO :
@ -68,62 +212,6 @@
return $return;
}
/**
* Cette fonction vérifie si une table existe
* @param string $table : Nom de la table
* @return mixed : Vrai si la table existe, faux sinon
*/
public function tableExist($table)
{
$query = '
SHOW TABLES LIKE :table
';
$query_datas = array(
'table' => $table
);
$req = $this->bdd->prepare($query);
$req->execute($query_datas);
$result = $req->fetch();
if(count($result))
{
return true;
}
return false;
}
/**
* Cette fonction vérifie si un champs existe dans une table
* @param string $field : Nom du champ
* @param string $table : Nom de la table
* @return mixed : Vrai si le champs existe, faux, si le champs ou la table n'existe pas
*/
public function fieldExist($field, $table)
{
if($this->tableExist($table))
{
$query = '
SHOW COLUMNS FROM ' . $table . ' LIKE :field
';
$query_datas = array(
'field' => $field
);
$req = $this->bdd->prepare($query);
$req->execute($query_datas);
$result = $req->fetch();
if(count($result))
{
return true;
}
}
return false;
}
/**
* Cette fonction permet de récupérer les éléments necessaires à une requete 'IN' depuis un tableau php
* @param string $values : Tableau PHP des valeurs
@ -150,55 +238,49 @@
return $return;
}
/**
* Cette requete retourne le dernier id inséré
* return int : le dernier id inséré
/*
Fonctions de manipulations basiques des données
*/
public function lastId()
{
return $this->bdd->lastInsertId();
}
/**
* Cette fonction permet de récupérer la liste de toutes les colonnes d'une table de façon propre, appelable via MySQL. Cela permet de faire des requetes plus optimisée qu'avec "*"
* @param string $table : Nom de la table pour laquelle on veux les colonnes
* @return boolean string : Tous les noms des colonnes liées par des ", ". Ex : 'id, nom, prenom". Si la table n'existe pas, on retourne false.
*/
public function getColumnsForTable($table)
{
if ($this->tableExist($table))
{
$query = 'SHOW COLUMNS FROM ' . $table;
$datas = array();
$fields = $this->runQuery($query, $datas, self::FETCHALL);
$fieldsName = array();
foreach ($fields as $field)
{
$fieldsName[] = $field['Field'];
}
return implode(', ', $fieldsName);
}
return false;
}
/**
* Cette fonction permet de récupérer une table complète, éventuellement en la triant par une colonne, éventuellement en limitant le nombre de résultat, ou en sautant certains (notamment pour de la pagination)
* @param string $table : Le nom de la table a récupérer
* Cette fonction permet de récupérer des lignes en fonction de restrictions
* @param string $table : Le nom de la table dans laquelle on veux recuperer la ligne
* @param array $restrictions : Les restrictions que l'on veux appliquer
* @param string $order_by : Le nom de la colonne par laquelle on veux trier les résultats. Si non fourni, tri automatique
* @param string $desc : L'ordre de tri (asc ou desc). Si non défini, ordre par défaut (ASC)
* @param string $limit : Le nombre maximum de résultats à récupérer (par défaut pas le limite)
* @param string $offset : Le nombre de résultats à ignorer (par défaut pas de résultats ignorés)
* @return array : Tableau avec dans chaque case une ligne de la base
* @return mixed : False en cas d'erreur, sinon les lignes retournées
*/
public function getAll($table, $order_by = '', $desc = false, $limit = false, $offset = false)
public function getFromTableWhere($table, $restrictions = array(), $order_by = '', $desc = false, $limit = false, $offset = false)
{
if ($this->tableExist($table))
$restrictions = !is_array($restrictions) ? array() : $restrictions;
$fields = $this->describeTable($table);
if (!$fields)
{
$query = "SELECT " . $this->getColumnsForTable($table) . " FROM " . $table;
return false;
}
//On gère les restrictions
$wheres = array();
$params = array();
foreach ($restrictions as $label => $value)
{
//Si le champs pour la restriction n'existe pas on retourne false
if (!array_key_exists($label, $fields))
{
return false;
}
//On ajoute la restriction au WHERE
$params['where_' . $label] = $value;
$wheres[] = $label . ' = :where_' . $label . ' ';
}
$query = "SELECT " . $this->getColumnsForTable($table) . " FROM " . $table . " WHERE 1 " . (count($wheres) ? 'AND ' : '') . implode('AND ', $wheres);
if ($order_by)
{
@ -232,9 +314,166 @@
}
}
//On associe les paramètres
foreach ($params as $label => &$param)
{
$req->bindParam(':' . $label, $param);
}
$req->setFetchMode(PDO::FETCH_ASSOC);
$req->execute();
return $req->fetchAll();
}
/**
* Cette fonction permet de modifier les données d'une table pour un la clef primaire
* @param string $table : Le nom de la table dans laquelle on veux insérer des données
* @param string $primary : La clef primaire qui sert à identifier la ligne a modifier
* @param array $datas : Les données à insérer au format "champ" => "valeur"
* @param array $restrictions : Un tableau des restrictions à appliquer sous forme "champ" => "valeur". Par défaut un tableau vide
* @return mixed : False en cas d'erreur, sinon le nombre de lignes modifiées
*/
public function updateTableWhere ($table, $datas, $restrictions = array())
{
$fields = $this->describeTable($table);
if (!$fields)
{
return false;
}
$params = array();
$sets = array();
//On gère les set
foreach ($datas as $label => $value)
{
//Si le champs pour la nouvelle valeur n'existe pas on retourne false
if (!array_key_exists($label, $fields))
{
return false;
}
//Si le champs est Nullable est qu'on à reçu une chaine vide, on passe à null plutot qu'à chaine vide
if ($fields[$label]['NULL'] && $value === '')
{
$value = null;
}
$params['set_' . $label] = $value;
$sets[] = $label . ' = :set_' . $label . ' ';
}
//On gère les restrictions
$wheres = array();
foreach ($restrictions as $label => $value)
{
//Si le champs pour la restriction n'existe pas on retourne false
if (!array_key_exists($label, $fields))
{
return false;
}
//On ajoute la restriction au WHERE
$params['where_' . $label] = $value;
$wheres[] = $label . ' = :where_' . $label . ' ';
}
//On fabrique la requete
$query = "UPDATE " . $table . " SET " . implode(', ', $sets) . " WHERE 1 AND " . implode('AND ', $wheres);
//On retourne le nombre de lignes insérées
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* Cette fonction permet de supprimer des lignes d'une table en fonctions de restrictions
* @param string $table : Le nom de la table dans laquelle on veux supprimer la ligne
* @param array $restrictions : Les restrictions pour la suppression sous la forme "label" => "valeur"
* @return mixed : False en cas d'erreur, sinon le nombre de lignes supprimées
*/
public function deleteFromTableWhere($table, $restrictions = array())
{
$fields = $this->describeTable($table);
if (!$fields)
{
return false;
}
//On gère les restrictions
$wheres = array();
$params = array();
foreach ($restrictions as $label => $value)
{
//Si le champs pour la restriction n'existe pas on retourne false
if (!array_key_exists($label, $fields))
{
return false;
}
//On ajoute la restriction au WHERE
$params['where_' . $label] = $value;
$wheres[] = $label . ' = :where_' . $label . ' ';
}
$query = "DELETE FROM " . $table . " WHERE 1 AND " . implode('AND ', $wheres);
return $this->runQuery($query, $params, self::ROWCOUNT);
}
/**
* Cette fonction permet d'insérer des données dans une table
* @param string $table : Le nom de la table dans laquelle on veux insérer des données
* @param array $datas : Les données à insérer
* @return mixed : False en cas d'erreur, et le nombre de lignes insérées sinon
*/
public function insertIntoTable($table, $datas)
{
$fields = $this->describeTable($table);
if (!$fields)
{
return false;
}
$params = array();
$fieldNames = array();
//On s'assure davoir toutes les données, on evite les auto increment, on casse en cas de donnée absente
foreach ($fields as $nom => $field)
{
if ($field['AUTO_INCREMENT'])
{
continue;
}
//Si il manque un champs qui peux être NULL ou qu'il est rempli avec une chaine vide ou null, on passe au suivant
if ((!isset($datas[$nom]) || $datas[$nom] === NULL || $datas[$nom] === '') && $field['NULL'])
{
continue;
}
//Si il manque un champs qui a une valeur par défaut
if (!isset($datas[$nom]) && $field['HAS_DEFAULT'])
{
continue;
}
//Si il nous manque un champs
if (!isset($datas[$nom]))
{
return false;
}
$params[$nom] = $datas[$nom];
$fieldNames[] = $nom;
}
//On fabrique la requete
$query = "INSERT INTO " . $table . "(" . implode(', ', $fieldNames) . ") VALUES(:" . implode(', :', $fieldNames) . ")";
//On retourne le nombre de lignes insérées
return $this->runQuery($query, $params, self::ROWCOUNT);
}
}

View file

@ -68,6 +68,16 @@
$this->params = $value;
}
/**
* Cette méthode retourne la page 404 par défaut
*/
public function return404 ()
{
http_response_code(404);
include(PWD . 'mvc/404.php');
die();
}
/**
* Retourne une route avec seulement l'url parsée comme il faut
* @param string $route : La route à analyser
@ -77,12 +87,12 @@
{
$directory_to_remove = strstr(preg_replace('#http(s)?://#', '', HTTP_PWD), '/'); //On retire la partie protocole, et l'adresse du serveur de la partie de la route à ignorer
$route = mb_strcut($route, mb_strlen($directory_to_remove)); //On retire la partie à ignorer de la route
$route = preg_split('#[/?]#', $route); //On explose la route
$route = explode('?', $route)[0]; //on ne garde que ce qui précède les arguments
$route = preg_split('#[/]#', $route); //On explose la route
foreach($route as $key => $val) //On garde seulement les repertoires non vides
{
if(empty($val))
if(empty($val) && $val !== 0 && $val !== '0')
{
unset($route[$key]);
}
@ -100,17 +110,21 @@
public function parseController($route)
{
$route = $this->parseRoute($route); //On récupère la route parsé
//On lie le bon controlleur
if (empty($route[0]) || !file_exists(PWD_CONTROLLER . $route[0] . '.php') || mb_strpos($route[0], 'internal') !== false) //Si on a pas de premier parametre, ou qu'il ne correspond à aucun controlleur
//Si pas de controlleur, on prend celui par défaut
if (empty($route[0]))
{
$controllerName = DEFAULT_CONTROLLER; //On défini le nom du controlleur par défaut
}
else //Sinon, si tout est bon
{
$controllerName = $route[0]; //On défini le nom du controlleur
return DEFAULT_CONTROLLER;
}
return $controllerName;
//Sinon, si le controlleur n'existe pas ou est internal, on retourne une 404
if (!file_exists(PWD_CONTROLLER . $route[0] . '.php') || mb_strpos($route[0], 'internal') !== false)
{
return $this->return404();
}
//On retourne le controlleur adapté
return $route[0];
}
/**
@ -120,18 +134,69 @@
*/
public function parseMethod($route)
{
//On instancie le controlleur
$controllerName = $this->parseController($route);
require_once(PWD_CONTROLLER . $controllerName . '.php'); //On inclus le controlleur
$controller = new $controllerName();
$route = $this->parseRoute($route); //On récupère la route parsé
//On lie la bonne méthode
if (empty($route[1]) || !method_exists($controller, $route[1])) //Si on a pas de second parametre, ou qu'il ne correspond à aucune méthode du controlleur
$prefixMethod = '';
//On recupère les paramètres dans l'url pour les utiliser un peu plus tard
$params = $this->parseParams($route);
//On vérifie si le controlleur est un controlleur API, si c'est le cas on le refais avec cette fois la bonne methode
if ($controller instanceof ApiController)
{
$method = DEFAULT_METHOD; //On prend la méthode par défaut
//On va choisir le type à employer
$method = $_SERVER['REQUEST_METHOD'];
switch (mb_convert_case($method, MB_CASE_LOWER))
{
case 'delete' :
$prefixMethod = 'delete';
break;
case 'patch' :
$prefixMethod = 'patch';
break;
case 'post' :
$prefixMethod = 'post';
break;
case 'put' :
$prefixMethod = 'put';
break;
default :
$prefixMethod = 'get';
}
else //Sinon, si tout est bon
}
$route = $this->parseRoute($route); //On récupère la route parsé
//On regarde quelle route il nous faut et on evite les routes qui commencent par '_', qui sont maintenant considérées comme privées
if (empty($route[1]))
{
$method = $route[1]; //On défini la méthode appelée
$method = DEFAULT_METHOD;
}
else
{
$method = $route[1];
}
if ($prefixMethod)
{
$method = $prefixMethod . mb_convert_case($method, MB_CASE_TITLE);
}
//Si la méthode à appeler n'existe pas ou si la route commencent par '_', signe qu'elle est un outils non accessibles
if (!method_exists($controller, $method) || mb_substr($method, 0, 1) == '_')
{
return $this->return404();
}
//On instancie la classe reflection de PHP sur la méthode que l'on veux analyser pour l'objet controller
$methodAnalyser = new ReflectionMethod($controller, $method);
//Si la méthode à appeler demande plus de paramètres que fournis on retourne une 404
if ($methodAnalyser->getNumberOfRequiredParameters() > count($params))
{
return $this->return404();
}
return $method;
@ -146,48 +211,83 @@
{
$route = $this->parseRoute($route); //On récupère la route parsé
$params = array();
$already_use_params = array();
//On transforme les paramètres $_GET passés par l'url au format clef_value. Ex : prenom_pierre-lin = $_GET['prenom'] => 'pierre-lin'
//On transforme les paramètres $_GET passés par l'url au format clef-value. Ex : prenom-pierre-lin = $_GET['prenom'] => 'pierre-lin'
if (count($route) > 2) //Si on a plus de deux paramètres qui ont été passé
{
unset($route[0], $route[1]); //On supprime le controlleur, et la route, des paramètres, il ne reste que les parametres a passer en GET
foreach($route as $param) //On passe sur chaque paramètre a transformer en GET
foreach ($route as $param)
{
$param = explode('_', $param, 2); //On récupère le paramètre, via la délimiteur '_', en s'arretant au premier
//Si on a déjà utilisé cette variable GET
if (in_array($param[0], $already_use_params))
{
if (isset($params[$param[0]]))
{
$tmp_value = $params[$param[0]];
$params[$param[0]] = array($tmp_value);
unset($tmp_value);
}
$params[$param[0]][] = (isset($param[1])) ? rawurldecode($param[1]) : NULL;
}
else
{
$params[$param[0]] = (isset($param[1])) ? rawurldecode($param[1]) : NULL; //On définit la propriétée GET correspondante
$already_use_params[] = $param[0];
$params[] = rawurldecode($param);
}
}
}
return $params;
}
/**
* Cette fonction permet de vérifier si le cache est activé pour une route, et si oui quel fichier utiliser
* @param string $route : Route à analyser
* @return mixed : Si pas de cache, faux. Sinon un tableau avec deux clefs, "state" => statut du nom de fichier retourné (true, le fichier doit être utilisé, false, le fichier doit être créé), "file" => Le nom du fcihier de cache
*/
public function verifyCache($route)
{
//On récupère le nom du controller et de la méthode
$controllerName = $this->parseController($route);
$methodName = $this->parseMethod($route);
$params = $this->parseParams($route);
$controller = new $controllerName();
//Si on ne doit pas activer le cache ou si on na pas de cache pour ce fichier
if (!ACTIVATING_CACHE || !property_exists($controller, 'cache_' . $methodName))
{
return false;
}
//Si on a du cache, on va déterminer le nom approprié
//Format de nom = <hash:nom_router.nom_methode><hash_datas>
$hashName = md5($controllerName . $methodName);
$hashDatas = md5(json_encode($_GET) . json_encode($_POST) . json_encode($params));
$fileName = $hashName . $hashDatas;
//Si il n'existe pas de fichier de cache pour ce fichier
if (!file_exists(PWD_CACHE . $fileName))
{
return array('state' => false, 'file' => $fileName);
}
//Sinon, si le fichier de cache existe
$fileLastChange = filemtime(PWD_CACHE . $fileName);
//On calcul la date de mise à jour valide la plus ancienne possible
$now = new DateTime();
$propertyName = 'cache_' . $methodName;
$propertyValue = $controller->$propertyName;
$now->sub(new DateInterval('PT' . $propertyValue . 'M'));
$maxDate = $now->format('U');
//Si le fichier de cache est trop vieux
if ($fileLastChange < $maxDate)
{
return array('state' => false, 'file' => $fileName);
}
//Sinon, on retourne le fichier de cache en disant de l'utiliser
return array('state' => true, 'file' => $fileName);
}
/**
* Cette fonction permet de charger la page adaptée a partir d'une url
* Elle gère également le cache
* @param string $route : Route à analyser pour charger une page
* @return void
*/
public function loadRoute($route)
{
$_GET = array_merge($_GET, $this->parseParams($route)); //On fusionne les paramètres GET et ceux passés dans la route du controller
$params = $this->parseParams($route); //On récupère les paramètres à passer à la fonction
$controllerName = $this->parseController($route); //On récupère le nom du controleur à appeler
$controller = new $controllerName(); //On créer le controleur
$beforeMethodName = DEFAULT_BEFORE; //On défini le nom de la fonction before
if (method_exists($controller, $beforeMethodName)) //Si une fonction before existe pour ce controller, on l'appel
{
@ -195,7 +295,27 @@
}
$methodName = $this->parseMethod($route); //On récupère le nom de la méthode
$controller->$methodName(); //On appel la méthode
$verifyCache = $this->verifyCache($route);
//Si on ne doit pas utiliser de cache
if ($verifyCache === false)
{
call_user_func_array(array($controller, $methodName), $params); //On appel la methode, en lui passant les arguments necessaires
return null;
}
//Si on doit utiliser un cache avec un nouveau fichier
if ($verifyCache['state'] == false)
{
//On créer le fichier avec le contenu adapté
ob_start();
call_user_func_array(array($controller, $methodName), $params); //On appel la methode, en lui passant les arguments necessaires
$content = ob_get_contents();
file_put_contents(PWD_CACHE . $verifyCache['file'], $content);
ob_end_clean();
}
//On utilise le fichier de cache
readfile(PWD_CACHE . $verifyCache['file']);
}
}

View file

@ -9,6 +9,8 @@
*/
function autoloader($class)
{
$class = str_replace('\\', '/', $class); #Gestion des namespaces
if (file_exists(PWD_CONTROLLER . $class . '.php'))
{
require_once(PWD_CONTROLLER . $class . '.php');
@ -17,6 +19,10 @@
{
require_once(PWD_MODEL . $class . '.php');
}
else if (file_exists(PWD . 'mvc/modules/' . $class . '.php'))
{
require_once(PWD . 'mvc/modules/' . $class . '.php');
}
}
spl_autoload_register('autoloader');

View file

@ -1,9 +1,9 @@
<?php
//CETTE PAGE GERE LA CONNEXION A LA BASE DE DONNEES
$host = 'localhost';
$dbname = 'raspisms';
$user = 'root';
$password = 'DATABASE_PASSWORD';
$host = DATABASE_HOST;
$dbname = DATABASE_NAME;
$user = DATABASE_USER;
$password = DATABASE_PASSWORD;
try
{

View file

@ -31,3 +31,18 @@
//Réglages des logs
define('LOG_ACTIVATED', 1); //On active les logs
//Réglages du cache
define('ACTIVATING_CACHE', false); //On desactive le cache
//Réglages divers
define('WEBSITE_TITLE', 'RaspiSMS'); //Le titre du site
define('WEBSITE_DESCRIPTION', ''); //Description du site
define('WEBSITE_KEYWORDS', ''); //Mots clefs du site
define('WEBSITE_AUTHOR', 'Raspbian-France'); //Auteur du site
//Réglages des identifiants de base de données
define('DATABASE_HOST', 'localhost'); //Hote de la bdd
define('DATABASE_NAME', 'raspisms'); //Nom de la bdd
define('DATABASE_USER', 'root'); //Utilisateur de la bdd
define('DATABASE_PASSWORD', ''); //Password de l'utilisateur

View file

@ -8,7 +8,7 @@
ARGUMENTS :
Obligatoires :
- string &$text_source : Une variable passé par référence qui sera utilisé comme texte source
- string $text_source : Une variable qui sera utilisé comme texte source
Optionnels :
- boolean $no_nl2br : Par défaut à faux -> les retours à la lignes sont transformé en <br/>. A vrai -> ils sont conservés tels quels
- boolean $escape_quotes : Par défaut à faux -> les guillemets ne sont pas échappés. A vrai -> ils sont transformés en entitées HTML
@ -17,7 +17,7 @@
RETOUR : Cette fonction retourne le texte transformé en cas de success, false sinon
*/
function secho(&$text_source, $no_nl2br = false, $escape_quotes = false, $authorize_null = true) //On utilise une reference, si la variable n'existe pas, ça ne lévera pas d'erreur
function secho($text_source, $no_nl2br = false, $escape_quotes = false, $authorize_null = true) //On utilise une reference, si la variable n'existe pas, ça ne lévera pas d'erreur
{
if ($authorize_null) //Si on les variables null, false ou '' doivent être prises comme définies
{

View file

@ -37,7 +37,7 @@
<h3 class="panel-title"><i class="fa fa-terminal fa-fw"></i> Ajout d'une nouvelle commande</h3>
</div>
<div class="panel-body">
<form action="<?php echo $this->generateUrl('commands', 'create', array('csrf' => $_SESSION['csrf']));?>" method="POST">
<form action="<?php echo $this->generateUrl('commands', 'create', [$_SESSION['csrf']]);?>" method="POST">
<div class="form-group">
<label>Nom commande</label>
<div class="form-group">

View file

@ -72,8 +72,8 @@
<div class="btn-group action-dropdown" target="#table-commands">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">Action pour la sélection <span class="caret"></span></button>
<ul class="dropdown-menu pull-right" role="menu">
<li><a href="<?php echo $this->generateUrl('commands', 'edit', array('csrf' => $_SESSION['csrf'])); ?>"><span class="fa fa-edit"></span> Modifier</a></li>
<li><a href="<?php echo $this->generateUrl('commands', 'delete', array('csrf' => $_SESSION['csrf'])); ?>"><span class="fa fa-trash-o"></span> Supprimer</a></li>
<li><a href="<?php echo $this->generateUrl('commands', 'edit', [$_SESSION['csrf']]); ?>"><span class="fa fa-edit"></span> Modifier</a></li>
<li><a href="<?php echo $this->generateUrl('commands', 'delete', [$_SESSION['csrf']]); ?>"><span class="fa fa-trash-o"></span> Supprimer</a></li>
</ul>
</div>
</div>
@ -96,7 +96,7 @@
var url = jQuery(this).attr('href');
jQuery(target).find('input:checked').each(function ()
{
url += '/command' + jQuery(this).val() + '_' + jQuery(this).val();
url += '/' + jQuery(this).val();
});
window.location = url;
});

View file

@ -37,7 +37,7 @@
<h3 class="panel-title"><i class="fa fa-edit fa-fw"></i>Modification de commandes</h3>
</div>
<div class="panel-body">
<form action="<?php echo $this->generateUrl('commands', 'update', array('csrf' => $_SESSION['csrf']));?>" method="POST">
<form action="<?php echo $this->generateUrl('commands', 'update', [$_SESSION['csrf']]);?>" method="POST">
<?php
foreach ($commands as $command)
{

View file

@ -28,5 +28,4 @@
</div>
</div>
<?php
include_once(PWD . 'mvc/pingback.php');
$incs->footer();

View file

@ -37,7 +37,7 @@
<h3 class="panel-title"><i class="fa fa-user fa-fw"></i> Ajout d'un contact</h3>
</div>
<div class="panel-body">
<form action="<?php echo $this->generateUrl('contacts', 'create', array('csrf' => $_SESSION['csrf']));?>" method="POST">
<form action="<?php echo $this->generateUrl('contacts', 'create', [$_SESSION['csrf']]);?>" method="POST">
<div class="form-group">
<label>Nom contact</label>
<div class="form-group input-group">
@ -49,7 +49,7 @@
<label>Numéro de téléphone du contact</label>
<div class="form-group input-group">
<span class="input-group-addon"><span class="fa fa-phone"></span></span>
<input name="phone" class="form-control" type="text" placeholder="Numéro du contact" pattern="0[1-9]([0-9] ?){8}" required>
<input name="phone" class="form-control" type="text" placeholder="Numéro du contact" pattern="(0|\+[1-9]{1,3}|\+1\-[0-9]{3})[1-9][0-9]{8}" required>
</div>
</div>
<a class="btn btn-danger" href="<?php echo $this->generateUrl('contacts'); ?>">Annuler</a>

View file

@ -70,8 +70,8 @@
<div class="btn-group action-dropdown" target="#table-contacts">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">Action pour la sélection <span class="caret"></span></button>
<ul class="dropdown-menu pull-right" role="menu">
<li><a href="<?php echo $this->generateUrl('contacts', 'edit', array('csrf' => $_SESSION['csrf'])); ?>"><span class="fa fa-edit"></span> Modifier</a></li>
<li><a href="<?php echo $this->generateUrl('contacts', 'delete', array('csrf' => $_SESSION['csrf'])); ?>"><span class="fa fa-trash-o"></span> Supprimer</a></li>
<li><a href="<?php echo $this->generateUrl('contacts', 'edit', [$_SESSION['csrf']]); ?>"><span class="fa fa-edit"></span> Modifier</a></li>
<li><a href="<?php echo $this->generateUrl('contacts', 'delete', [$_SESSION['csrf']]); ?>"><span class="fa fa-trash-o"></span> Supprimer</a></li>
</ul>
</div>
</div>
@ -94,7 +94,7 @@
var url = jQuery(this).attr('href');
jQuery(target).find('input:checked').each(function ()
{
url += '/contacts' + jQuery(this).val() + '_' + jQuery(this).val();
url += '/' + jQuery(this).val();
});
window.location = url;
});

View file

@ -37,7 +37,7 @@
<h3 class="panel-title"><i class="fa fa-edit fa-fw"></i> Modification de contacts</h3>
</div>
<div class="panel-body">
<form action="<?php echo $this->generateUrl('contacts', 'update', array('csrf' => $_SESSION['csrf']));?>" method="POST">
<form action="<?php echo $this->generateUrl('contacts', 'update', [$_SESSION['csrf']]);?>" method="POST">
<?php
foreach ($contacts as $contact)
{
@ -53,7 +53,7 @@
<label>Numéro de téléphone du contact</label>
<div class="form-group input-group">
<span class="input-group-addon"><span class="fa fa-phone"></span></span>
<input name="contacts[<?php secho($contact['id']); ?>][phone]" class="form-control" type="text" placeholder="Numéro du contact" pattern="0[1-9]([0-9] ?){8}" required value="<?php secho($contact['number']); ?>">
<input name="contacts[<?php secho($contact['id']); ?>][phone]" class="form-control" type="text" placeholder="Numéro du contact" pattern="(0|\+[1-9]{1,3}|\+1\-[0-9]{3})[1-9][0-9]{8}" required value="<?php secho($contact['number']); ?>">
</div>
</div>
<hr/>

View file

@ -0,0 +1,68 @@
<?php
//Template dashboard
$incs = new internalIncs();
$incs->head('Discussions - Show All');
?>
<div id="wrapper">
<?php
$incs->nav('discussions');
?>
<div id="page-wrapper">
<div class="container-fluid">
<!-- Page Heading -->
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">
Dashboard <small>Discussions</small>
</h1>
<ol class="breadcrumb">
<li>
<i class="fa fa-dashboard"></i> <a href="<?php echo $this->generateUrl('dashboard'); ?>">Dashboard</a>
</li>
<li class="active">
<i class="fa fa-comments-o"></i> Discussions
</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-comments-o fa-fw"></i> Liste des discussions</h3>
</div>
<div class="panel-body">
<div class="table-responsive">
<table class="table table-bordered table-hover table-striped" id="table-discussions">
<thead>
<tr>
<th>Date du dernier message</th>
<th>Numéro</th>
</tr>
</thead>
<tbody>
<?php
foreach ($discussions as $discussion)
{
?>
<tr class="goto" url="<?php secho($this->generateUrl('discussions', 'show', [$discussion['number']])); ?>">
<td><?php secho($discussion['at']); ?></td>
<td><?php secho(isset($discussion['contact']) ? $discussion['contact'] . ' (' . $discussion['number'] . ')' : $discussion['number']); ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<?php
$incs->footer();

134
templates/discussions/show.php Executable file
View file

@ -0,0 +1,134 @@
<?php
//Template dashboard
$incs = new internalIncs();
$incs->head('Discussions - Show All');
?>
<div id="wrapper">
<?php
$incs->nav('discussions');
?>
<div id="page-wrapper">
<div class="container-fluid">
<!-- Page Heading -->
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">
Discussion <small><?php secho($contact ? $contact . ' (' . $number . ')' : $number); ?></small>
</h1>
<ol class="breadcrumb">
<li>
<i class="fa fa-dashboard"></i> <a href="<?php echo $this->generateUrl('dashboard'); ?>">Dashboard</a>
</li>
<li>
<i class="fa fa-comments-o"></i> <a href="<?php echo $this->generateUrl('discussions'); ?>">Discussions</a>
</li>
<li class="active">
<?php secho($number); ?>
</li>
</ol>
</div>
</div>
<!-- /.row -->
<div class="row">
<div class="col-lg-12 discussion-container">
<div class="text-center"><i class="fa fa-spinner fa-spin"></i></div>
</div>
<div class="col-lg-12 message-input-container">
<div class="discussion-message message-input">
<form class="send-message-discussion" action="<?php secho($this->generateUrl('discussions', 'send', [$_SESSION['csrf']])); ?>" method="POST">
<textarea name="content" placeholder="Envoyer un message..."></textarea>
<input type="hidden" name="numbers[]" value="<?php secho($number); ?>" />
<button class="btn" ><span class="fa fa-fw fa-send-o"></span> Envoyer</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
jQuery(document).ready(function () {
/**
* Cette fonction vérifie régulièrement les sms pour mettre à jour l'affichage
*/
function getmessages ()
{
ajaxTransactionId = Date.now();
jQuery.getJSON(HTTP_PWD + "/discussions/getmessages/<?php echo htmlspecialchars(urlencode($number)); ?>/" + ajaxTransactionId , function( data ) {
if (data.transactionId != ajaxTransactionId)
{
return false;
}
jQuery('.discussion-container').html('');
$.each(data.messages, function(key, message) {
switch (message.type)
{
case 'received' :
var texte = '' +
'<div class="clearfix message-container">' +
'<div class="discussion-message message-received">' +
'<div class="discussion-message-text">' + message.text + '</div>' +
'<div class="discussion-message-date">' + message.date + '</div>' +
'</div>' +
'</div>';
break;
case 'sended' :
var texte = '' +
'<div class="clearfix message-container">' +
'<div class="discussion-message message-sended">' +
'<div class="discussion-message-text">' + message.text + '</div>' +
'<div class="discussion-message-date">' + message.date + '</div>' +
'</div>' +
'</div>';
break;
case 'inprogress' :
var texte = '' +
'<div class="clearfix message-container">' +
'<div class="discussion-message message-sended">' +
'<div class="message-in-progress-hover"><i class="fa fa-spinner fa-spin"></i></div>' +
'<div class="discussion-message-text">' + message.text + '</div>' +
'<div class="discussion-message-date">' + message.date + '</div>' +
'</div>' +
'</div>';
break;
default :
var texte = '';
break;
}
jQuery('.discussion-container').append(texte);
});
scrollDownDiscussion();
});
}
/**
* Cette fonction permet de fixer la taille de la fenetre de discussion
*/
function fullHeightDiscussion()
{
var containerPosition = jQuery('.discussion-container').position();
var windowHeight = jQuery(window).height();
var messageInputContainer = jQuery('.message-input-container').outerHeight();
var footerHeight = jQuery('footer').outerHeight();
var containerHeight = Math.floor(windowHeight - (containerPosition.top + footerHeight * 2 + messageInputContainer));
jQuery('.discussion-container').outerHeight(containerHeight);
}
fullHeightDiscussion();
jQuery(window).on('resize', function () {
fullHeightDiscussion();
});
var getmessagesInterval = setInterval(getmessages, 2500);
});
</script>
<?php
$incs->footer();

View file

@ -37,7 +37,7 @@
<h3 class="panel-title"><i class="fa fa-group fa-fw"></i> Ajout d'un groupe</h3>
</div>
<div class="panel-body">
<form action="<?php echo $this->generateUrl('groups', 'create', array('csrf' => $_SESSION['csrf']));?>" method="POST">
<form action="<?php echo $this->generateUrl('groups', 'create', [$_SESSION['csrf']]);?>" method="POST">
<div class="form-group">
<label>Nom du groupe</label>
<div class="form-group input-group">

View file

@ -71,7 +71,7 @@
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">Action pour la sélection <span class="caret"></span></button>
<ul class="dropdown-menu pull-right" role="menu">
<li><a href="<?php echo $this->generateUrl('groups', 'edit'); ?>"><span class="fa fa-edit"></span> Modifier</a></li>
<li><a href="<?php echo $this->generateUrl('groups', 'delete', array('csrf' => $_SESSION['csrf'])); ?>"><span class="fa fa-trash-o"></span> Supprimer</a></li>
<li><a href="<?php echo $this->generateUrl('groups', 'delete', [$_SESSION['csrf']]); ?>"><span class="fa fa-trash-o"></span> Supprimer</a></li>
</ul>
</div>
</div>
@ -94,7 +94,7 @@
var url = jQuery(this).attr('href');
jQuery(target).find('input:checked').each(function ()
{
url += '/groups' + jQuery(this).val() + '_' + jQuery(this).val();
url += '/' + jQuery(this).val();
});
window.location = url;
});

View file

@ -37,7 +37,7 @@
<h3 class="panel-title"><i class="fa fa-edit fa-fw"></i> Modification de groupes</h3>
</div>
<div class="panel-body">
<form action="<?php echo $this->generateUrl('groups', 'update', array('csrf' => $_SESSION['csrf']));?>" method="POST">
<form action="<?php echo $this->generateUrl('groups', 'update', [$_SESSION['csrf']]);?>" method="POST">
<?php
foreach ($groups as $group)
{

View file

@ -15,6 +15,10 @@
<link href="<?php echo HTTP_PWD; ?>font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">
<!-- Custom CSS site -->
<link href="<?php echo HTTP_PWD; ?>css/style.css" rel="stylesheet">
<?php
$incs = new internalIncs();
$incs->phptojs();
?>
<script src="<?php echo HTTP_PWD; ?>js/jquery.js"></script>
<script src="<?php echo HTTP_PWD; ?>js/bootstrap.min.js"></script>
<script src="<?php echo HTTP_PWD; ?>js/plugins/morris/raphael.min.js"></script>
@ -58,3 +62,4 @@
</script>
</head>
<body>
<div class="popup-alerts-container"></div>

View file

@ -34,6 +34,9 @@
<li <?php echo $page == 'scheduleds' ? 'class="active"' : ''; ?>>
<a href="<?php echo $this->generateUrl('scheduleds'); ?>"><i class="fa fa-fw fa-envelope"></i> SMS</a>
</li>
<li <?php echo $page == 'discussions' ? 'class="active"' : ''; ?>>
<a href="<?php echo $this->generateUrl('discussions'); ?>"><i class="fa fa-fw fa-comments"></i> Discussions</a>
</li>
<li <?php echo $page == 'commands' ? 'class="active"' : ''; ?>>
<a href="<?php echo $this->generateUrl('commands'); ?>"><i class="fa fa-fw fa-terminal"></i> Commandes</a>
</li>

View file

@ -0,0 +1,3 @@
<script>
var HTTP_PWD = '<?php echo addslashes(HTTP_PWD); ?>';
</script>

View file

@ -49,7 +49,7 @@
<h4 class="panel-title"><i class="fa fa-key fa-fw"></i> Modifier mot de passe</h4>
</div>
<div class="panel-body">
<form action="<?php echo $this->generateUrl('profile', 'changePassword', array('csrf' => $_SESSION['csrf'])); ?>" method="POST">
<form action="<?php echo $this->generateUrl('profile', 'changePassword', [$_SESSION['csrf']]); ?>" method="POST">
<div class="form-group">
<label>Mot de passe :</label>
<input name="password" type="password" class="form-control" placeholder="Nouveau mot de passe" />
@ -64,6 +64,23 @@
</form>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title"><i class="fa fa-trash-o fa-fw"></i> Supprimer ce compte</h4>
</div>
<div class="panel-body">
<form action="<?php echo $this->generateUrl('profile', 'delete', [$_SESSION['csrf']]); ?>" method="POST">
<div class="checkbox">
<label>
<input name="delete_account" type="checkbox" value="1" /> Je suis totalement sûr de vouloir supprimer ce compte
</label>
</div>
<div class="text-center">
<button class="btn btn-danger">Supprimer ce compte</button>
</div>
</form>
</div>
</div>
</div>
<div class="col-xs-12 col-md-6">
<div class="panel panel-default">
@ -71,7 +88,7 @@
<h4 class="panel-title"><i class="fa fa-at fa-fw"></i> Modifier e-mail</h4>
</div>
<div class="panel-body">
<form action="<?php echo $this->generateUrl('profile', 'changeEmail', array('csrf' => $_SESSION['csrf'])); ?>" method="POST">
<form action="<?php echo $this->generateUrl('profile', 'changeEmail', [$_SESSION['csrf']]); ?>" method="POST">
<div class="form-group">
<label>Adresse e-mail :</label>
<input name="mail" type="email" class="form-control" placeholder="Nouvelle adresse e-mail" />
@ -88,17 +105,19 @@
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title"><i class="fa fa-trash-o fa-fw"></i> Supprimer ce compte</h4>
<h4 class="panel-title"><i class="fa fa-share fa-fw"></i> Transfert des SMS par e-mail</h4>
</div>
<div class="panel-body">
<form action="<?php echo $this->generateUrl('profile', 'delete', array('csrf' => $_SESSION['csrf'])); ?>" method="POST">
<div class="checkbox">
<label>
<input name="delete_account" type="checkbox" value="1" /> Je suis totalement sûr de vouloir supprimer ce compte
</label>
<form action="<?php echo $this->generateUrl('profile', 'changeTransfer', [$_SESSION['csrf']]); ?>" method="POST">
<div class="form-group">
<label>Transfert activé : </label>
<select name="transfer" class="form-control">
<option value="0">Non</option>
<option value="1" <?php echo $_SESSION['transfer'] ? 'selected' : ''; ?>>Oui</option>
</select>
</div>
<div class="text-center">
<button class="btn btn-danger">Supprimer ce compte</button>
<button class="btn btn-success">Mettre à jour les données</button>
</div>
</form>
</div>
@ -121,7 +140,7 @@
var url = jQuery(this).attr('href');
jQuery(target).find('input:checked').each(function ()
{
url += '/users' + jQuery(this).val() + '_' + jQuery(this).val();
url += '/' + jQuery(this).val();
});
window.location = url;
});

View file

@ -37,7 +37,7 @@
<h3 class="panel-title"><i class="fa fa-calendar fa-fw"></i> Ajout d'un SMS programmé</h3>
</div>
<div class="panel-body">
<form action="<?php echo $this->generateUrl('scheduleds', 'create', array('csrf' => $_SESSION['csrf']));?>" method="POST">
<form action="<?php echo $this->generateUrl('scheduleds', 'create', [$_SESSION['csrf']]);?>" method="POST">
<div class="form-group">
<label>Texte du SMS</label>
<textarea name="content" class="form-control" required></textarea>
@ -73,7 +73,7 @@
{
jQuery('.form-datetime').datetimepicker(
{
format: 'yyyy-mm-dd hh:ii',
format: 'yyyy-mm-dd hh:ii:ss',
autoclose: true,
minuteStep: 1,
language: 'fr'

View file

@ -52,7 +52,7 @@
<tr>
<td><?php secho($scheduled['id']); ?></td>
<td><?php secho($scheduled['at']); ?></td>
<td><?php secho($scheduled['content']); ?>...</td>
<td><?php secho($scheduled['content']); ?></td>
<td><input type="checkbox" value="<?php secho($scheduled['id']); ?>"></td>
</tr>
<?php
@ -71,7 +71,7 @@
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">Action pour la sélection <span class="caret"></span></button>
<ul class="dropdown-menu pull-right" role="menu">
<li><a href="<?php echo $this->generateUrl('scheduleds', 'edit'); ?>"><span class="fa fa-edit"></span> Modifier</a></li>
<li><a href="<?php echo $this->generateUrl('scheduleds', 'delete', array('csrf' => $_SESSION['csrf'])); ?>"><span class="fa fa-trash-o"></span> Supprimer</a></li>
<li><a href="<?php echo $this->generateUrl('scheduleds', 'delete', [$_SESSION['csrf']]); ?>"><span class="fa fa-trash-o"></span> Supprimer</a></li>
</ul>
</div>
</div>
@ -94,7 +94,7 @@
var url = jQuery(this).attr('href');
jQuery(target).find('input:checked').each(function ()
{
url += '/scheduleds' + jQuery(this).val() + '_' + jQuery(this).val();
url += '/' + jQuery(this).val();
});
window.location = url;
});

View file

@ -37,7 +37,7 @@
<h3 class="panel-title"><i class="fa fa-edit fa-fw"></i> Modification des SMS programmés</h3>
</div>
<div class="panel-body">
<form action="<?php echo $this->generateUrl('scheduleds', 'update', array('csrf' => $_SESSION['csrf']));?>" method="POST">
<form action="<?php echo $this->generateUrl('scheduleds', 'update', [$_SESSION['csrf']]);?>" method="POST">
<?php
foreach ($scheduleds as $scheduled)
{
@ -102,7 +102,7 @@
{
jQuery('.form-datetime').datetimepicker(
{
format: 'yyyy-mm-dd hh:ii',
format: 'yyyy-mm-dd hh:ii:ss',
autoclose: true,
minuteStep: 1,
language: 'fr'

View file

@ -37,7 +37,7 @@
<h3 class="panel-title"><i class="fa fa-user fa-fw"></i> Ajout d'un utilisateur</h3>
</div>
<div class="panel-body">
<form action="<?php echo $this->generateUrl('users', 'create', array('csrf' => $_SESSION['csrf']));?>" method="POST">
<form action="<?php echo $this->generateUrl('users', 'create', [$_SESSION['csrf']]);?>" method="POST">
<div class="form-group">
<label>Adresse e-mail</label>
<div class="form-group input-group">

View file

@ -70,7 +70,7 @@
<div class="btn-group action-dropdown" target="#table-users">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">Action pour la sélection <span class="caret"></span></button>
<ul class="dropdown-menu pull-right" role="menu">
<li><a href="<?php echo $this->generateUrl('users', 'delete', array('csrf' => $_SESSION['csrf'])); ?>"><span class="fa fa-trash-o"></span> Supprimer</a></li>
<li><a href="<?php echo $this->generateUrl('users', 'delete', [$_SESSION['csrf']]); ?>"><span class="fa fa-trash-o"></span> Supprimer</a></li>
</ul>
</div>
</div>
@ -93,7 +93,7 @@
var url = jQuery(this).attr('href');
jQuery(target).find('input:checked').each(function ()
{
url += '/users' + jQuery(this).val() + '_' + jQuery(this).val();
url += '/' + jQuery(this).val();
});
window.location = url;
});