Système de messagerie en php sous wordpress

Système de messagerie en php sous wordpress

Aujourd’hui je vais partir de l’exemple d’un site, qui intègre un système de messagerie en php sous wordpress: les utilisateurs peuvent s’envoyer des messages, le destinataire reçoit la notification de ce message, et l’admin peut également envoyer des messages, des documents, ou encore notifier des rendez vous à l’utilisateur. Mais Ici nous traiterons que de la première partie, les messages entre utilisateurs.

Comme à la base sur le site il y a deux sources pour les messages : les utilisateurs et l’admin, le code est optimisé pour afficher l’ensemble des messages, pour afficher une pagination globale qui boucle sur la totalité des messages (donc sur plusieurs tableaux). Ici, volontairement je cache la partie concernant les messages admin, car elle est trop longue, mais je vous montre quand même le code, qui peut donc servir de base à un plugin ou la mise en place d’un véritable système de messagerie interne.

Dans ce système de messagerie en php sous wordpress :

– on va créer deux tables supplémentaires dans la base de donnée.

– on va créer un modèle de page  ‘message.php’  ainsi qu’une page dédiée dans wordpress.

– un formulaire d’envoi de message avec les vérif qui vont bien, l’ajout de ces messages dans la base, et l’envoi d’un mail de notification pour le destinataire.

– On va créer une fonction de pagination pour l’ensemble des messages, une fonction d’ajout des messages dans la première table, une seconde pour l’ajout des messages vus dans la seconde table.

-on va créer un fichier dédié(ou non) pour l’envoi de notification

Prérequis : la base de donnée

Une table message

On va d’abord créer une table dans notre base de donnée Mysql : on va l’appeler message, et en voici la structure:

structuremlkimssg

La  table contiendra un id, on lui donne un nom spécifique pour éviter que mysql s’emmêle les pinceaux avec les autres tables..Un iduser, un iddest : c’est l’id du destinataire  à qui l’utilisateur souhaite envoyer un message. Un titre pour notre message, le contenu (colonne msg) puis une date d’envoi (dateenr) et la date à laquelle a été vu le message.

Une table messages_vues

Pour faire les choses bien, on va devoir créer également une table messages_vues, pour lister les messages qui seront ouverts ou lus. Dans sa liste de message, l’utilisateur pourra donc voir les messages qu’il aura ouvert et les non lus qu’on marquera avec une enveloppe fermée par exemple.

structure2mkimsg

La, pareil, un idvue, l‘iduser pour faire la liaison avec notre table précédente, l‘idmsg qui correspond également  à l’idmsg de notre première table, une date d’enregistrement du message, et enfin une colonne origin, pour signifier l’origine du message, (le personne qui envoie).

Maintenant qu’on a nos tables, on  va créer notre système de messagerie en php.

Message.php

Dans une page message.php, je vais créer mon formulaire avec les vérifications en php :

if ($_POST[action] == "enr") {
if (!isset($_POST[iddest])) {
$hasError = true;
} else {
$iddest = $_POST[iddest];
}
if ($_POST[message_ok] == "") {
$hasError = true;
} else {
$message_ok = $_POST[message_ok];
}
if (!isset($_POST[titre])) {
$error = 'Indiquez votre titre.';
$hasError = true;
} else {
$titre = $_POST[titre];
}
if (!isset($_POST[msg])) {
$error = 'Entrez votre message.';
$hasError = true;
} else {
$msg = $_POST[msg];
}
....
}

ici j’affiche la vérif php que je place tout en haut de mon fichier message.php: on base notre vérif sur l’action d’envoi via l’input hidden « enr‘, puis on vérifie les champs qui nous intéressent avant l’envoi en base.J’ai rajouté pour l’exemple un input hidden pour récupérer l’iddest (id du destinataire) et un champ hidden supplémentaire « message_ok« , non obligatoire.

En tète de notre formulaire, un message de remerciement en cas de succès de l’envoi  puis le formulaire lui même:

<div class="container">
<div class="row">
<div class="col-lg-9">

<?php if ($_POST[action] == "enr") { ?>
<div class="panel panel-success confirmation">
<div class="panel-heading">Votre message a bien été envoyé</div>
</div>
<?php } ?>

<?php
$userid = $_GET['iddest'];
$userdata = get_userdata($userid);
if ($userdata) {
// print_r($userdata->data);
echo ' . <form method="POST" class="formulaire">
<div>
<h2>Envoyez un Message à :
' .
$userdata->last_name . ", " . $userdata->first_name . '
</h2>
</div>
<div class="form-group">
<label for="titre">Titre: </label>
<input type="text" class="form-control" name="titre" required value=" ' . $_POST[titre] . '" id="titre"/>
</div>
<div class="form-group">
<label for="msg">Votre message : </label>
<textarea class="form-control" rows="5"name="msg" value="' . $_POST[msg] . '" id="msg" required></textarea>
</div>
<div class="form-group">
<input type="hidden" class="form-control" name="iddest" required value="' . $_GET[iddest] . '" id="iddest"/>
<input type="hidden" class="form-control" name="message_ok" required value="' . $_GET[message_ok] . '" id="message_ok"/>
</div>
<input type="hidden" name="action" value="enr" />
<button name="submit" id="submit" type="submit" class="btn btn-default">Envoyer</button>
</form>
</div> .';
} else {
// echo "utilisateur inconnu";
?>
</div>
<?php }; ?>

Dans notre exemple, pour définir l’identité du destinataire on récupère son id via l’url en $_GET avec la variable $iddest, et, avec le mot clé get_userdata, on récupère toutes les infos sur ce destinataire.
En faisant ‘$userdata->last_name . « ,  » . $userdata->first_name . ‘ on peut extraire, à partir du tableau $userdata les informations qui nous intéressent, ici le nom et le prénom.
L ‘Id du destinataire ainsi que l’origine sont en champs cachés, on affiche seulement le titre et le corps du message dans notre formulaire mais on va quand même les récupérer lors de nos vérifications.

Maintenant on va ajouter, suite à la vérif php, le moyen d’insérer les messages en base, pour les archiver et notamment pouvoir indiquer par la suite s’ils sont lus ou non.
Tout en haut de notre fichier, à la suite de la vérif et dans le if ($_POST[action] == « enr ») {
on va placer une fonction d’ajout de message :

 $data = array(
'iduser' => $iduser,
'iddest' => $iddest,
'message_ok' => $message_ok,
'titre' => $titre,
'msg' => $msg
);
add_msg($data);

Notre fonction va tout simplement vérifier que toutes les données soient bien envoyées avant l’insertion en base: (à placer dans functions.php)

function add_msg($data) {

global $wpdb;

if (!empty($data[iddest]) && !empty($data[message_ok]) && !empty($data[titre]) && !empty($data[msg])) {
$sql = "insert into message (idmsg,iduser,iddest,titre,msg,dateenr,datevue) values ('$data[idmsg]','$data[iduser]','$data[iddest]','$data[titre]','$data[msg]',now(),'$data[datevue]')";

$wpdb->query($sql);
}
}

Maintenant, toujours dans notre vérif php, on va préparer le code pour envoyer la notification de message au destinataire.
A la suite de notre code précédent, on récupère l’email du destinataire avec encore une fois le « get_userdata » :

 //recuperation des donnees user et son mail
$userdata = get_userdata($iddest);
if ($userdata) {
$userdata->user_email;
// print_r($userdata->user_email);
$datamsg = '
<span style="font-size:18px; color:#00395f"><strong>Bonjour Mr ';
$datamsg .= $userdata->last_name;
$datamsg .= '</strong> </span><br /><br />
Un nouveau message vous a été adressé.
Rendez-vous dès maintenant sur votre espace ';
$message = modeleHtml(array("msg" => $datamsg));
wp_mail($userdata->user_email, $titre, $message);
} else {
die('erreur !' . mysql_error());
}

}

On récupère ensuite le nom du destinataire pour personnaliser le message de notification.
Ici on rédige le corps du mail uniquement, celui ci va venir s’insérer dans une fonction modeleHtml que je vous montrerai plus loin et qui contient un modèle, en fait toute la structure d’un mail de notification, dans lequel on viendra pour chaque événement insérer un contenu central différent.(parce qu’en fait sur ce site d’exemple, un plugin permet l’envoi de message de l’admin aux users, avec des notifications pour des rendez vous, des documents etc..il valait mieux factoriser…)

Les fonctions d’insertion et de notification

Au sein de ce modèle html on va placer une variable $date[msg], et c’est elle qui va contenir les différents messages de notifications.
$message = modeleHtml(array(« msg » => $datamsg));

Comme on le voit ici, on insère les données récupérées via  $datamsg dans notre tableau contenant la structure du mail, au travers de la variable ‘msg‘.
La fonction wp_mail de wordpress nous permet d’envoyer le mail.

Il faut l’insérer soit dans un plugin dédié, soit dans le fichier functions.php;
Dans mon cas, et pour ce site, j’ai du le réaliser au sein d’un plugin dédié aux messages justement.
Je vous donne donc l’ensemble du code de ce plugin ou notamment on retrouve la personnalisation d’envoi de message, la notification pour oubli de mot de passe, notification pour inscription etc..et notre fonction modeleHtml:

// Modifie le charset des emails envoyes
add_filter ("wp_mail_content_type", "my_awesome_mail_content_type");
function my_awesome_mail_content_type() {
return "text/html";
}

// Modifie le form email
add_filter ("wp_mail_from", "my_awesome_mail_from");
function my_awesome_mail_from() {
return "votreemail@kkchose.fr";
}

//Modifie le from name
add_filter( 'wp_mail_from_name', 'custom_wp_mail_from_name' );
function custom_wp_mail_from_name( $original_email_from )
{
return 'le nom de votre site';
}

function modeleHtml($data){
$message ='<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>TITRE DU SITE | TITRE DU SITE</title>
</head>

<body>
<table width="600" border="0" cellspacing="0" cellpadding="0" align="center" style="border:#dedede 1px solid">
<tr>
<td width="600" height="118" bgcolor="#FFFFFF">
<table width="600" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="187" height="118">
<img src="chemin _vers_une_image/img.jpg" width="187" height="118" alt="" border="0" style="display:block"/>
</td>
<td width="263" height="118">
<font face="Arial, Helvetica, sans-serif" style="font-size:16px; color:#00395f">
<span style="font-size:33px"><strong>Sous titre</strong></span><br />
Paris - Quelquepart
</font>
</td>
<td width="150" height="118">
<img src="chemin_vers_votre_image/images/logo.jpg" width="150" height="118" alt="" border="0" style="display:block"/>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td width="600" height="277">
<img src="chemin_vers_votre_image.jpg" width="600" height="277" alt="" border="0" style="display:block"/>
</td>
</tr>
<tr>
<td width="600" height="300">
<table width="600" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="40" height="300"></td>
<td width="520" height="300">
<font face="Arial, Helvetica, sans-serif" style="font-size:14px; color:#2c2c2e">
'.$data[msg].'
</font>
</td>
<td width="40" height="300"></td>
</tr>
<tr>
<td width="40" height="32">
</td>
<td width="520" height="32" align="left">
<a href="nom_de_domaine/nom_du_theme/wp-login.php" title="Cliquez ici pour accéder à votre profil" target="_blank">
<img src="image_boutton/btn.jpg" width="185" height="32" alt="Acceder à mon profil" border="0" style="display:block"/></a>
</td>
<td width="40" height="32">
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td width="600" height="40">
</td>
</tr>
<tr>
<td width="600" height="55">
<a href="nom_de_domaine/nom_du_theme/wp-login.php" title="Cliquez ici pour accéder au site" target="_blank">
<img src="chemin_vers_votre_image/footer.jpg" width="600" height="55" alt="Acceder au site" border="0" style="display:block"/></a>
</td>
</tr>
</table>
</body>
</html>';

return $message;

}
// Redefine user notification function
if (!function_exists('wp_new_user_notification')) {
function wp_new_user_notification($user_id, $plaintext_pass) {
$user = new WP_User($user_id);

$user_login = stripslashes($user->user_login);
$user_email = stripslashes($user->user_email);


$email_subject = "Bienvenue sur Mon site ".$user_login."!";

$datamsg = '
<span style="font-size:18px; color:#00395f"><strong>Félicitation ';$datamsg .= $user_login ;
$datamsg .= '</strong> </span><br /><br />
En tant que nouveau membre du site, vousavez désormais accès à un site qui vous est entièrement dédié : <span style="color:#00395f"><a href="#" title="Cliquez ici pour accéder au site" style="text-decoration:none; color:#00395f" target="_blank">nom_de_domaine</a><br /><br />


Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte Du texte !<br /><br />

Rendez-vous dès maintenant sur votre espace à l\'aide de vos identifiants privés :';
$datamsg.= " $user_login / $user_email / $plaintext_pass";

$message = modeleHtml(array("msg"=>$datamsg));

wp_mail($user_email, $email_subject, $message);
}
}



// Definit le titre de l'email pour retrouver le password
function my_retrieve_password_subject_filter($old_subject) {
// $old_subject is the default subject line created by WordPress.
// (You don't have to use it.)

$blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
$subject = sprintf( __('[%s] Password Reset'), $blogname );
// This is how WordPress creates the subject line. It looks like this:
// [Doug's blog] Password Reset
// You can change this to fit your own needs.

// You have to return your new subject line:
return $subject;
}
add_filter ( 'retrieve_password_title', 'my_retrieve_password_subject_filter', 10, 1 );

// Fonction pour retrouver le password
function my_retrieve_password_message_filter($old_message, $key) {
// $old_message is the default message already created by WordPress.
// (You don't have to use it.)
// $key is the password-like token that allows the user to get
// a new password
$input = filter_input( INPUT_POST, 'user_login', FILTER_SANITIZE_STRING );

$user = get_user_by( 'email', $input );
$user_login = $user->data->user_login;
$datamsg = '
<span style="font-size:18px; color:#00395f"><strong>Bonjour ';$datamsg .= $user_login ;
$datamsg .= '</strong> </span><br /><br />

Vous avez demandé votre identifiant et mot de passe sur le site.
Pour renouveller votre mot de passe, copier collez le lien dans votre navigateur, dans le cas contraire, vous pouvez ignorez ce message.<br>';

// $datamsg .= network_site_url() . "\r\n\r\n";
$datamsg .= sprintf(__('Identifiant: %s'), $user_login) . "<br>";
$datamsg .= network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . "<br>";


$message = modeleHtml(array("msg"=>$datamsg));

// This is how WordPress creates the message.
// You can change this to meet your own needs.

// You have to return your new message:
return $message;
}
add_filter ( 'retrieve_password_message', 'my_retrieve_password_message_filter', 10, 2 );
?>

Comme on le voit, notre fonction modeleHtml permet de factoriser le code pour toutes les notifications, on a un modèle de mail dont on se sert à chaque fois.

La liste des messages

Maintenant qu’on a notre formulaire avec vérification et insertion en base, notre envoi de notification pour l’envoi de message, grâce à notre fonction dédiée modeleHtml, on peut dresser la liste des messages :
je vous donne ici le reste du code à place à la suite du formulaire:message.php

    <div class="col-lg-9">
<h2>Retrouvez tous vos messages</h2>
<!--<p class=" gris">  Cras elementum ultrices diam...</p>-->
<?php
$origin = $wpdb->get_results("SELECT * FROM messages_vues WHERE iduser ='" . $iduser . "'");
for ($i = 0; $i < count($origin); $i++) {
$msg_vue[$origin[$i]->origin][] = $origin[$i]->idmsg;
}

//Definition deuxieme tableau
global $wpdb;
$msg = $wpdb->get_results("SELECT * FROM message WHERE iddest ='" . $iduser . "'");
for ($i = 0; $i < count($msg); $i++) {
$tabmsg[$msg[$i]->dateenr] = array(
id => $msg[$i]->idmsg,
titre => $msg[$i]->titre,
message => $msg[$i]->msg,
origin => "msgprive",
expediteur => $userdata->last_name . $userdata->first_name
);
}
//Remise du tableau ordre chrono
ksort($tabmsg);
$tabmsg = array_reverse($tabmsg);

//Pagination array calcul de l'offset et limit
if (empty($_GET[npage])) {
$npage = "1";
} else {
$npage = $_GET[npage];
}
$nbre_post_page = 10;
// Calcul de l'offset
$offset = $npage * $nbre_post_page - $nbre_post_page;
$tab = array_slice($tabmsg, $offset, $nbre_post_page);
foreach ($tab as $key => $value) {
if ($value[origin] == 'msgprive') {
$value[expediteur] = $userdata->last_name . $userdata->first_name;
} else {
if ($value[origin] == 'msgadmin') {
$value[expediteur] = "Message de l'admin";
}
}


//liste message
// for($i=0;$i<count([$origin[$i]->origin]);$i++){
if (!empty($msg_vue[$value[origin]]) && in_array($value[id],$msg_vue[$value[origin]]) ) {
echo '<div class="row msg_uniq">';
$imgvu = "msg_open.png";
} else {
$nonce = wp_create_nonce("add_msg_vue_nonce");

echo '<div class="row msg_uniq" data-idmsg="' . $value[id] . '" data-nonce="' . $nonce . '"data-origin="' . $value[origin] . '"data-iduser="' . $value[iduser] . ' " data-vue="' . $value[idvue] .'">';
$imgvu = "msg_new.png";
}
echo '
<div class="col-lg-1 bleu_typo msg_date">' . date("d/m", strtotime($key)) . '</div>
<div class="col-lg-1"><img id="monImage" src="' . get_bloginfo(stylesheet_directory) . '/img/' . $imgvu . '" class="img-responsive"/></div>
<div class="col-lg-9">
<strong>De : ' . $value[expediteur] . '</strong><br/>' . $value[titre] . '
<div class="msg_content collapse" >' . $value[message] . '</div>
</div>
<div class="col-lg-1"><img id="monpointer" src="' . get_bloginfo(stylesheet_directory) . '/img/image_close.png" class="img-responsive"/> </div>
';
echo '</div>';
}
//
// }

?>
<?php
$data = array('iduser' => $iduser);
$nbre_page_total = sizeof($tabmsg);
// Affiche la pagination
$navigation = pagination(array("url" => "./", "offset" => $offset, "npage" => $npage, "maxpost" => $nbre_page_total, "nbre_post_par_page" => $nbre_post_page));
echo $navigation;
?>

</div>
<?php
get_sidebar();
?>
</div>
<?php
get_footer();
?>

Pour les explications, rapidement:
-Première requête et boucle pour sélectionner tous les messages qui sont vus.
on insère le résultat de notre requête dans une variable $origin.
on boucle notre tableau $origin et on lie l’origine au message

-Deuxième requête et boucle pour sélectionner tous les messages de notre table message

A chaque fois on remplit un tableau général que l’on appelle $tabmsg: on va chercher les données issues de nos colonnes réelles dans notre table message, et on créer des colonnes à notre tableau général.Ce sont les colones : id, titre, message, origin, expediteur.

Ensuite le Ksort nous permet de remettre le tableau dans l’ordre , puis un array_reverse  nous permet de remettre le tout dans l’ordre chronologique.
Vient ensuite la pagination, ici on ne va pas paginer directement sur la requête, en insérant dans notre requête SQL un offset et un limit.

Ici on va paginer sur un array, grace à la fonction array_slice, qui nous ramène une portion seulement d’un tableau, celle notamment définie par nos variables $offset, et $nbre_post_page.

Ensuite, en amont de notre liste de messages, on va définir l’origine du message, grâce notamment à la fonction in_array qui va lier le  message à son origine.

On affiche donc une enveloppe fermée si le message n’est pas lu, et ouvert si le message a été lu.  On extrait les données de notre tableau général que l’on met en forme grâce à nos classes bootstrap.

Enfin, la fonction size_of nous retourne le nombre total de messages et permettant à  fonction de pagination de calculer le nombre de page à afficher( dans la pagination)..la voici( à insérer dans functions.php ).

function pagination($data) {

$page_total = $data[maxpost] / $data[nbre_post_par_page];
$page_total = ceil($page_total);

$nav = array();

for ($i = 1; $i <= $page_total; $i++) {
if ($i == $data[npage]) {
$class = "active";
} else {
$class = "";
}
$nav[] = '<li class="' . $class . '"><a href="' . $data[url] . '?npage=' . $i . '&idcat=' . $data[idcat] . '">' . $i . '</a></li>';
}

$navls = "<ul class='pagination pull-right'>";
$navls.= implode("", $nav);
$navls.= "</ul>";
return $navls;
}

Enfin, pour terminer, comme on affiche directement l’ouverture du message par une enveloppe ouverte, sans rechargement de page, on utilise de l’ajax : (à insérer dans message.php).

<script type="text/javascript">

jQuery(document).ready(function() {
jQuery(".msg_uniq").click(function() {

var idmsg = jQuery(this).attr('data-idmsg');
var nonce = jQuery(this).attr("data-nonce");
var origin = jQuery(this).attr("data-origin");
jQuery(this).children(".col-lg-9").children(".msg_content").slideToggle();
jQuery(this).children(".col-lg-1").children("img#monImage").attr('src', '<?php echo get_bloginfo(stylesheet_directory) ?>/img/msg_open.png');
jQuery.ajax({
url: "<?php echo admin_url('admin-ajax.php'); ?>",
type: "GET",
data: {action: "add_msg_vue", idmsg: idmsg, iduser:<?php echo $iduser; ?>, nonce: nonce, origin: origin},
success: function(html) {
},
error: function() {
}
});
jQuery(this).children(".col-lg-1").children("img#monImage").attr('src', '<?php echo get_bloginfo(stylesheet_directory) ?>/img/msg_open.png');
});
});
</script>

Les fichiers

voici ma page message.php en entier:

<?php
/*
Template Name: Messages
*/

global $current_user;
get_currentuserinfo();
$iduser = $current_user->ID;


if ($_POST[action] == "enr") {
if (!isset($_POST[iddest])) {
$hasError = true;
} else {
$iddest = $_POST[iddest];
}
if ($_POST[message_ok] == "") {
$hasError = true;
} else {
$message_ok = $_POST[message_ok];
}
if (!isset($_POST[titre])) {
$error = 'Indiquez votre titre.';
$hasError = true;
} else {
$titre = $_POST[titre];
}
if (!isset($_POST[msg])) {
$error = 'Entrez votre message.';
$hasError = true;
} else {
$msg = $_POST[msg];
}
//
// si il y au moins un resultat
$data = array(
'iduser' => $iduser,
'iddest' => $iddest,
'message_ok' => $message_ok,
'titre' => $titre,
'msg' => $msg
);
add_msg($data);
//recuperation des donnees user et son mail
$userdata = get_userdata($iddest);
if ($userdata) {
$userdata->user_email;
// print_r($userdata->user_email);
$datamsg = '
<span style="font-size:18px; color:#00395f"><strong>Bonjour Mr ';
$datamsg .= $userdata->last_name;
$datamsg .= '</strong> </span><br /><br />
Un nouveau message vous a été adressé.
Rendez-vous dès maintenant sur votre espace ';
$message = modeleHtml(array("msg" => $datamsg));
wp_mail($userdata->user_email, $titre, $message);
} else {
die('erreur !' . mysql_error());
}

}
get_header();
?>
<script type="text/javascript">

jQuery(document).ready(function() {
jQuery(".msg_uniq").click(function() {

var idmsg = jQuery(this).attr('data-idmsg');
var nonce = jQuery(this).attr("data-nonce");
var origin = jQuery(this).attr("data-origin");
jQuery(this).children(".col-lg-9").children(".msg_content").slideToggle();
jQuery(this).children(".col-lg-1").children("img#monImage").attr('src', '<?php echo get_bloginfo(stylesheet_directory) ?>/img/msg_open.png');
jQuery.ajax({
url: "<?php echo admin_url('admin-ajax.php'); ?>",
type: "GET",
data: {action: "add_msg_vue", idmsg: idmsg, iduser:<?php echo $iduser; ?>, nonce: nonce, origin: origin},
success: function(html) {
},
error: function() {
}
});
jQuery(this).children(".col-lg-1").children("img#monImage").attr('src', '<?php echo get_bloginfo(stylesheet_directory) ?>/img/msg_open.png');
});
});
</script>

<div class="bandeau">
<div class="container">
<h1><?php the_title(); ?></h1>
</div>
</div>

<div class="container">
<div class="row">
<div class="col-lg-9">

<?php if ($_POST[action] == "enr") { ?>
<div class="panel panel-success confirmation">
<div class="panel-heading">Votre message a bien été envoyé</div>
</div>
<?php } ?>

<?php
$userid = $_GET['iddest'];
$userdata = get_userdata($userid);
if ($userdata) {
// print_r($userdata->data);
echo ' . <form method="POST" class="formulaire">
<div>
<h2>Envoyez un Message à :
' .
$userdata->last_name . ", " . $userdata->first_name . '
</h2>
</div>
<div class="form-group">
<label for="titre">Titre: </label>
<input type="text" class="form-control" name="titre" required value=" ' . $_POST[titre] . '" id="titre"/>
</div>
<div class="form-group">
<label for="msg">Votre message : </label>
<textarea class="form-control" rows="5"name="msg" value="' . $_POST[msg] . '" id="msg" required></textarea>
</div>
<div class="form-group">
<input type="hidden" class="form-control" name="iddest" required value="' . $_GET[iddest] . '" id="iddest"/>
<input type="hidden" class="form-control" name="message_ok" required value="' . $_GET[message_ok] . '" id="message_ok"/>
</div>
<input type="hidden" name="action" value="enr" />
<button name="submit" id="submit" type="submit" class="btn btn-default">Envoyer</button>
</form>
</div> .';
} else {
// echo "utilisateur inconnu";
?>
</div>
<?php }; ?>
<div class="col-lg-9">
<h2>Retrouvez tous vos messages</h2>
<!--<p class=" gris">  Cras elementum ultrices diam...</p>-->
<?php

//première requet et boucle pour selectionner tous les messages qui sont vus
//on insère le résultat de notre requete dans une variable $origin
//on boucle notre tableau $origin et on lie l'origine au message
$origin = $wpdb->get_results("SELECT * FROM messages_vues WHERE iduser ='" . $iduser . "'");
for ($i = 0; $i < count($origin); $i++) {
$msg_vue[$origin[$i]->origin][] = $origin[$i]->idmsg;
}


//Definition tableau
global $wpdb;
$msg = $wpdb->get_results("SELECT * FROM message WHERE iddest ='" . $iduser . "'");
for ($i = 0; $i < count($msg); $i++) {
$tabmsg[$msg[$i]->dateenr] = array(
id => $msg[$i]->idmsg,
titre => $msg[$i]->titre,
message => $msg[$i]->msg,
origin => "msgprive",
expediteur => $userdata->last_name . $userdata->first_name
);
}
//Remise du tableau ordre chrono
ksort($tabmsg);
$tabmsg = array_reverse($tabmsg);

//Pagination array calcul de l'offset et limit
if (empty($_GET[npage])) {
$npage = "1";
} else {
$npage = $_GET[npage];
}
$nbre_post_page = 10;
// Calcul de l'offset
$offset = $npage * $nbre_post_page - $nbre_post_page;
$tab = array_slice($tabmsg, $offset, $nbre_post_page);
foreach ($tab as $key => $value) {
if ($value[origin] == 'msgprive') {
$value[expediteur] = $userdata->last_name . $userdata->first_name;

}


//liste message
// for($i=0;$i<count([$origin[$i]->origin]);$i++){
if (!empty($msg_vue[$value[origin]]) && in_array($value[id],$msg_vue[$value[origin]]) ) {
echo '<div class="row msg_uniq">';
$imgvu = "msg_open.png";
} else {
$nonce = wp_create_nonce("add_msg_vue_nonce");

echo '<div class="row msg_uniq" data-idmsg="' . $value[id] . '" data-nonce="' . $nonce . '"data-origin="' . $value[origin] . '"data-iduser="' . $value[iduser] . ' " data-vue="' . $value[idvue] .'">';
$imgvu = "msg_new.png";
}
echo '
<div class="col-lg-1 bleu_typo msg_date">' . date("d/m", strtotime($key)) . '</div>
<div class="col-lg-1"><img id="monImage" src="' . get_bloginfo(stylesheet_directory) . '/img/' . $imgvu . '" class="img-responsive"/></div>
<div class="col-lg-9">
<strong>De : ' . $value[expediteur] . '</strong><br/>' . $value[titre] . '
<div class="msg_content collapse" >' . $value[message] . '</div>
</div>
<div class="col-lg-1"><img id="monpointer" src="' . get_bloginfo(stylesheet_directory) . '/img/msg_arrow_close.png" class="img-responsive"/> </div>
';
echo '</div>';
}
//
// }

?>
<?php
$data = array('iduser' => $iduser);
$nbre_page_total = sizeof($tabmsg);
// Affiche la pagination
$navigation = pagination(array("url" => "./", "offset" => $offset, "npage" => $npage, "maxpost" => $nbre_page_total, "nbre_post_par_page" => $nbre_post_page));
echo $navigation;
?>

</div>
<?php
get_sidebar();
?>
</div>
<?php
get_footer();
?>

Puis la page des fonctions:

add_action("wp_ajax_add_msg_vue", "add_msg_vue");

function add_msg_vue() {

global $wpdb;

if (!wp_verify_nonce($_REQUEST['nonce'], "add_msg_vue_nonce")) {
exit("bye");
}

if (!empty($_GET[iduser]) && !empty($_GET[idmsg])) {
$sql = "select idvue from messages_vues where iduser = '$_GET[iduser]' and idmsg = '$_GET[idmsg]' and origin = '$_GET[origin]'";
$mylink = $wpdb->get_results($sql);

if (empty($mylink)) {
$sql = "insert into messages_vues (iduser,idmsg,dateenr,origin) values ('$_GET[iduser]','$_GET[idmsg]',now(),'$_GET[origin]')";
$wpdb->query($sql);
}
}
}


function add_msg($data) {

global $wpdb;

if (!empty($data[iddest]) && !empty($data[message_ok]) && !empty($data[titre]) && !empty($data[msg])) {
$sql = "insert into message (idmsg,iduser,iddest,titre,msg,dateenr,datevue) values ('$data[idmsg]','$data[iduser]','$data[iddest]','$data[titre]','$data[msg]',now(),'$data[datevue]')";

$wpdb->query($sql);
}
}

function pagination($data) {

$page_total = $data[maxpost] / $data[nbre_post_par_page];
$page_total = ceil($page_total);

$nav = array();

for ($i = 1; $i <= $page_total; $i++) {
if ($i == $data[npage]) {
$class = "active";
} else {
$class = "";
}
$nav[] = '<li class="' . $class . '"><a href="' . $data[url] . '?npage=' . $i . '&idcat=' . $data[idcat] . '">' . $i . '</a></li>';
}

$navls = "<ul class='pagination pull-right'>";
$navls.= implode("", $nav);
$navls.= "</ul>";
return $navls;
}