LikeIt: je like it like that

Voici une feature que je n'avais pas prévue de prime abord mais qui m'a été rapidement demandée par les utilisateurs de cette version sociale de pluxml: ("wesh, c'est pas possible de liker... tu devrais l'ajouter ce serait trop dard") ("wesh derechef")
Du coup, je m'y suis collé rapidement et voilà: un plugin qui permet de manifester en un clic son approbation sur un article ou un commentaire, mais aussi d'afficher une liste de ceux qui approuvent également...
Fonctionnement:
Le plugin utilise des hooks perso et un script php chargé de sauver les modifications dans le fichier de données spécifique au plugin.
public function ThemeEndBody(){
// ajoute le js nécessaire à la gestion du clic et de la gestion en ajax
echo '
<script>
function save_like(obj){
href=obj.getAttribute("href");
request = new XMLHttpRequest;
request.open("GET",href, true);
request.send();
// Gestion de la réponse du serveur
request.onreadystatechange=function(){
if (request.readyState==4 && request.status==200){
rep=request.responseText;
obj.innerHTML=rep;
obj.classList.toggle("like");
obj.classList.toggle("dislike");
}
}
return false;
}
</script>
';
}
public function likeButton_here($param){ // array('article','nb')
if (empty($param)||empty($param[1])||empty($param[0])){return;}
$likes=$this->load();
// déterminer si le user a déjà liké cet article/comment : non=> like / oui => dislike
if (in_array($_SESSION['user'], $likes[$param[0]][$param[1]])){
$msg='Ne plus aimer';
$class='dislike';
}else{
$msg='Aimer';
$class='like';
}
echo '<p class="like_button "><a class="'.$class.'" onclick="save_like(this);return false;" href="https://www.warriordudimanche.net/'.PLX_PLUGINS.'likeIt/savelike.php?number='.$_SESSION['user'].'&what='.$param[0].'&id='.$param[1].'">'.$msg.'</a></p>';
}
public function whoLikesIt($param){ //array('article','nb') echo liste des gens qui aiment
$likes=$this->load();
if (empty($param[0])||empty($param[1])||empty($likes[$param[0]][$param[1]])){return;}
foreach ($likes[$param[0]][$param[1]] as $user){
$users[]=$this->getName($user);
}
echo '<div class="who_likes_it">'. implode (',',$users).' aime';
if (count($users)>1){echo 'nt';}
echo '</div>';
}</pre>
Le script savelike.php:
<?php
session_start();
function load(){
$filename='likes.dat';
if (is_file($filename)){return unserialize(file_get_contents($filename));}else{return array('article'=>array(),'comment'=>array());}
}
function save($data){
$filename='likes.dat';
file_put_contents($filename,serialize($data));
}
gestion ajax des likes (via post)
if (
!empty($_GET)
&& isset($_SESSION["domain"])
&& isset($_SESSION["user"])
&& isset($_SESSION["profil"])
&& isset($_SESSION["hash"])
&& isset($_SESSION["lang"])
&& $_SESSION["user"]!=""
){
// si connecté et loggué
$likes=load();
//
foreach ($_GET as $k=>$v){$get[$k]=strip_tags($v);}
if (!empty($get['what']) && !empty($get['id']) && !empty($get['number']) ){
//gestion des like sur des articles
if (empty($likes[$get['what']][$get['id']])){$likes[$get['what']][$get['id']]=array();}
$tf=array_search($_SESSION['user'], $likes[$get['what']][$get['id']]);
if ($tf!==false){
$msg='Aimer';
unset($likes[$get['what']][$get['id']][$tf]);
save($likes);
}else{
$msg='Ne plus aimer';
$likes[$get['what']][$get['id']][]=$get['number'];
save($likes);
}
exit($msg);
}
}
?>
Je pense qu'il aurait sans doute été plus judicieux d'intégrer directement les nouvelles données dans le fichier de l'article, mais ça s'avérait un peu trop pointu pour moi et le ratio temps consommé / résultat obtenu me paraissait peu satisfaisant 
Le script js pour l'appel en ajax utilise .classList.toggle pour basculer l'état du bouton like, ce qui peut poser problème sur certains(!) navigateurs... Pour le moment, je n'ai constaté aucun problème et mes users non plus...
Utilisation:
Il suffit de placer des appels aux hooks aux endroits où l'on souhaite voir le bouton like ou la liste des gens qui likent:
<?php eval($plxShow->callHook('whoLikesIt',array( 'article',$plxShow->artID() ) ) );?>
<?php eval($plxShow->callHook( 'likeButton_here',array( 'article',$plxShow->artID() ) ) );?>
Pour pouvoir différencier les likes d'articles de ceux des commentaires on spécifie un array en argument:
array('article|commentaire','ID_DE_LARTICLE|ID_DU_COMENTAIRE');
ce qui donne :
ou 
J'ai opté pour ce système car il me permet d'éventuellement étendre les likes à d'autres éléments du site (si j'ajoutais une galerie, un calendrier pour convenir d'une date etc, ce serait facilement adaptable)
Allez savoir ce que les utilisateurs vont encore me demander !!! 

✍ Écrire un commentaire
les commentaires relevant du SPAM seront filtrés et dégagés direct...