From db1b5c35d88b50e1daa49bac996b6b1f0e22ec87 Mon Sep 17 00:00:00 2001 From: Pierre-Lin Bonnemaison Date: Mon, 17 Aug 2015 02:30:09 +0200 Subject: [PATCH] =?UTF-8?q?Ajout=20du=20syst=C3=A8me=20de=20discussion=20e?= =?UTF-8?q?t=20fixe=20des=20quelques=20bugs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controllers/discussions.php | 232 ++++++++++++++++++++++++++++++ controllers/internalConsole.php | 5 +- controllers/scheduleds.php | 11 +- controllers/smsAPI.php | 2 +- css/style.css | 100 +++++++++++++ js/custom.js | 55 +++++++ model/DataBase.php | 91 ++++++++++++ templates/discussions/default.php | 68 +++++++++ templates/discussions/show.php | 134 +++++++++++++++++ templates/internalIncs/nav.php | 3 + templates/scheduleds/add.php | 2 +- templates/scheduleds/edit.php | 2 +- 12 files changed, 699 insertions(+), 6 deletions(-) create mode 100755 controllers/discussions.php create mode 100755 templates/discussions/default.php create mode 100755 templates/discussions/show.php diff --git a/controllers/discussions.php b/controllers/discussions.php new file mode 100755 index 0000000..bba8d38 --- /dev/null +++ b/controllers/discussions.php @@ -0,0 +1,232 @@ +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' => $sended['at'], + 'text' => $sended['content'], + 'type' => 'sended', + ); + } + + foreach ($receiveds as $received) + { + $messages[] = array( + 'date' => $received['at'], + 'text' => $received['content'], + 'type' => 'received', + ); + } + + foreach ($scheduleds as $scheduled) + { + $messages[] = array( + 'date' => $scheduled['at'], + 'text' => $scheduled['content'], + 'type' => 'inprogress', + ); + } + + //On va trier le tableau des messages + usort($messages, function($a, $b) { + return strtotime($a["date"]) - strtotime($b["date"]); + }); + + 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/internalConsole.php b/controllers/internalConsole.php index 4e10031..56996ab 100755 --- a/controllers/internalConsole.php +++ b/controllers/internalConsole.php @@ -134,7 +134,10 @@ $now = new DateTime(); $now = $now->format('Y-m-d H:i:s'); //On peut maintenant ajouter le SMS - $db->insertIntoTable('sendeds', ['at' => $now, 'number' => $number, 'content' => $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 diff --git a/controllers/scheduleds.php b/controllers/scheduleds.php index 0b05039..dfca54e 100755 --- a/controllers/scheduleds.php +++ b/controllers/scheduleds.php @@ -102,7 +102,7 @@ * @param string $_POST['groups'] : Un tableau avec les ids des groupes auxquels envoyer le sms * @return boolean; */ - public function create($csrf = '', $api = false) + public function create($csrf = '', $api = false, $discussion = false) { if (!$api) { @@ -145,7 +145,7 @@ return false; } - if (!internalTools::validateDate($date, 'Y-m-d H:i')) + if (!internalTools::validateDate($date, 'Y-m-d H:i:s')) { if (!$api) { @@ -167,6 +167,13 @@ } $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; diff --git a/controllers/smsAPI.php b/controllers/smsAPI.php index 3d8e3f7..1c3b05d 100755 --- a/controllers/smsAPI.php +++ b/controllers/smsAPI.php @@ -120,7 +120,7 @@ $_POST['groups'] = $groups; $scheduleds = new scheduleds(); - $success = $scheduleds->create(true); + $success = $scheduleds->create('', true); if (!$success) { diff --git a/css/style.css b/css/style.css index d8314a7..a7df0e9 100755 --- a/css/style.css +++ b/css/style.css @@ -88,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/js/custom.js b/js/custom.js index f404c51..12261fd 100755 --- a/js/custom.js +++ b/js/custom.js @@ -33,8 +33,63 @@ function verifReceived() }); } +/** + * Cette fonction permet de scroller au dernier message + */ +function scrollDownDiscussion() +{ + 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('
'); + 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, ">"), 0); + jQuery('.discussion-container').find('#send-message-spiner').remove(); + } + } + }).done(function() + { + form.trigger("reset"); + }); + }); + + scrollDownDiscussion(); }); diff --git a/model/DataBase.php b/model/DataBase.php index 6ebb585..5557006 100755 --- a/model/DataBase.php +++ b/model/DataBase.php @@ -115,6 +115,46 @@ return $this->runQuery($query, $params); } + /** + * 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 getReceivedsSinceForNumberOrderByDate($date, $number) + { + $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( + 'date' => $date, + 'number' => $number + ); + + return $this->runQuery($query, $params); + } + + /** + * 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 + "; + + return $this->runQuery($query); + } + /********************************/ /* PARTIE DES REQUETES CONTACTS */ /********************************/ @@ -382,6 +422,57 @@ return $this->runQuery($query, $params, self::ROWCOUNT); } + /** + * 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 getScheduledsBeforeDateForNumber($date, $number) + { + $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( + 'date' => $date, + 'number' => $number, + ); + + return $this->runQuery($query, $params); + } + /********************************/ /* PARTIE DES REQUETES COMMANDS */ /********************************/ diff --git a/templates/discussions/default.php b/templates/discussions/default.php new file mode 100755 index 0000000..52a17fe --- /dev/null +++ b/templates/discussions/default.php @@ -0,0 +1,68 @@ +head('Discussions - Show All'); +?> +
+nav('discussions'); +?> +
+
+ +
+
+

+ Dashboard Discussions +

+ +
+
+ + +
+
+
+
+

Liste des discussions

+
+
+
+ + + + + + + + + + + + + + + +
Date du dernier messageNuméro
+
+
+
+
+
+
+
+
+footer(); diff --git a/templates/discussions/show.php b/templates/discussions/show.php new file mode 100755 index 0000000..67ce0d0 --- /dev/null +++ b/templates/discussions/show.php @@ -0,0 +1,134 @@ +head('Discussions - Show All'); +?> +
+nav('discussions'); +?> +
+
+ +
+
+

+ Discussion +

+ +
+
+ + +
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+ +footer(); diff --git a/templates/internalIncs/nav.php b/templates/internalIncs/nav.php index 84e78de..49ba288 100755 --- a/templates/internalIncs/nav.php +++ b/templates/internalIncs/nav.php @@ -34,6 +34,9 @@
  • > SMS
  • +
  • > + Discussions +
  • > Commandes
  • diff --git a/templates/scheduleds/add.php b/templates/scheduleds/add.php index 116956f..8eb838a 100755 --- a/templates/scheduleds/add.php +++ b/templates/scheduleds/add.php @@ -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' diff --git a/templates/scheduleds/edit.php b/templates/scheduleds/edit.php index afd22fb..5a0cc8a 100755 --- a/templates/scheduleds/edit.php +++ b/templates/scheduleds/edit.php @@ -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'