Gestion affichage Guestbook avec Checkbox

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Gestion affichage Guestbook avec Checkbox

Re: Gestion affichage Guestbook avec Checkbox

par moogli » 22 juin 2011, 18:18

de rien :mrgreen:

Re: Gestion affichage Guestbook avec Checkbox

par Ez3kiel » 22 juin 2011, 16:49

Merci ! Je comprends mieux maintenant ! :mrgreen:
J'avoue j'ai dû relire plusieurs fois ton "cours", mais j'ai fais quelques petits scripts pour essayer, et niquel. :)
C'est très ressemblant aux tableaux vb.net et vba en fait ... ^^
Au revoir et merci encore de ton aide !

Re: Gestion affichage Guestbook avec Checkbox

par moogli » 16 juin 2011, 12:15

bon en fait les tableaux c'est pas sorcier ;)

tu te souvient des tableaux a deux entrées que tu fesais en math en primaire ? ben c'est pareil.

un tableau, c'est une variable dans laquelle on peux en stocker plusieurs "dans des cases" différentes, c'est un peu une étagère à une seul colonne. et tu fait référence à chaque "case" de l'étagère par un chiffre (le premier étant zéro parce qu'en info on commence à compter à zéro et pas à un ;) ).

donc graphiquement tu a

_____________
| case zéro | => index zéro
_____________
| case un | => index un
_____________
| case deux | => index deux
_____________
| case trois | => index trois

etc

En php tu peux déclarer un tableau avec $tableau = array(), ou simplement en affectant dirrectement quelque chose avec les [] $tableau[] = 'le contenu de la nouvelle case'; cette syntaxe a l'avantage de créer le tableau et en même temps d'ajouter une nouvelle case (en bas de l'étagère ;) ).

la taille n'est, théoriquement, pas limités. Les index peuvent être numérique, au aussi alphabétique (donc mon tableau pourrait être
$tableau['ma premiere case'] = 'la valeur de la première case';
$tableau['ma deuxième case'] = 'la valeur de la deuxième case';
$tableau['ma troisème case'] = 'la valeur de la troisème case';
________________________________
| la valeur de la première case | => index : 'ma premiere case'
________________________________
| la valeur de la deuxième case | => index : 'ma deuxième case'
________________________________
| la valeur de la troisème case | => index : 'ma troisème case'

pour avoir une valeur tu utilise l'index (le numéro ou la chaine de caractère qui représente la ligne)

donc : echo $tableau['ma deuxième case']; va afficher " la valeur de la deuxième case "

ce principe est extrémement pratique en programmation.

Dans le cas qui nous interresse, j'ai pas compris qu'il y avait plusieurs lignes (d'après la capture d'écran).
Puisse que tu en a plusieurs le tableau devient indispensable, car avec la notation name="lenom[]" dans le champs hml, php va récupérer un tableau dans $_POST['lenom'] avec toute les cas qui ont étaient cochées (enfin la valeur de la case cochées).
si tu fait name="lenom[index]" tu va pouvoir passer deux infos. Par exemple si tu souhaite passer et la clef et une valeur (qui peux prendre plusieurs etat) tu met la valeur dans le value et tu obtient et la clef et la valeur à la validation du formulaire ;)

avec mon exemple tu utilise plein de tableau :
- le tableau session dans lequel tu met un tableau (etat) qui va contenir l'état de la case avant modif
$_SESSION['etat'][ 'la clef primaire dans la table'] = 'valeur correspondante';
et ceci pour toutes les lignes de la table mysql (qui au final est un tableau aussi, la clef primaire sert d'index ;)). ce qui fait que tu pourrais valider tous les champs d'un coup.

Il faut que tu ajoute un session_start(); à la première ligne du fichier (enfin la 1ère de la page appelé par le navigateur ;) ).
Lorsque tu affiche le formulaire html tu commence le formulaire avant la table qui affiche les message (tu va faire qu'un seul formulaire ;) )
ensuite dans la case ou tu affiche la checkbox
<input type="checkbox" name="affichage[]" value="<?php $Enregistrement->id; ?>"
<?php if ($Enregistrement->afficher == '1'){ echo 'Checked';} 
$_SESSION['etat'][ $Enregistrement->id] = $Enregistrement->afficher; 
?>/>
Avec ça tu a un tableau dans la variable de session etat qui va contenir l'état de tous ce que tu affiche, la clef du tableau correspond à l'id dans la table.

ensuite vient le traitement du formulaire :
<?php
// on vérifie que le formulaire à été posté correctement
if (isset($_POST['affichage']) && is_array($_POST['affichage']) {
	//initialisation des tableaux
	$azero=array(); // ce tableau va contenir l'id des messages que dont l'état va passer a zéro
	$aun = array(); // ce tableau va contenir l'id des messages que dont l'état va passer a un
	// on parcourt le tableau de session qui contient l'état précédent
	foreach ($_SESSION['etat'] as $id => $etat) {
		// on regarde si on a l'id dans le tableau du formulaire
		if (isset ($_POST['afficher'][$id])) {
			// oui ça veux dire qu'il est coché dans le formulaire
			// on regarde si la valeur a changée si c'est le cas c'est qu'elle est passée de 0 à 1
			if ($_POST['afficher'][$id] != $etat)
				$aun[] = $id; // valeur changée on l'ajoute dans le tableau des champs a mettre a un
		}
		else {
		// pas présent dans le tableau du forulaire donc non coché donc à mettre a zéro
			if ($etat == 1)
				// si l'ancien état était 1 alors on le met à zéro (sinon c'est qu'il était déja a zéro ;)
				$azero[] = $id;
	}
}
// les requetes SQL 
$miseAzero = 'update tablemessage SET afficher=0 where id in ('.implode(',',$azero).');';
$miseAun   = 'update tablemessage SET afficher=1 where id in ('.implode(',',$aun)  .');';
mysql_query($miseAzero);
mysql_query($miseAun);

//et voila le tour est jouer ;)
?>
Le désavantage de cette solution :
- si tu affiche tout les messages a la 1 étape (le formulaire) ben tu va mettre beaucoup de chose en session et donc ralentir la chose et le traitement du formulaire. mais ça va fonctionner :)

Avantage :
- si tu met en place une pagination ou même un filtrage (c'est mieux de ne pouvoir afficher qu'une vingtaine de ligne que 400000 ;), voir même de n'afficher que les messages non valider ;)) Et bien dans ces deux cas la validation fonctionne et est indépendante de l'affichage, filtre ou pas, pagination ou pas le code fonctionne ;)

pour ce qui est du foreach c'est relativement en fait il prmet de parcourir un tableau (il géère tous seul l'index, ce que toi tu fait avec la boucle for) et il te fournit la clef du tableau (optionel) et la valeur
donc foreach( $tableau as $valeur) ou foreach($tableau as $key => $value). dans les {} tu peux directement utiliser $key ou $value pour traitement, tu peut même faire un $tableau[$key] = 'autre valeur';

c'est donc extremement pratique pour éviter de devoir calculer le nombre d'élément du tableau (pour pas dépasser) et de ne pas gérer l'index. bref autant en abuser ;)

autre chose, en php les objets peuvent aussi être parcouru comme un tableau (ce qui fait qu'en remplaçant le tableau par un objet tu pourra obtenir toute les propiétés publique ;) ).

voila j'espère ne pas être trop incompréhensible :)

@+

Re: Gestion affichage Guestbook avec Checkbox

par Ez3kiel » 16 juin 2011, 10:45

Bon et bien j'ai fais ma méthode et ça marche niquel. Mais je sais que ce n'est pas du tout optimisé...
Pour l'instant sur ma page de gestion il y a ça :
	<form action="#" method="POST" name="afficher" >

						<input type="checkbox" name="affichage" <?php if ($Enregistrement->afficher == '1'){ echo ' Checked ';} ?> onclick="document.location.href='AfficherLivre.php?id=<?php echo "$Enregistrement->id"; ?>&value=<?php echo "$Enregistrement->afficher;" ?>'" >
					</form>
Qui me renvoi donc sur la page où il y a le script de traitement :

<?php
		//Test les variables
		if(isset($_GET['id']) && ($_GET['value']))
		//récupération des variables
		$id=$_GET['id'];
		$value=$_GET['value'];

		//Si value vaut 0, alors la case était décochée
		if ($value == 0 )
		{
			$value = '1' ; //Donc value vaudra 1 car ça veut dire qu'elle vient d'être coché pour aboutir à ce script
		}
		else if ($value == 1 ) // Sinon inversement
		{
			$value = '0' ;
		}
		else
		{
			echo "Erreur dans l'url" ;
		}

		//appel au fichier "Connect.php" intégrant les constantes de connexion à la BDD 
		require("Connect.php"); 	 
		
		//connexion au serveur Mysql
		$cnx = mysql_connect(SERVEUR,NOM,MDP)or die("erreur de connexion au serveur mysql  : ".SERVEUR);
		
		//selection de la BDD 
		mysql_select_db(BASE, $cnx)or die ("erreur lors de la sélection à la BDD : " .BASE);
		
		//écriture de la requête
		$LaRequete = "Update guestbook SET afficher='$value' where id='$id'";
		

		
		//interrogation de la base à l'aide de la requête passé en paramètre
		$ResultatRequete = mysql_query($LaRequete) or die("Erreur SQL ! <br><br>".$LaRequete."<br><br>".mysql_error());

		mysql_close( $cnx );
			
		Header("location: ValiderLivre.php");
		

?>

Et j'affiche le tout sur ma page d'affichage avec restriction sur 'afficher' qui doit valoir 1 ...

Donc c'est 'résolu' ... MAIS je suis toujours preneur sur l'optimisation, ou je veux bien essayer de comprendre la proposition de Moogli. :)

Re: Gestion affichage Guestbook avec Checkbox

par Ez3kiel » 15 juin 2011, 19:08

Oula oula, tu mets mes 5 mois de connaissances en PHP à rude épreuve. #-o
Je n'ai jamais utilisé de tableau, mais je connais "vaguement" le principe avec le vb. Est-ce pareil en php ? (J'ai lu quelques explications sur des sites, mais c'était des tableaux statiques, on ne le remplissait pas avec des variables issues d'un mysql_fetch_object ... :| )

Et donc si je traduis, en newbie que je suis, ton idée, le but serait de récupérer tous les id des lignes du fetch_object qui ont 1 pour valeur au champs de la table 'afficher' (donc coché). Ce qui donnerait un tableau d'id qui ont 1 pour valeur du champs 'afficher' ?

Ensuite ... ensuite je me suis perdu dans ce que tu expliquais. :cry:

J'avais en tête de faire une case à cocher, et que lorsque l'on coche, ça nous propulse sur livredor_exec.php?id=$id&afficher=$afficher ($afficher valant 1 ou 0) qui contiendrait le script récupérant juste la valeur de $id et la valeur de $afficher dans l'URL. Pour ensuite faire " Si $afficher vaut 1 alors $afficher vaut 0 et Update guestbook set afficher = $afficher where id=$id et enfin header pour revenir à notre page affichant les checkbox immédiatement. (Et la modification sera déjà effective sur le panneau d'administration)
Voilà c'est l'idée que je m'étais faite, car comme je l'ai dis plus haut, je ne me suis jamais servi de tableau parce que je ne comprend pas très bien, alors je cherche toujours un échappatoire.
Cependant, je ne suis pas avare de connaissances, alors je veux bien essayer ta technique mais pour le moment je n'arrive pas à la comprendre.
Si tu veux bien me ré-expliquer avec moins de termes techniques ... Sinon c'est pas grave ne t'en fais pas, je comprend que tu ais mieux à faire. ^^

Ha et aussi, vu que le formulaire ici ne contient qu'une checkbox et un champs hidden, comment le soumettre à son action (donc le script php pour mettre à jour) sans son bouton submit ?

Ps: J'affiche les messages du livre sur une autre page encore où elle n'affiche que les messages dont $afficher vaut 1.

Merci de ta patience !

Re: Gestion affichage Guestbook avec Checkbox

par moogli » 15 juin 2011, 17:06

ben si mais pourquoi mettre deux champ au lieu d'un ? :mrgreen:

dans ce cas tu fait la meme chose pour le nomage du champ hidden que tu "affiche" a coté de la checkbox, les deux auront le même index, ensuite tu parcourt le tableau des checkboxs et récupère celui des id. mais bon c'est un peux plus compliqué et donc source d'anerie ;)


avec ton code
<input type="checkbox" name="afficher[]" value="<?php echo $Enregistrement->id; ?>"  heu j'te laisse gérer le checked tu a l'air de savoir faire ;)  />

dans le script cible tu va avoir $_POST['afficher'] qui sera un tableau qui ne contiendra les valeurs QUE des checkbox qui ont étaient cochée (essai en mettant un var_dump($_POST); en haut de ton script et va voir ce que sa donne ;)

ensuite avec ce que je t'ai donné tu fait la mise a jour. 

après si tu peux revenir en arrière (genre décocher) la c'est un plus "chaud". 

deux solutions, soit tu lock la table et tu passe tout a zéro puis tu utilise ma requete. 

soit tu optimise. donc la le mieux serait de faire la comparaison entre l'état avant le formulaire et l'état après, donc la je dirais qu'il te faut mettre cette état dans un tableau en session ($_SESSION['etat'][ $id ] = 1 ou 0) et quand tu valide tu compare ce que les deux

genre
[php]
<?php
$azero=array();
$aun = array();
foreach ($_SESSION['etat'] as $id => $etat) {
if (isset ($_POST['afficher'][$id])) {
// la ça veux dire qu'il est a un
if ($_POST['afficher'][$id] != $etat)
    $aun[] = $id;
}
else {
// pas présent dans le tableau du forulaire donc non coché donc zéro
if ($_POST['afficher'][$id] != $etat)
    $azero[] = $id;
}
//deux requetes pour la mise a un ou a zéro en utilisant le in comme dans mon premier exemple ;)
?>
l'avantage de cette solution ?
avec le if ($_POST['afficher'][$id] != $etat) je regarde si la case a changer de valeur et seulement dans ce cas la je l'ajoute au tableau qui contient les "id" dont on va modifie la valeur de la colonne afficher et donc moins de modif sur la table même s'il y a deux requetes ;)

@+

Re: Gestion affichage Guestbook avec Checkbox

par Ez3kiel » 15 juin 2011, 16:53

Mais ... je ne peux pas récupérer simplement l'id avec un champ hidden
<input type="hidden" name="id" value="<?php $Enregistrement->id; ?>">

Et faire ensuite
if (isset($_POST['id'])
$id=$_POST['id'];

$sql = "Update blabla set afficher = "1" ou "0" where id = '$id';"
Ps: Id est un entier auto-inc.

Re: Gestion affichage Guestbook avec Checkbox

par moogli » 15 juin 2011, 16:33

salut,

avant toute chose il faut nommer la checkbox avec la notation tableau afin de pouvoir récupérer toute les cases coché => name="afficher[]".

avec cela tu met en value l'id du message et ta requete devient
update tablemessage SET afficher=1 where id in ( liste des id);
en php ça devient
<?php
if (isset($_POST['afficher']) && is_array($_POST['afficher'])) {
    // mise a jour de la table
    $sql = 'update tablemessage SET afficher=1 where id in ('.implode(',',$_POST['afficher']).');';
    //query
}
?>
Bon après tu peux aussi vérifier si les valeurs sont correct et qu'il s'agit bien de chiffre en utilisant par exemple array_map ou array_walk et une fonction de callback qui test que la chaine est bien un entier (si c'est bien le cas) et à la limite ajouter un mysql_real_escape_string ou équivalent ;)


@+

Gestion affichage Guestbook avec Checkbox

par Ez3kiel » 15 juin 2011, 16:19

Bonjour !

Je suis en train de faire un Guestbook, avec possibilité d'afficher ou non les messages depuis l'interface d'administration, qui ressemble à ceci :
Image

J'ai réussi à faire en sorte que la Checkbox soit checked si le champ "afficher" de la table vaut 1 et pas cheked si il vaut 0.

Mais ensuite, c'est la panne, je ne sais pas trop comment m'y prendre pour que lorsque l'admin cliquera dessus, ça fera l'UPDATE sur la table. Que donc, si coché, alors SET afficher=1, sinon si décoché SET afficher = 0, sachant que pour qu'il y ai la checkbox, il faut un formulaire, mais en l’occurrence ici il ne contiendra que 2 champs, le checkbox, et un champ hidden pour récupérer l'id du message, alors comment le soumettre ?

Enfin bref, vous avez compris que je suis un peu perdu ...
Si vous aviez des petites idées de comment résoudre ça proprement. ^^

Pour l'instant la celulle contenant la checkbox donne ça :
						<FORM name="afficher" method="POST" action="Afficher_Livre.php" enctype="multipart/form-data">
						
						<input type="checkbox" name="affichage" value="<?php $Enregistrement->afficher; ?>" 
						<?php if ($Enregistrement->afficher == '1'){ echo 'Checked';} ?>/>
						
						</form>
Merci d'avance ! :mrgreen: