[RESOLU] Système de notation

Eléphant du PHP | 283 Messages

27 sept. 2014, 18:14

Bonjour à tous,

Je rencontre actuellement un problème avec la mise en place d'un système de notation concernant l'ajout d'une news.

Je fonctionne avec un principe d'étoile et je voudrais insérer la note du posteur de sujet dans la bdd et que cela s'affiche via le système d'étoile pour le lecteur.

Voici mon code actuel :
if(isset($_POST['ajout_news'])) {
		if(!empty($_POST['titre_news']) && !empty($_POST['contenu_news'])) {
				$titre = $_POST['titre_news'];
				$genre = $_POST['genre'];
				$contenu = $_POST['contenu_news'];
				$img = $_POST['img'];
				$date = date('Y-m-d');
				$addNewsQuery = $bdd->prepare("INSERT INTO `news` VALUES ('', ?, ?, ?, ?, ?, ?)") or die(mysql_error());
				$addNewsQuery->execute(array($titre, $date, $contenu, $genre, $img, '1')) or die(mysql_error());
			
			}	
				
	}
//Fin des traitement de formulaire

Et voici mon code html concernant la notation :

Code : Tout sélectionner

<tr> <td align="right" valign="top"><span style="font-weight:bold;">Note:</span></td> <td align="left"> <div class="rating"><!-- --><a href="#5" title="Donner 5 étoiles">☆</a><!-- --><a href="#4" title="Donner 4 étoiles">☆</a><!-- --><a href="#3" title="Donner 3 étoiles">☆</a><!-- --><a href="#2" title="Donner 2 étoiles">☆</a><!-- --><a href="#1" title="Donner 1 étoile">☆</a> </div> </td> </tr>
Merci d'avance à ceux qui pourront m'aider dans cette impasse. :)

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

27 sept. 2014, 18:50

Salut,

Le plus simple reste de stocker les notes etre calculer la note a l'affichage. (Bien-sûr çe ci peux être mis en cache en cas de besoin de performance, l'utilisation d'une udf SGBD est aussi une bonne idée ;) )

Donc, il faut une table, disons "vote", avec comme colonnes :
- idvote : entier, clef primaire.
- idnews : entier, clef étrangère de la table news
- note : entier (de préférence avec une contrainte Check pour etre certains que la note soit entre zero et cinq)
- autre colonne que tu juge utile (par exemple un id utilisateur si seule les membres peuvent voter, histoire d'éviter les doublons dans les votes).

Le calcul est simple
Moyenne = select sum(note) from vote where idnews=xxx / select count(1) from vote where idnews=xxx

Pour l'insertion c'est pareil c'est simple il te faut la note, l’Id de la news rien de complexe pour avoir les infos ;)

Pour afficher les étoiles il va devoir faire un arrondis (il y a peut de chances que les notes rondes).

En php round ou ceil suivant çe que tu veux (j'ai une préférence pour round).

@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 283 Messages

27 sept. 2014, 22:06

D'accord, sauf que la je veux qu'il n'y ait que le posteur de la news qui donne son avis via le système de notation en même temps que l'envoie de la news.
Donc je comptais stocker dans la dite table "news".

Il faut donc que je rajoute un champ note.

Par contre je ne vois pas comment stocker en fonction du nombre d'étoile et comment afficher le résultat dans la news ?

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

27 sept. 2014, 22:35

c'est étonnant de vouloir demander à quelqu'un de ce noter ;)

Ceci dit je comprend mieux.

Donc il te faut un champ de formulaire caché (type hidden) avec un comme valeur par défaut.

Ensuite il te faut une fonction javascript qui va modifier la valeur de ce champs en fonction de son paramètre.

tu ajoute l'utilisation de cette fonction dans l'attribut on click des liens avec une valeur différente.

Lorsque l'utilisateur clique sur une image cela modifie le champs caché que tu pourras ensuite utiliser pour alimenter ta base.

exemple

[javascript]function valeurNote(note) {
// modification de la valeur du champs avec la note.
}[/javascript]
<a href="#5" title="Donner 5 étoiles" onclick="valeurNote(5);">☆</a>
idem pour chaque lien.

Tu peux utiliser la fonction javascript pour modifier aussi la couleur des étoiles "en dessous" (ainsi que la concernée) pour marquer la sélection correctement ;)



@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 283 Messages

27 sept. 2014, 23:17

D'accord merci, sinon il n'est pas possible de faire quelque chose de plus simple ?
Par exemple un select pour choisir la note de 1 à 5 et ensuite on récupère la note et on l'affiche sous forme d'étoile ?

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

29 sept. 2014, 15:55

si, tout est possible :)
un simple select que tu alimente avec une boucle for.
La colonne en base tu ne peux pas y couper ;)

Pour l'affichage une autre boucle for pour afficher autant d'étoile qu'il faut pour la note ;)

je te propose une solution plus "user friendly" c'est tout.


@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 283 Messages

16 nov. 2014, 18:50

Du coup j'ai réussi à faire le système de notation avec étoile mais je ne sais pas comment faire pour conserver la note d'un membre car pour le moment j'ai masqué les étoiles une fois que le membre à voté.
Autre soucis, je ne sais pas comment faire pour empêcher de renvoyer l'url et que ça vote une nouvelle fois.
<?php
if (isset ($_GET['id'])&& isset ($_GET['stars'])){
	            $posteur = $_SESSION['id'];
				$id_news= $_GET['id'];
				$note = $_GET['stars'];
				$addnote = $bdd->prepare("INSERT INTO `note` VALUES ('', ?, ?, ?)");
				$addnote->execute(array($posteur, $id_news, $note));	
	echo '<div id="alerte">Votre note a bien été pris en compte !</div>';		
}
?>
	<style type="text/css">
		/*  
		 * Rating styles
		 */
		.rating {
		    width:220px;
            margin-top:36px;
			font-size: 25px;
			overflow:hidden;
		}
		.rating a {
			float:right;
			color: #aaa;
			text-decoration: none;
			-webkit-transition: color .4s;
			-moz-transition: color .4s;
			-o-transition: color .4s;
			transition: color .4s;
		}
		.rating a:hover,
		.rating a:hover ~ a,
		.rating a:focus,
		.rating a:focus ~ a		{
			color: orange;
			cursor: pointer;
		}
		.rating2 {
			direction: rtl;
		}
		.rating2 a {
			float:none
		}
		
	</style>
<?php
$posteur = $bdd->quote($_SESSION['id']);
$id_news= $bdd->quote($_GET['id']);
$getNewsQuery = $bdd->prepare("SELECT * FROM `note` WHERE posteur=$posteur AND id_news=$id_news");
if( $getNewsQuery->fetch() !== false)
{  
   // Le membre a déjà voté
 }
else
{
   echo '<div class="rating rating2"><!--
  		--><a href="?mod=news&id='.$_GET['id'].'&stars=10" title="Donner 10/10">★</a><!--
 		--><a href="?mod=news&id='.$_GET['id'].'&stars=9" title="Donner 9/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=8" title="Donner 8/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=7" title="Donner 7/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=6" title="Donner 6/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=5" title="Donner 5/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=4" title="Donner 4/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=3" title="Donner 3/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=2" title="Donner 2/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=1" title="Donner 1/10">★</a>
	</div>';
}
?>
Merci d'avance à ceux qui pourront m'aider. ;)

Nestecha
Invité n'ayant pas de compte PHPfrance

16 nov. 2014, 22:40

Comment ça pour "conserver" la note d'un membre ? Pas compris ce soucis.

Pour l'empêcher de re-voter, il faut que tu regardes avant si une note faite sur cette news existe déjà.

Donc tu fais un select dans vote où id_news est égale à la news dans laquelle l'utilisateur veut voter. Si tu n'obtiens aucun résultat, alors tu lances le code pour voter, sinon tu peux afficher un message d'erreur ou autre.

Eléphant du PHP | 283 Messages

16 nov. 2014, 23:31

D'accord merci de ton aide Nestecha.
En fait je voudrais qu'une fois que le membre a voté, que son nombre d'étoile reste coloré de façon a ce qu'il voit ce qu'il a voté pour cette news.

Du coup, ce n'est pas ce que j'ai déjà fait ? :
<?php
$posteur = $bdd->quote($_SESSION['id']);
$id_news= $bdd->quote($_GET['id']);
$getNewsQuery = $bdd->prepare("SELECT * FROM `note` WHERE posteur=$posteur AND id_news=$id_news");
if( $getNewsQuery->fetch() !== false)
{  
   // Le membre a déjà voté
 }
else
{
   echo '<div class="rating rating2"><!--
                --><a href="?mod=news&id='.$_GET['id'].'&stars=10" title="Donner 10/10">★</a><!--
                --><a href="?mod=news&id='.$_GET['id'].'&stars=9" title="Donner 9/10">★</a><!--
                --><a href="?mod=news&id='.$_GET['id'].'&stars=8" title="Donner 8/10">★</a><!--
                --><a href="?mod=news&id='.$_GET['id'].'&stars=7" title="Donner 7/10">★</a><!--
                --><a href="?mod=news&id='.$_GET['id'].'&stars=6" title="Donner 6/10">★</a><!--
                --><a href="?mod=news&id='.$_GET['id'].'&stars=5" title="Donner 5/10">★</a><!--
                --><a href="?mod=news&id='.$_GET['id'].'&stars=4" title="Donner 4/10">★</a><!--
                --><a href="?mod=news&id='.$_GET['id'].'&stars=3" title="Donner 3/10">★</a><!--
                --><a href="?mod=news&id='.$_GET['id'].'&stars=2" title="Donner 2/10">★</a><!--
                --><a href="?mod=news&id='.$_GET['id'].'&stars=1" title="Donner 1/10">★</a>
        </div>';
}
?>
 

Nestecha
Invité n'ayant pas de compte PHPfrance

16 nov. 2014, 23:54

Pas vraiment non, puisqu'il lui suffit d'ouvrir une nouvelle fenêtre de navigation privée pour que $_SESSION disparaisse et qu'il puisse voter à nouveau !

Si tu veux faire ça sans changer de page, il faut utiliser de l'AJAX (pour que la note s'insère tout de même dans la base de données).

Si tu t'en fiches que la page s'actualise lorsqu'il aura voté, et bien lorsqu'il réactualisera la page il devrait voir la note qu'il a mis, si tu as déjà fait l'affichage.

Eléphant du PHP | 283 Messages

17 nov. 2014, 11:13

Donc en fait je dois remplacer mon session id pour $posteur par le pseudo du joueur pour voir s'il y a déjà un enregistrement avec ce pseudo pour cette id de news ?

Nestecha
Invité n'ayant pas de compte PHPfrance

17 nov. 2014, 16:14

Oui c'est ca !

Eléphant du PHP | 283 Messages

27 nov. 2014, 19:44

D'accord merci, donc c'est bon pour la vérification, par contre je ne vois toujours pas comment conserver la note du membre une fois qu'il a voté sous forme d'étoiles.
Par exemple s'il a voté 7/10 je voudrais 7 étoiles en jaune et les autres en grises.

Mais je vois pas du tout comment faire en fait. Des idées ?

Eléphant du PHP | 283 Messages

03 déc. 2014, 14:58

Salut,

Je suis partie la dessus :
<?php
$posteur = $bdd->quote($_SESSION['id']);
$id_news= $bdd->quote($_GET['id']);
$getNewsQuery = $bdd->query("SELECT * FROM `note` WHERE posteur=$posteur AND id_news=$id_news");
if( $getNewsQuery->fetch() !== false )
{  
// Etoiles jaunes
 
$i = 0;
while ($i != $vote) {
echo $etoilejaune;
$i++;}
 
// Etoiles grises
 
$i = 0;
while ($i != (10 - $vote)) {
echo $etoilegrise;
$i++;}
 }
else
{
   echo '<div class="rating rating2"><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=10" title="Donner 10/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=9" title="Donner 9/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=8" title="Donner 8/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=7" title="Donner 7/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=6" title="Donner 6/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=5" title="Donner 5/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=4" title="Donner 4/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=3" title="Donner 3/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=2" title="Donner 2/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=1" title="Donner 1/10">★</a>
	</div>';
}
?>
Mais le problème c'est que je ne vois pas comment préciser les variables $etoilejaune et $etoilegrise.

Des idées ?

Eléphant du PHP | 283 Messages

03 déc. 2014, 21:10

Donc j'ai essayé en mettant des images pour tester si ça fonctionne sauf que ça ne me met 10 étoiles grises et la soustraction de 10 - note du posteur ne fonctionne pas.
<?php
$posteur = $bdd->quote($_SESSION['id']);
$id_news= $bdd->quote($_GET['id']);
$getNewsQuery = $bdd->query("SELECT id,posteur,id_news,note AS '$vote' FROM `note` WHERE posteur=$posteur AND id_news=$id_news");
if( $getNewsQuery->fetch() !== false )
{  

// Etoiles jaunes 
$etoilejaune = '<img src="./interface/etoile-pleine.png"/>';
$i = 0;
while ($i != $vote) {
echo $etoilejaune;
$i++;}
 
// Etoiles grises
 $etoilegrise = '<img src="./interface/etoile-vide.png"/>';
$i = 0;
while ($i != (10 - $vote)) {
echo $etoilegrise;
$i++;}
 }
else
{
   echo '<div class="rating rating2"><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=10" title="Donner 10/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=9" title="Donner 9/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=8" title="Donner 8/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=7" title="Donner 7/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=6" title="Donner 6/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=5" title="Donner 5/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=4" title="Donner 4/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=3" title="Donner 3/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=2" title="Donner 2/10">★</a><!--
		--><a href="?mod=news&id='.$_GET['id'].'&stars=1" title="Donner 1/10">★</a>
	</div>';
}
?>
Merci d'avance à ceux qui pourront m'indiquer ou se trouve mon erreur. ;)