diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..75e3d6e --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +#On force les retours UNIX +text eol=lf diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/controllers/commands.php b/controllers/commands.php index a88c388..5b21da8 100755 --- a/controllers/commands.php +++ b/controllers/commands.php @@ -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')); } } diff --git a/controllers/connect.php b/controllers/connect.php index d00dff1..2ce7f2b 100755 --- a/controllers/connect.php +++ b/controllers/connect.php @@ -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,32 +33,32 @@ //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['connect'] = true; - $_SESSION['admin'] = $user['admin']; - $_SESSION['email'] = $user['email']; - $_SESSION['csrf'] = str_shuffle(uniqid().uniqid()); - header('Location: ' . $this->generateUrl('')); - return true; - } - - header('Location: ' . $this->generateUrl('connect', 'login', array( - 'errormessage' => 'Identifiants incorrects.' - ))); + $_SESSION['errormessage'] = 'Identifiants incorrects.'; + header('Location: ' . $this->generateUrl('connect', 'login')); return false; } - header('Location: ' . $this->generateUrl('connect', 'login', array( - 'errormessage' => 'Cet e-mail n\'existe pas.' - ))); - 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; } /** @@ -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])) { - $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)) - { - $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; - } - } - - header('Location: ' . $this->generateUrl('connect', 'forgetPassword', array( - 'errormessage' => 'Impossible d\'envoyer les nouveaux identifiants.' - ))); + $_SESSION['errormessage'] = 'Cet e-mail n\'existe pas.'; + header('Location: ' . $this->generateUrl('connect', 'forgetPassword')); return false; } - header('Location: ' . $this->generateUrl('connect', 'forgetPassword', array( - 'errormessage' => 'Cet e-mail n\'existe pas.' - ))); - 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)) + { + $_SESSION['errormessage'] = 'Impossible d\'envoyer les nouveaux identifiants.'; + header('Location: ' . $this->generateUrl('connect', 'forgetPassword')); + return false; + } + + $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; + } + + $_SESSION['successmessage'] = 'Un nouveau mot de passe vous a été envoyé par mail.'; + header('Location: ' . $this->generateUrl('connect', 'login')); + return true; + } /** diff --git a/controllers/contacts.php b/controllers/contacts.php index 7d7e21b..5800a7e 100755 --- a/controllers/contacts.php +++ b/controllers/contacts.php @@ -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); - header('Location: ' . $this->generateUrl('contacts')); + $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 (!$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; - } - - header('Location: ' . $this->generateUrl('contacts', 'add', array( - 'errormessage' => 'Impossible créer ce contact.' - ))); - return true; + $_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' => 'Numéro de téléphone incorrect.' - ))); + if (!$db->insertIntoTable('contacts', ['name' => $nom, 'number' => $phone])) + { + $_SESSION['errormessage'] = 'Impossible créer ce contact.'; + header('Location: ' . $this->generateUrl('contacts', 'add')); + return false; + } + + $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')); } } diff --git a/controllers/dashboard.php b/controllers/dashboard.php index cfef016..475d6c0 100755 --- a/controllers/dashboard.php +++ b/controllers/dashboard.php @@ -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, diff --git a/controllers/discussions.php b/controllers/discussions.php new file mode 100755 index 0000000..d1be75c --- /dev/null +++ b/controllers/discussions.php @@ -0,0 +1,235 @@ +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); + } + } diff --git a/controllers/events.php b/controllers/events.php index a8e0c87..8b4f431 100755 --- a/controllers/events.php +++ b/controllers/events.php @@ -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, diff --git a/controllers/groups.php b/controllers/groups.php index 59d9406..cfa24f5 100755 --- a/controllers/groups.php +++ b/controllers/groups.php @@ -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); - header('Location: ' . $this->generateUrl('groups')); + $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])) { - $id_group = $db->lastId(); - $db->createEvent('GROUP_ADD', 'Ajout du groupe : ' . $nom); - foreach ($_POST['contacts'] as $id_contact) - { - $db->createGroups_contacts($id_group, $id_contact); - } - - header('Location: ' . $this->generateUrl('groups', 'showAll', array( - 'successmessage' => 'Le groupe a bien été créé.' - ))); - - return true; + $_SESSION['errormessage'] = 'Impossible de créer ce groupe.'; + header('Location: ' . $this->generateUrl('groups')); + return false; } - header('Location: ' . $this->generateUrl('groups', 'showAll', array( - 'errormessage' => 'Impossible de créer ce groupe.' - ))); + $id_group = $db->lastId(); + $db->insertIntoTable('events', ['type' => 'GROUP_ADD', 'text' => 'Ajout du groupe : ' . $nom]); + + foreach ($_POST['contacts'] as $id_contact) + { + $db->insertIntoTable('groups_contacts', ['id_group' => $id_group, 'id_contact' => $id_contact]); + } + + $_SESSION['successmessage'] = 'Le groupe a bien été créé.'; + header('Location: ' . $this->generateUrl('groups')); + return true; } /** * 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')); } } diff --git a/controllers/internalConsole.php b/controllers/internalConsole.php index 5755367..57d7934 100755 --- a/controllers/internalConsole.php +++ b/controllers/internalConsole.php @@ -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,86 +76,93 @@ //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'); - $now = new DateTime(); - $now = $now->format('Y-m-d H:i:s'); + echo "Début de l'envoi des SMS programmés\n"; - echo "Début de l'envoi des SMS programmés\n"; + $scheduleds = $db->getScheduledsNotInProgressBefore($now); - $scheduleds = $db->getScheduledsNotInProgressBefore($now); + $ids_scheduleds = array(); - $ids_scheduleds = array(); - - //On passe en cours de progression tous les SMS - foreach ($scheduleds as $scheduled) - { - $ids_scheduleds[] = $scheduled['id']; - } - - echo count($ids_scheduleds) . " SMS à envoyer ont été trouvés et ajoutés à la liste des SMS en cours d'envoi.\n"; - - $db->updateProgressScheduledsIn($ids_scheduleds, true); - - //Pour chaque SMS à envoyer - foreach ($scheduleds as $scheduled) - { - $id_scheduled = $scheduled['id']; - $text_sms = escapeshellarg($scheduled['content']); - - //On initialise les numéros auxquelles envoyer le SMS - $numbers = array(); - - //On récupère les numéros pour le SMS et on les ajoute - $target_numbers = $db->getNumbersForScheduled($id_scheduled); - foreach ($target_numbers as $target_number) + //On passe en cours de progression tous les SMS + foreach ($scheduleds as $scheduled) { - $numbers[] = $target_number['number']; + $ids_scheduleds[] = $scheduled['id']; } - //On récupère les contacts, et on ajoute les numéros - $contacts = $db->getContactsForScheduled($id_scheduled); - foreach ($contacts as $contact) - { - $numbers[] = $contact['number']; - } + echo count($ids_scheduleds) . " SMS à envoyer ont été trouvés et ajoutés à la liste des SMS en cours d'envoi.\n"; - //On récupère les groupes - $groups = $db->getGroupsForScheduled($id_scheduled); - foreach ($groups as $group) + $db->updateProgressScheduledsIn($ids_scheduleds, true); + + //Pour chaque SMS à envoyer + foreach ($scheduleds as $scheduled) { - //On récupère les contacts du groupe et on les ajoute aux numéros - $contacts = $db->getContactsForGroup($group['id']); + $id_scheduled = $scheduled['id']; + $text_sms = escapeshellarg($scheduled['content']); + + //On initialise les numéros auxquelles envoyer le SMS + $numbers = array(); + + //On récupère les numéros pour le SMS et on les ajoute + $target_numbers = $db->getNumbersForScheduled($id_scheduled); + foreach ($target_numbers as $target_number) + { + $numbers[] = $target_number['number']; + } + + //On récupère les contacts, et on ajoute les numéros + $contacts = $db->getContactsForScheduled($id_scheduled); foreach ($contacts as $contact) { $numbers[] = $contact['number']; } - } - - foreach ($numbers as $number) - { - echo " Envoi d'un SMS au " . $number . "\n"; - //On ajoute le SMS aux SMS envoyés - //Pour plus de précision, on remet la date à jour en réinstanciant l'objet DateTime (et on reformatte la date, bien entendu) - $now = new DateTime(); - $now = $now->format('Y-m-d H:i:s'); - //On peut maintenant ajouter le SMS - $db->createSended($now, $number, $scheduled['content']); - $id_sended = $db->lastId(); + + //On récupère les groupes + $groups = $db->getGroupsForScheduled($id_scheduled); + foreach ($groups as $group) + { + //On récupère les contacts du groupe et on les ajoute aux numéros + $contacts = $db->getContactsForGroup($group['id']); + foreach ($contacts as $contact) + { + $numbers[] = $contact['number']; + } + } - //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 + foreach ($numbers as $number) + { + echo " Envoi d'un SMS au " . $number . "\n"; + //On ajoute le SMS aux SMS envoyés + //Pour plus de précision, on remet la date à jour en réinstanciant l'objet DateTime (et on reformatte la date, bien entendu) + $now = new DateTime(); + $now = $now->format('Y-m-d H:i:s'); + //On peut maintenant ajouter le SMS + 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 - $commande = '(' . $commande_send_sms . ') >/dev/null 2>/dev/null &'; - - exec($commande); //On execute la commande d'envoi d'un SMS + //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'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); + 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,112 +173,165 @@ //On créer l'objet de base de données global $db; - foreach (scandir(PWD_RECEIVEDS) as $dir) - { - //Si le fichier est un fichier système, on passe à l'itération suivante - if ($dir == '.' || $dir == '..') + for ($i = 0; $i < 30; $i++) + { + foreach (scandir(PWD_RECEIVEDS) as $dir) { - continue; - } - - //On récupère la date du SMS à la seconde près grâce au nom du fichier (Cf. parseSMS.sh) - //Il faut mettre la date au format Y-m-d H:i:s - $date = substr($dir, 0, 4) . '-' . substr($dir, 4, 2) . '-' . substr($dir, 6, 2) . ' ' . substr($dir, 8, 2) . ':' . substr($dir, 10, 2) . ':' . substr($dir, 12, 2); - - //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) - { - $this->wlog('Unable to read file "' . $dir); - die(4); - } - - //On supprime le fichier. Si on n'y arrive pas, alors on log - if (!unlink(PWD_RECEIVEDS . $dir)) - { - $this->wlog('Unable to delete file "' . $dir); - die(8); - } - - $content_file = explode(':', $content_file, 2); - - //Si on a pas passé de numéro ou de message, alors on lève une erreur - if (!isset($content_file[0], $content_file[1])) - { - $this->wlog('Missing params in file "' . $dir); - die(5); - } - - $number = $content_file[0]; - $number = internalTools::parsePhone($number); - $text = $content_file[1]; - - - if (!$number) - { - $this->wlog('Invalid phone number in file "' . $dir); - die(6); - } - - //On va vérifier si on a reçu une commande, et des identifiants - $flags = internalTools::parseForFlag($text); - - //On créer le tableau qui permettra de stocker les commandes trouvées - - $found_commands = array(); - - //Si on reçu des identifiants - if (array_key_exists('LOGIN', $flags) && array_key_exists('PASSWORD', $flags)) - { - //Si on a bien un utilisateur avec les identifiants reçus - $user = $db->getUserFromEmail($flags['LOGIN']); - $this->wlog('We found ' . count($user) . ' users'); - if ($user && $user['password'] == sha1($flags['PASSWORD'])) + //Si le fichier est un fichier système, on passe à l'itération suivante + if ($dir == '.' || $dir == '..') { - $this->wlog('Password is valid'); - //On va passer en revue toutes les commandes, pour voir si on en trouve dans ce message - $commands = $db->getAll('commands'); + continue; + } - $this->wlog('We found ' . count($commands) . ' commands'); - foreach ($commands as $command) + //On récupère la date du SMS à la seconde près grâce au nom du fichier (Cf. parseSMS.sh) + //Il faut mettre la date au format Y-m-d H:i:s + $date = substr($dir, 0, 4) . '-' . substr($dir, 4, 2) . '-' . substr($dir, 6, 2) . ' ' . substr($dir, 8, 2) . ':' . substr($dir, 10, 2) . ':' . substr($dir, 12, 2); + + //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 peux pas ouvrir le fichier, on quitte en logant une erreur + if ($content_file == false) + { + $this->wlog('Unable to read file "' . $dir); + die(4); + } + + //On supprime le fichier. Si on n'y arrive pas, alors on log + if (!unlink(PWD_RECEIVEDS . $dir)) + { + $this->wlog('Unable to delete file "' . $dir); + die(8); + } + + $content_file = explode(':', $content_file, 2); + + //Si on a pas passé de numéro ou de message, alors on lève une erreur + if (!isset($content_file[0], $content_file[1])) + { + $this->wlog('Missing params in file "' . $dir); + die(5); + } + + $number = $content_file[0]; + $number = internalTools::parsePhone($number); + $text = $content_file[1]; + + + if (!$number) + { + $this->wlog('Invalid phone number in file "' . $dir); + die(6); + } + + //On va vérifier si on a reçu une commande, et des identifiants + $flags = internalTools::parseForFlag($text); + + //On créer le tableau qui permettra de stocker les commandes trouvées + + $found_commands = array(); + + //Si on reçu des identifiants + if (array_key_exists('LOGIN', $flags) && array_key_exists('PASSWORD', $flags)) + { + //Si on a bien un utilisateur avec les identifiants reçus + $user = $db->getUserFromEmail($flags['LOGIN']); + $this->wlog('We found ' . count($user) . ' users'); + if ($user && $user['password'] == sha1($flags['PASSWORD'])) { - $command_name = mb_strtoupper($command['name']); - if (array_key_exists($command_name, $flags)) + $this->wlog('Password is valid'); + //On va passer en revue toutes les commandes, pour voir si on en trouve dans ce message + $commands = $db->getAll('commands'); + + $this->wlog('We found ' . count($commands) . ' commands'); + foreach ($commands as $command) { - $this->wlog('We found command ' . $command_name); - - //Si la commande ne nécessite pas d'être admin, ou si on est admin - if (!$command['admin'] || $user['admin']) + $command_name = mb_strtoupper($command['name']); + if (array_key_exists($command_name, $flags)) { - $this->wlog('And the count is ok'); - $found_commands[$command_name] = PWD_SCRIPTS . $command['script'] . escapeshellcmd($flags[$command_name]); + $this->wlog('We found command ' . $command_name); + + //Si la commande ne nécessite pas d'être admin, ou si on est admin + if (!$command['admin'] || $user['admin']) + { + $this->wlog('And the count is ok'); + $found_commands[$command_name] = PWD_SCRIPTS . $command['script'] . escapeshellcmd($flags[$command_name]); + } } } } } + + //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->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) + { + echo 'Execution de la commande : ' . $command_name . ' :: ' . $command . "\n"; + exec($command); + } } - //On va supprimer le mot de passe du SMS pour pouvoir l'enregistrer sans danger - $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)) - { - echo "Erreur lors de l'enregistrement du SMS\n"; - $this->wlog('Unable to process the SMS in file "' . $dir); - die(7); - } - - //Chaque commande sera executée. - foreach ($found_commands as $command_name => $command) - { - echo 'Execution de la commande : ' . $command_name . ' :: ' . $command . "\n"; - 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); + } } diff --git a/controllers/internalIncs.php b/controllers/internalIncs.php index 6ab5a7f..ea1ecdf 100755 --- a/controllers/internalIncs.php +++ b/controllers/internalIncs.php @@ -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'); } } diff --git a/controllers/internalTools.php b/controllers/internalTools.php index 5942a68..4d33043 100755 --- a/controllers/internalTools.php +++ b/controllers/internalTools.php @@ -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; } diff --git a/controllers/profile.php b/controllers/profile.php index 63fd678..a81ac72 100755 --- a/controllers/profile.php +++ b/controllers/profile.php @@ -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,62 +138,63 @@ 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é' - ))); - return false; + 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; + } /** diff --git a/controllers/receiveds.php b/controllers/receiveds.php index 90dd04f..517ba50 100755 --- a/controllers/receiveds.php +++ b/controllers/receiveds.php @@ -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; + } } diff --git a/controllers/scheduleds.php b/controllers/scheduleds.php index bfc2302..03517b0 100755 --- a/controllers/scheduleds.php +++ b/controllers/scheduleds.php @@ -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); - header('Location: ' . $this->generateUrl('scheduleds')); + $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,31 +86,36 @@ $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']; @@ -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,102 +139,105 @@ { 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])) { - $id_scheduled = $db->lastId(); - $db->createEvent('SCHEDULED_ADD', 'Ajout d\'un SMS pour le ' . $date); - $errors = false; - - foreach ($numbers as $number) + if (!$api) { - if ($number = internalTools::parsePhone($number)) - { - $db->createScheduleds_numbers($id_scheduled, $number); - } - else - { - $errors = true; - } + $_SESSION['errormessage'] = 'Impossible de créer ce SMS.'; + header('Location: ' . $this->generateUrl('scheduleds')); + } + return false; + } + + $id_scheduled = $db->lastId(); + + 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)) + { + $errors = true; + continue; } - foreach ($contacts as $id_contact) + if (!$db->insertIntoTable('scheduleds_numbers', ['id_scheduled' => $id_scheduled, 'number' => $number])) { - if (!$db->createScheduleds_contacts($id_scheduled, $id_contact)) - { - $errors = true; - } + $errors = true; } + } - foreach ($groups as $id_group) + foreach ($contacts as $id_contact) + { + if (!$db->insertIntoTable('scheduleds_contacts', ['id_scheduled' => $id_scheduled, 'id_contact' => $id_contact])) { - if (!$db->createScheduleds_groups($id_scheduled, $id_group)) - { - $errors = true; - } + $errors = true; } + } - if ($errors) + foreach ($groups as $id_group) + { + if (!$db->insertIntoTable('scheduleds_groups', ['id_scheduled' => $id_scheduled, 'id_group' => $id_group])) { - if (!$api) - { - header('Location: ' . $this->generateUrl('scheduleds', 'showAll', array( - 'errormessage' => 'Le SMS a bien été créé, mais certains numéro ne sont pas valides.' - ))); - } - return true; + $errors = true; } - else + } + + if ($errors) + { + if (!$api) { - if (!$api) - { - header('Location: ' . $this->generateUrl('scheduleds', 'showAll', array( - 'successmessage' => 'Le SMS a bien été créé.' - ))); - } - return true; + $_SESSION['errormessage'] = 'Le SMS a bien été créé, mais certains numéro ne sont pas valides.'; + header('Location: ' . $this->generateUrl('scheduleds')); } + 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; } } } diff --git a/controllers/sendeds.php b/controllers/sendeds.php index 9f67128..68402eb 100755 --- a/controllers/sendeds.php +++ b/controllers/sendeds.php @@ -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, diff --git a/controllers/smsAPI.php b/controllers/smsAPI.php index a89dc9b..1c3b05d 100755 --- a/controllers/smsAPI.php +++ b/controllers/smsAPI.php @@ -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; } } diff --git a/controllers/users.php b/controllers/users.php index 293b617..ac414f6 100755 --- a/controllers/users.php +++ b/controllers/users.php @@ -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); - header('Location: ' . $this->generateUrl('users')); + $db->deleteUsersIn($ids); + header('Location: ' . $this->generateUrl('users')); + return true; } } diff --git a/createDatabase.sql b/createDatabase.sql index 1763ae1..4310c08 100755 --- a/createDatabase.sql +++ b/createDatabase.sql @@ -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 +); diff --git a/css/style.css b/css/style.css index dea9794..a7df0e9 100755 --- a/css/style.css +++ b/css/style.css @@ -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; +} diff --git a/fonts/glyphicons-halflings-regular.woff2 b/fonts/glyphicons-halflings-regular.woff2 old mode 100644 new mode 100755 diff --git a/js/custom.js b/js/custom.js index 45e9ebf..802ee30 100755 --- a/js/custom.js +++ b/js/custom.js @@ -17,5 +17,86 @@ function showMessage(message, type) } var alerthtml = '
Date du dernier message | +Numéro | +
---|---|
+ | + |