From 4f9bb3e2565151e8cc1c6ed409f15886f459b085 Mon Sep 17 00:00:00 2001
From: Pierre-Lin Bonnemaison <pierre.lin@free.fr>
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 @@
+<?php
+	/**
+	 * Page des discussions
+	 */
+	class discussions extends Controller
+	{
+		/**
+		 * Cette fonction est appelée avant toute les autres : 
+		 * Elle vérifie que l'utilisateur est bien connecté
+		 * @return void;
+		 */
+		public function before()
+		{
+			internalTools::verifyConnect();
+		}
+
+		/**
+		 * Cette fonction retourne toutes les discussions, sous forme d'un tableau permettant l'administration de ces contacts
+		 */	
+		public function byDefault()
+		{
+			//Creation de l'object de base de données
+			global $db;
+			
+			//Recupération des nombres des 4 panneaux d'accueil
+			$discussions = $db->getDiscussions();
+
+			foreach ($discussions as $key => $discussion)
+			{
+				if (!$contacts = $db->getFromTableWhere('contacts', ['number' => $discussion['number']]))
+				{
+					continue;
+				}
+
+				$discussions[$key]['contact'] = $contacts[0]['name'];
+			}
+
+			$this->render('discussions/default', array(
+				'discussions' => $discussions,
+			));
+		}
+		
+		/**
+		 * Cette fonction permet d'afficher la discussion avec un numero
+		 * @param string $number : La numéro de téléphone avec lequel on discute
+		 */
+		public function show ($number)
+		{
+			global $db;
+
+			$contact = '';
+
+			if ($contacts = $db->getFromTableWhere('contacts', ['number' => $number]))
+			{
+				$contact = $contacts[0]['name'];
+			}
+
+			$this->render('discussions/show', array(
+				'number' => $number,
+				'contact' => $contact,
+			));
+		}
+
+		/**
+		 * Cette fonction récupère l'ensemble des messages pour un numéro, recçus, envoyés, en cours
+		 * @param string $number : Le numéro cible
+		 * @param string $transactionId : Le numéro unique de la transaction ajax (sert à vérifier si la requete doit être prise en compte)
+		 */
+		function getmessages($number, $transactionId)
+		{
+			global $db;
+
+			$now = new DateTime();
+			$now = $now->format('Y-m-d H:i:s');
+
+			$sendeds = $db->getFromTableWhere('sendeds', ['target' => $number], 'at');
+			$receiveds = $db->getFromTableWhere('receiveds', ['send_by' => $number], 'at');
+			$scheduleds = $db->getScheduledsBeforeDateForNumber($now, $number);
+
+			$messages = [];
+
+			foreach ($sendeds as $sended)
+			{
+				$messages[] = array(
+					'date' => $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('<div class="text-center" id="send-message-spiner"><i class="fa fa-spinner fa-spin"></i></div>');
+		scrollDownDiscussion();
+		jQuery.ajax({
+			url: form.attr('action'),
+			type: form.attr('method'),
+			data: formData,
+			contentType: false,
+			processData: false,
+			dataType: "json",
+			success: function (data)
+			{
+				if (!data.success)
+				{
+					showMessage(data.message.replace(/</g, "&lt;").replace(/>/g, "&gt;"), 0);
+					jQuery('.discussion-container').find('#send-message-spiner').remove();
+				}
+			}
+		}).done(function()
+		{
+			form.trigger("reset");
+		});
+	});
+
+	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 @@
+<?php
+	//Template dashboard
+	$incs = new internalIncs();
+	$incs->head('Discussions - Show All');
+?>
+<div id="wrapper">
+<?php
+	$incs->nav('discussions');
+?>
+	<div id="page-wrapper">
+		<div class="container-fluid">
+			<!-- Page Heading -->
+			<div class="row">
+				<div class="col-lg-12">
+					<h1 class="page-header">
+						Dashboard <small>Discussions</small>
+					</h1>
+					<ol class="breadcrumb">
+						<li>
+							<i class="fa fa-dashboard"></i> <a href="<?php echo $this->generateUrl('dashboard'); ?>">Dashboard</a>
+						</li>
+						<li class="active">
+							<i class="fa fa-comments-o"></i> Discussions
+						</li>
+					</ol>
+				</div>
+			</div>
+			<!-- /.row -->
+
+			<div class="row">
+				<div class="col-lg-12">
+					<div class="panel panel-default">
+						<div class="panel-heading">
+							<h3 class="panel-title"><i class="fa fa-comments-o fa-fw"></i> Liste des discussions</h3>
+						</div>
+						<div class="panel-body">
+							<div class="table-responsive">
+								<table class="table table-bordered table-hover table-striped" id="table-discussions">
+									<thead>
+										<tr>
+											<th>Date du dernier message</th>
+											<th>Numéro</th>
+										</tr>
+									</thead>
+									<tbody>
+									<?php
+										foreach ($discussions as $discussion)
+										{
+											?>
+												<tr class="goto" url="<?php secho($this->generateUrl('discussions', 'show', [$discussion['number']])); ?>">
+												<td><?php secho($discussion['at']); ?></td>
+												<td><?php secho(isset($discussion['contact']) ? $discussion['contact'] . ' (' . $discussion['number'] . ')' : $discussion['number']); ?></td>
+											</tr>
+											<?php
+										}
+									?>
+									</tbody>
+								</table>
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+</div>
+<?php
+	$incs->footer();
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 @@
+<?php
+	//Template dashboard
+	$incs = new internalIncs();
+	$incs->head('Discussions - Show All');
+?>
+<div id="wrapper">
+<?php
+	$incs->nav('discussions');
+?>
+	<div id="page-wrapper">
+		<div class="container-fluid">
+			<!-- Page Heading -->
+			<div class="row">
+				<div class="col-lg-12">
+					<h1 class="page-header">
+						Discussion <small><?php secho($contact ? $contact . ' (' . $number . ')' : $number); ?></small>
+					</h1>
+					<ol class="breadcrumb">
+						<li>
+							<i class="fa fa-dashboard"></i> <a href="<?php echo $this->generateUrl('dashboard'); ?>">Dashboard</a>
+						</li>
+						<li>
+							<i class="fa fa-comments-o"></i> <a href="<?php echo $this->generateUrl('discussions'); ?>">Discussions</a>
+						</li>
+						<li class="active">
+							<?php secho($number); ?>
+						</li>
+					</ol>
+				</div>
+			</div>
+			<!-- /.row -->
+
+			<div class="row">
+				<div class="col-lg-12 discussion-container">
+					<div class="text-center"><i class="fa fa-spinner fa-spin"></i></div>
+				</div>
+				<div class="col-lg-12 message-input-container">
+					<div class="discussion-message message-input">
+						<form class="send-message-discussion" action="<?php secho($this->generateUrl('discussions', 'send', [$_SESSION['csrf']])); ?>" method="POST">
+							<textarea name="content" placeholder="Envoyer un message..."></textarea>
+							<input type="hidden" name="numbers[]" value="<?php secho($number); ?>" />
+							<button class="btn" ><span class="fa fa-fw fa-send-o"></span> Envoyer</button>
+						</form>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+</div>
+<script>
+	jQuery(document).ready(function () {
+		/**
+		 * Cette fonction vérifie régulièrement les sms pour mettre à jour l'affichage
+		 */
+		function getmessages ()
+		{
+			ajaxTransactionId = Date.now();
+			jQuery.getJSON(HTTP_PWD + "/discussions/getmessages/<?php echo htmlspecialchars(urlencode($number)); ?>/" + ajaxTransactionId , function( data ) {
+				if (data.transactionId != ajaxTransactionId)
+				{
+					return false;
+				}
+
+				jQuery('.discussion-container').html('');
+
+				$.each(data.messages, function(key, message) {
+
+					switch (message.type)
+					{
+						case 'received' :
+							var texte = '' +
+							'<div class="clearfix message-container">' +
+								'<div class="discussion-message message-received">' +
+									'<div class="discussion-message-text">' + message.text.replace(/</g, "&lt;").replace(/>/g, "&gt;") + '</div>' +
+									'<div class="discussion-message-date">' + message.date.replace(/</g, "&lt;").replace(/>/g, "&gt;") + '</div>' +
+								'</div>' +
+							'</div>';
+							break;
+						case 'sended' :
+							var texte = '' +
+							'<div class="clearfix message-container">' +
+								'<div class="discussion-message message-sended">' +
+									'<div class="discussion-message-text">' + message.text.replace(/</g, "&lt;").replace(/>/g, "&gt;") + '</div>' +
+									'<div class="discussion-message-date">' + message.date.replace(/</g, "&lt;").replace(/>/g, "&gt;") + '</div>' +
+								'</div>' +
+							'</div>';
+							break;
+						case 'inprogress' :
+							var texte = '' +
+								'<div class="clearfix message-container">' +
+									'<div class="discussion-message message-sended">' +
+										'<div class="message-in-progress-hover"><i class="fa fa-spinner fa-spin"></i></div>' +
+										'<div class="discussion-message-text">' + message.text.replace(/</g, "&lt;").replace(/>/g, "&gt;") + '</div>' +
+										'<div class="discussion-message-date">' + message.date.replace(/</g, "&lt;").replace(/>/g, "&gt;") + '</div>' +
+									'</div>' +
+								'</div>';
+							break;
+						default :
+							var texte = '';
+							break;
+					}
+
+					jQuery('.discussion-container').append(texte);
+				});
+				scrollDownDiscussion();
+			});
+		}
+
+		/**
+		 * Cette fonction permet de fixer la taille de la fenetre de discussion
+		 */
+		function fullHeightDiscussion()
+		{
+			var containerPosition = jQuery('.discussion-container').position();
+			var windowHeight = jQuery(window).height();
+			var messageInputContainer = jQuery('.message-input-container').outerHeight();
+			var footerHeight = jQuery('footer').outerHeight();
+
+			var containerHeight = Math.floor(windowHeight - (containerPosition.top + footerHeight * 2 + messageInputContainer));
+
+			jQuery('.discussion-container').outerHeight(containerHeight);
+		}
+
+		fullHeightDiscussion();
+
+		jQuery(window).on('resize', function () {
+			fullHeightDiscussion();
+		});
+
+		var getmessagesInterval = setInterval(getmessages, 2500);
+	});
+</script>
+<?php
+	$incs->footer();
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 @@
 					<li <?php echo $page == 'scheduleds' ? 'class="active"' : ''; ?>>
 						<a href="<?php echo $this->generateUrl('scheduleds'); ?>"><i class="fa fa-fw fa-envelope"></i> SMS</a>
 					</li>
+					<li <?php echo $page == 'discussions' ? 'class="active"' : ''; ?>>
+						<a href="<?php echo $this->generateUrl('discussions'); ?>"><i class="fa fa-fw fa-comments"></i> Discussions</a>
+					</li>
 					<li <?php echo $page == 'commands' ? 'class="active"' : ''; ?>>
 						<a href="<?php echo $this->generateUrl('commands'); ?>"><i class="fa fa-fw fa-terminal"></i> Commandes</a>
 					</li>
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'