Euh... T'es là ?
Quoi, déjà ?
Bon bah, voyons ensemble le résultat : je vous rappelle que vous ne pouvez pas encore promouvoir des membres modérateurs, donc il faut le faire en passant par la base de données (ce n'est qu'une question de temps pour que l'on y arrive

).
Allez, on commence tout de suite avec l'édition de message !
Si vous n'avez pas réussi à réaliser ces systèmes, il serait plus bénéfique que vous essayiez de comprendre vos erreurs grâce à mes scripts, plutôt que de laisser complètement tomber ce que vous avez fait.
En tout cas, ne faites pas de copier / coller aveugle, et n'oubliez pas qu'un forum est là pour vous aider !
Dans les codes qui suivent, je n'ai pas systématiquement déclaré mes constantes, en particulier en lien avec la fonction erreur. Vous êtes grands et vous pouvez le faire seuls !
Éditer un message
Si vous avez bien suivi tout ce qui a été vu jusqu'ici, ça n'a pas dû vous poser trop de difficultés

.
Page poster.php
Déjà le code dans la page poster.php.
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 | <?php
case "edit": //Si on veut éditer le post
//On récupère la valeur de p
$post = (int) $_GET['p'];
echo'<h1>Edition</h1>';
//On lance enfin notre requête
$query=$db->prepare('SELECT post_createur, post_texte, auth_modo FROM forum_post
LEFT JOIN forum_forum ON forum_post.post_forum_id = forum_forum.forum_id
WHERE post_id=:post');
$query->bindValue(':post',$post,PDO::PARAM_INT);
$query->execute();
$data=$query->fetch();
$text_edit = $data['post_texte']; //On récupère le message
//Ensuite on vérifie que le membre a le droit d'être ici (soit le créateur soit un modo/admin)
if (!verif_auth($data['auth_modo']) && $data['post_createur'] != $id)
{
// Si cette condition n'est pas remplie ça va barder :o
erreur(ERR_AUTH_EDIT);
}
else //Sinon ça roule et on affiche la suite
{
//Le formulaire de postage
?>
<form method="post" action="postok.php?action=edit&p=<?php echo $post ?>" name="formulaire">
<fieldset><legend>Mise en forme</legend>
<input type="button" id="gras" name="gras" value="Gras" onClick="javascript:bbcode('[g]', '[/g]');return(false)" />
<input type="button" id="italic" name="italic" value="Italic" onClick="javascript:bbcode('[i]', '[/i]');return(false)" />
<input type="button" id="souligné" name="souligné" value="Souligné" onClick="javascript:bbcode('[s]', '[/s]');return(false)"/>
<input type="button" id="lien" name="lien" value="Lien" onClick="javascript:bbcode('[url]', '[/url]');return(false)" />
<br /><br />
<img src="./images/smileys/heureux.gif" title="heureux" alt="heureux" onClick="javascript:smilies(':D');return(false)" />
<img src="./images/smileys/lol.gif" title="lol" alt="lol" onClick="javascript:smilies(':lol:');return(false)" />
<img src="./images/smileys/triste.gif" title="triste" alt="triste" onClick="javascript:smilies(':triste:');return(false)" />
<img src="./images/smileys/cool.gif" title="cool" alt="cool" onClick="javascript:smilies(':frime:');return(false)" />
<img src="./images/smileys/rire.gif" title="rire" alt="rire" onClick="javascript:smilies('XD');return(false)" />
<img src="./images/smileys/confus.gif" title="confus" alt="confus" onClick="javascript:smilies(':s');return(false)" />
<img src="./images/smileys/choc.gif" title="choc" alt="choc" onClick="javascript:smilies(':O');return(false)" />
<img src="./images/smileys/question.gif" title="?" alt="?" onClick="javascript:smilies(':interrogation:');return(false)" />
<img src="./images/smileys/exclamation.gif" title="!" alt="!" onClick="javascript:smilies(':exclamation:');return(false)" />
</fieldset>
<fieldset><legend>Message</legend><textarea cols="80" rows="8" id="message" name="message"><?php echo $text_edit ?>
</textarea>
</fieldset>
<p>
<input type="submit" name="submit" value="Editer !" />
<input type="reset" name = "Effacer" value = "Effacer"/></p>
</form>
<?php
}
break; //Fin de ce cas :o
?>
|
Ce code doit être écrit dans le switch de la page poster.php.
Ce que l'on fait ici, c'est simplement relancer le formulaire pour poster, mais on pré-remplit la case message avant au final

.
Vous devez aussi modifier le haut de la page poster.php, en effet les droits d'accès dans le cas de la modération sont valables pour le modérateur et le créateur du message, il faut donc rajouter cette vérification.
Passons au traitement du message :
Page postok.php
Ce code est assez court, assez simple et en plus, il ressemble au précédent
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 | <?php
case "edit": //Si on veut éditer le post
//On récupère la valeur de p
$post = (int) $_GET['p'];
//On récupère le message
$message = $_POST['message'];
//Ensuite on vérifie que le membre a le droit d'être ici (soit le créateur soit un modo/admin)
$query=$db->prepare('SELECT post_createur, post_texte, post_time, topic_id, auth_modo
FROM forum_post
LEFT JOIN forum_forum ON forum_post.post_forum_id = forum_forum.forum_id
WHERE post_id=:post');
$query->bindValue(':post',$post,PDO::PARAM_INT);
$query->execute();
$data1 = $query->fetch();
$topic = $data1['topic_id'];
//On récupère la place du message dans le topic (pour le lien)
$query = $db->prepare('SELECT COUNT(*) AS nbr FROM forum_post
WHERE topic_id = :topic AND post_time < '.$data1['post_time']);
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$data2=$query->fetch();
if (!verif_auth($data1['auth_modo'])&& $data1['post_createur'] != $id)
{
// Si cette condition n'est pas remplie ça va barder :o
erreur(ERR_AUTH_EDIT);
}
else //Sinon ça roule et on continue
{
$query=$db->prepare('UPDATE forum_post SET post_texte = :message WHERE post_id = :post');
$query->bindValue(':message',$message,PDO::PARAM_STR);
$query->bindValue(':post',$post,PDO::PARAM_INT);
$query->execute();
$nombreDeMessagesParPage = 15;
$nbr_post = $data2['nbr']+1;
$page = ceil($nbr_post / $nombreDeMessagesParPage);
echo'<p>Votre message a bien été édité!<br /><br />
Cliquez <a href="./index.php">ici</a> pour revenir à l index du forum<br />
Cliquez <a href="./voirtopic.php?t='.$topic.'&page='.$page.'#p_'.$post.'">ici</a> pour le voir</p>';
$query->CloseCursor();
}
break;
?>
|
Voilà pour ce qui est de l'édition. Quand tout est terminé, on affiche un message pour annoncer la bonne nouvelle.
Quant à l'affichage du lien vers le dernier message, il est un peu étrange. En fait la difficulté est que le message édité n'est pas forcément le dernier du topic, il faut donc calculer sa place pour ensuite connaitre la page et enfin mettre le bon lien.
Supprimer
On passe au système suivant, la suppression d'un post et d'un topic. C'est à peu de choses près le même script que celui de la suppression d'un mp.
Page poster.php
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 | <?php
case "delete": //Si on veut supprimer le post
//On récupère la valeur de p
$post = (int) $_GET['p'];
//Ensuite on vérifie que le membre a le droit d'être ici
echo'<h1>Suppression</h1>';
$query=$db->prepare('SELECT post_createur, auth_modo
FROM forum_post
LEFT JOIN forum_forum ON forum_post.post_forum_id = forum_forum.forum_id
WHERE post_id= :post');
$query->bindValue(':post',$post,PDO::PARAM_INT);
$query->execute();
$data = $query->fetch();
if (!verif_auth($data['auth_modo']) && $data['post_createur'] != $id)
{
// Si cette condition n'est pas remplie ça va barder :o
erreur(ERR_AUTH_DELETE);
}
else //Sinon ça roule et on affiche la suite
{
echo'<p>Êtes vous certains de vouloir supprimer ce post ?</p>';
echo'<p><a href="./postok.php?action=delete&p='.$post.'">Oui</a> ou <a href="./index.php">Non</a></p>';
}
$query->CloseCursor();
break;
?>
|
On retrouve beaucoup de similitudes avec la partie édition dans la vérification des droits du membre. Vous voyez par ailleurs que cette fois, on demande de confirmer la suppression avant de tout envoyer aux oubliettes.
Page postok.php
Il ne reste plus qu'à traiter le message, en le supprimant sans pitié.
Eh, mais attends

! Comment on fait si c'est le premier post ou le dernier post d'un topic, faudra changer la valeur de
topic_last_post et
topic_first_post 
?
En fait pas tout à fait, c'est là qu'est la petite difficulté. Je m'explique : imaginez qu'on essaye de supprimer le premier post d'un topic. Si on laisse le topic en vie, ça ne va pas le faire... Il faudra donc le supprimer lui aussi. Et si on essaye de supprimer le dernier, il faudra ne pas oublier de mettre à jour la valeur de
topic_last_post !
Puis il faudra aussi baisser la valeur de
topic_post et de
forum_post, et mettre à jour
forum_last_post_id.
Bon bah au final, ça fait un code assez compliqué, tout ça ...
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160 | <?php
case "delete": //Si on veut supprimer le post
//On récupère la valeur de p
$post = (int) $_GET['p'];
$query=$db->prepare('SELECT post_createur, post_texte, forum_id, topic_id, auth_modo
FROM forum_post
LEFT JOIN forum_forum ON forum_post.post_forum_id = forum_forum.forum_id
WHERE post_id=:post');
$query->bindValue(':post',$post,PDO::PARAM_INT);
$query->execute();
$data = $query->fetch();
$topic = $data['topic_id'];
$forum = $data['forum_id'];
$poster = $data['post_createur'];
//Ensuite on vérifie que le membre a le droit d'être ici
//(soit le créateur soit un modo/admin)
if (!verif_auth($data['auth_modo']) && $poster != $id)
{
// Si cette condition n'est pas remplie ça va barder :o
erreur(ERR_AUTH_DELETE);
}
else //Sinon ça roule et on continue
{
//Ici on vérifie plusieurs choses :
//est-ce un premier post ? Dernier post ou post classique ?
$query = $db->prepare('SELECT topic_first_post, topic_last_post FROM forum_topic
WHERE topic_id = :topic');
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$data_post=$query->fetch();
//On distingue maintenant les cas
if ($data_post['topic_first_post']==$post) //Si le message est le premier
{
//Les autorisations ont changé !
//Normal, seul un modo peut décider de supprimer tout un topic
if (!verif_auth($data['auth_modo']))
{
erreur('ERR_AUTH_DELETE_TOPIC');
}
//Il faut s'assurer que ce n'est pas une erreur
echo'<p>Vous avez choisi de supprimer un post.
Cependant ce post est le premier du topic. Voulez vous supprimer le topic ? <br />
<a href="./postok.php?action=delete_topic&t='.$topic.'">oui</a> - <a href="./voirtopic.php?t='.$topic.'">non</a>
</p>';
$query->CloseCursor();
}
elseif ($data_post['topic_last_post']==$post) //Si le message est le dernier
{
//On supprime le post
$query=$db->prepare('DELETE FROM forum_post WHERE post_id = :post');
$query->bindValue(':post',$post,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
//On modifie la valeur de topic_last_post pour cela on
//récupère l'id du plus récent message de ce topic
$query=$db->prepare('SELECT post_id FROM forum_post WHERE topic_id = :topic
ORDER BY post_id DESC LIMIT 0,1');
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$data=$query->fetch();
$last_post_topic=$data['post_id'];
$query->CloseCursor();
//On fait de même pour forum_last_post_id
$query=$db->prepare('SELECT post_id FROM forum_post WHERE post_forum_id = :forum
ORDER BY post_id DESC LIMIT 0,1');
$query->bindValue(':forum',$forum,PDO::PARAM_INT);
$query->execute();
$data=$query->fetch();
$last_post_forum=$data['post_id'];
$query->CloseCursor();
//On met à jour la valeur de topic_last_post
$query=$db->prepare('UPDATE forum_topic SET topic_last_post = :last
WHERE topic_last_post = :post');
$query->bindValue(':last',$last_post_topic,PDO::PARAM_INT);
$query->bindValue(':post',$post,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
//On enlève 1 au nombre de messages du forum et on met à
//jour forum_last_post
$query=$db->prepare('UPDATE forum_forum SET forum_post = forum_post - 1, forum_last_post_id = :last
WHERE forum_id = :forum');
$query->bindValue(':last',$last_post_forum,PDO::PARAM_INT);
$query->bindValue(':forum',$forum,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
//On enlève 1 au nombre de messages du topic
$query=$db->prepare('UPDATE forum_topic SET topic_post = topic_post - 1
WHERE topic_id = :topic');
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
//On enlève 1 au nombre de messages du membre
$query=$db->prepare('UPDATE forum_membres SET membre_post = membre_post - 1
WHERE membre_id = :id');
$query->bindValue(':id',$poster,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
//Enfin le message
echo'<p>Le message a bien été supprimé !<br />
Cliquez <a href="./voirtopic.php?t='.$topic.'">ici</a> pour retourner au topic<br />
Cliquez <a href="./index.php">ici</a> pour revenir à l index du forum</p>';
}
else // Si c'est un post classique
{
//On supprime le post
$query=$db->prepare('DELETE FROM forum_post WHERE post_id = :post');
$query->bindValue(':post',$post,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
//On enlève 1 au nombre de messages du forum
$query=$db->prepare('UPDATE forum_forum SET forum_post = forum_post - 1 WHERE forum_id = :forum');
$query->bindValue(':forum',$forum,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
//On enlève 1 au nombre de messages du topic
$query=$db->prepare('UPDATE forum_topic SET topic_post = topic_post - 1
WHERE topic_id = :topic');
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
//On enlève 1 au nombre de messages du membre
$query=$db->prepare('UPDATE forum_membres SET membre_post = membre_post - 1
WHERE membre_id = :id');
$query->bindValue(':id',$data['post_createur'],PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
//Enfin le message
echo'<p>Le message a bien été supprimé !<br />
Cliquez <a href="./voirtopic.php?t='.$topic.'">ici</a> pour retourner au topic<br />
Cliquez <a href="./index.php">ici</a> pour revenir à l index du forum</p>';
}
} //Fin du else
break;
?>
|
Il faut distinguer les trois cas, ensuite on peut agir en fonction. De toute façon, il faudra toujours faire attention à ce genre de détails lorsque l'on travaillera sur les pages d'administration. Les tables sont liées entre elles par des valeurs comme
topic_last_post, par exemple, il est important de penser à mettre celles-ci à jour également pour ne pas rompre la relation

.
Concernant la suppression d'un topic
Vous avez sûrement remarqué une chose assez étrange : si l'on décide de supprimer le premier post, j'avais dit qu'il fallait supprimer tout le topic. Mais alors pourquoi on ne le fait pas directement ? C'est une question de clarté, et puis ça permet d'éviter de virer un topic entier par erreur

. Ce qu'on fait alors, c'est qu'on redemande si c'est bien le topic qu'il faut supprimer ? Si oui, on va voir ce qu'il se passe, si non, on a eu chaud et on revient en arrière

.
Voici donc la fin du code :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 | <?php
case "delete_topic":
$topic = (int) $_GET['t'];
$query=$db->prepare('SELECT forum_topic.forum_id, auth_modo
FROM forum_topic
LEFT JOIN forum_forum ON forum_topic.forum_id = forum_forum.forum_id
WHERE topic_id=:topic');
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$data = $query->fetch();
$forum = $data['forum_id'];
//Ensuite on vérifie que le membre a le droit d'être ici
//c'est-à-dire si c'est un modo / admin
if (!verif_auth($data['auth_modo']))
{
erreur('ERR_AUTH_DELETE_TOPIC');
}
else //Sinon ça roule et on continue
{
$query->CloseCursor();
//On compte le nombre de post du topic
$query=$db->prepare('SELECT topic_post FROM forum_topic WHERE topic_id = :topic');
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$data = $query->fetch();
$nombrepost = $data['topic_post'] + 1;
$query->CloseCursor();
//On supprime le topic
$query=$db->prepare('DELETE FROM forum_topic
WHERE topic_id = :topic');
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
//On enlève le nombre de post posté par chaque membre dans le topic
$query=$db->prepare('SELECT post_createur, COUNT(*) AS nombre_mess FROM forum_post
WHERE topic_id = :topic GROUP BY post_createur');
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
while($data = $query->fetch())
{
$query=$db->prepare('UPDATE forum_membres
SET membre_post = membre_post - :mess
WHERE membre_id = :id');
$query->bindValue(':mess',$data['nombre_mess'],PDO::PARAM_INT);
$query->bindValue(':id',$data['post_createur'],PDO::PARAM_INT);
$query->execute();
}
$query->CloseCursor();
//Et on supprime les posts !
$query=$db->prepare('DELETE FROM forum_post WHERE topic_id = :topic');
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
//Dernière chose, on récupère le dernier post du forum
$query=$db->prepare('SELECT post_id FROM forum_post
WHERE post_forum_id = :forum ORDER BY post_id DESC LIMIT 0,1');
$query->bindValue(':forum',$forum,PDO::PARAM_INT);
$query->execute();
$data = $query->fetch();
//Ensuite on modifie certaines valeurs :
$query=$db->prepare('UPDATE forum_forum
SET forum_topic = forum_topic - 1, forum_post = forum_post - :nbr, forum_last_post_id = :id
WHERE forum_id = :forum');
$query->bindValue(':nbr',$nombrepost,PDO::PARAM_INT);
$query->bindValue(':id',$data['post_id'],PDO::PARAM_INT);
$query->bindValue(':forum',$forum,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
//Enfin le message
echo'<p>Le topic a bien été supprimé !<br />
Cliquez <a href="./index.php">ici</a> pour revenir à l index du forum</p>';
} //Fin du else
break;
?>
|
Et là, c'est gagné. Du coup si vous avez suivi, il est très facile de faire un lien pour supprimer directement tout le topic (lien que vous pouvez placer dans la page voirtopic, par exemple

).
Retour sur la modification du nombre de post
J'aimerais revenir sur ce morceau de code :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | <?php
//On enlève le nombre de post posté par chaque membre dans le topic
$query=$db->prepare('SELECT post_createur, COUNT(*) AS nombre_mess FROM forum_post
WHERE topic_id = :topic GROUP BY post_createur');
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
while($data = $query->fetch())
{
$query=$db->prepare('UPDATE forum_membres
SET membre_post = membre_post - :mess
WHERE membre_id = :id');
$query->bindValue(':mess',$data['nombre_mess'],PDO::PARAM_INT);
$query->bindValue(':id',$data['post_createur'],PDO::PARAM_INT);
$query->execute();
}
?>
|
Ici, on veut soustraire à la valeur de
membre_post (nombre de posts d'un membre) le nombre de messages qu'il a laissé dans le topic que l'on supprime. Ça peut paraître simple, mais en fait on est obligé de faire une requête dans une boucle (berk

).
Du coup, grâce à une boucle, on retourne pour chaque membre qui a posté le nombre de messages qu'il a laissé. Ça limite un peu le nombre de requêtes ; cela dit, il est assez rare de supprimer un topic, en général, on le déplace dans un forum "poubelle".
Verrouillons !
Ce système de verrouillage / déverrouillage va se faire sur une simple requête sql. Celle-ci retourne la valeur de la case
topic_locked : si c'est 1, je rappelle que c'est verrouillé, on proposera alors de déverrouiller. Si c'est 0, le topic est ouvert, on propose alors de le verrouiller. Ça va, vous me suivez ?
En plus, comble du bonheur, on n'aura qu'une seule page à modifier.
Codons !
En fait, j'ai dit 1 page, mais j'ai menti

. C'est-à-dire que c'est dans la page voirtopic.php qu'il faut faire la requête qui va nous donner la valeur de
topic_locked. Ainsi, on fera deux liens selon les cas vers la page postok.php.
Enfin, voyez plutôt

:
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | <?php
$query = $db->prepare('SELECT topic_locked FROM forum_topic WHERE topic_id = :topic');
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$data=$query->fetch();
if ($data['topic_locked'] == 1) // Topic verrouillé !
{
echo'<a href="./postok.php?action=unlock&t='.$topic.'">
<img src="./images/unlock.gif" alt="deverrouiller" title="Déverrouiller ce sujet" /></a>';
}
else //Sinon le topic est déverrouillé !
{
echo'<a href="./postok.php?action=lock&t='.$topic.'">
<img src="./images/lock.gif" alt="verrouiller" title="Verrouiller ce sujet" /></a>';
}
$query->CloseCursor();
?>
|
Tout simplement

. Vous pouvez insérer ceci où vous voulez dans la page voirtopic.php, mais je vous conseille de le mettre en bas (à côté du numéro des pages) dans un endroit où vous mettrez toutes les options de modération (suppression du topic, verrouillage et déplacement).
Je ne l'ai pas mis parce que normalement vous l'avez fait au moment d'afficher le bouton de suppression du topic : mais pensez à vérifier les autorisations avant !
Passons à la page postok.php :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 | <?php
case "lock": //Si on veut verrouiller le topic
//On récupère la valeur de t
$topic = (int) $_GET['t'];
$query = $db->prepare('SELECT forum_topic.forum_id, auth_modo FROM forum_topic
LEFT JOIN forum_forum ON forum_forum.forum_id = forum_topic.forum_id
WHERE topic_id = :topic');
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$data = $query->fetch();
//Ensuite on vérifie que le membre a le droit d'être ici
if (!verif_auth($data['auth_modo']))
{
// Si cette condition n'est pas remplie ça va barder :o
erreur(ERR_AUTH_VERR);
}
else //Sinon ça roule et on continue
{
//On met à jour la valeur de topic_locked
$query->CloseCursor();
$query=$db->prepare('UPDATE forum_topic SET topic_locked = :lock WHERE topic_id = :topic');
$query->bindValue(':lock',1,PDO::PARAM_STR);
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
echo'<p>Le topic a bien été verrouillé ! <br />
Cliquez <a href="./voirtopic.php?t='.$topic.'">ici</a> pour retourner au topic<br />
Cliquez <a href="./index.php">ici</a> pour revenir à l index du forum</p>';
}
break;
case "unlock": //Si on veut déverrouiller le topic
//On récupère la valeur de t
$topic = (int) $_GET['t'];
$query = $db->prepare('SELECT forum_topic.forum_id, auth_modo FROM forum_topic
LEFT JOIN forum_forum ON forum_forum.forum_id = forum_topic.forum_id
WHERE topic_id = :topic');
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$data = $query->fetch();
//Ensuite on vérifie que le membre a le droit d'être ici
if (!verif_auth($data['auth_modo']))
{
// Si cette condition n'est pas remplie ça va barder :o
erreur(ERR_AUTH_VERR);
}
else //Sinon ça roule et on continue
{
//On met à jour la valeur de topic_locked
$query->CloseCursor();
$query=$db->prepare('UPDATE forum_topic SET topic_locked = :lock WHERE topic_id = :topic');
$query->bindValue(':lock',0,PDO::PARAM_STR);
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
echo'<p>Le topic a bien été déverrouillé !<br />
Cliquez <a href="./voirtopic.php?t='.$topic.'">ici</a> pour retourner au topic<br />
Cliquez <a href="./index.php">ici</a> pour revenir à l index du forum</p>';
}
break;
?>
|
Un simple
update, et le tour est joué !
Ouais, c'est cool ton truc, mais pour l'instant, ça sert à quoi que le champ
topic_locked soit sur
verrouillé puisque ça ne nous empêche pas de poster

?
En effet, pour l'instant c'est plus pour le style, mais ça n'empêche personne de poster un message

. Bah, ce n'est pas grave, remontez dans votre page postok.php, vous avez une des premières valeurs possibles de
$action qui est
repondre. C'est ici et
ici seulement qu'il faut faire agir le verrouillage.
Vous avez normalement quelque chose qui ressemble à ceci :
Code : PHP | <?php
case "repondre":
//On passe le message dans une série de fonction
$message = $_POST['message'];
//ici seulement, maintenant qu'on est sur qu'elle existe, on récupère la valeur de la variable t
$topic = (int) $_GET['t'];
?>
|
Il suffit de rajouter au-dessous le code suivant :
Code : PHP | <?php
$query=$db->prepare('SELECT topic_locked FROM forum_topic WHERE topic_id = :topic');
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$data=$query->fetch();
if ($data['topic_locked'] != 0)
{
erreur(ERR_TOPIC_VERR); //A vous d'afficher un message du genre : le topic est verrouillé qu'est ce que tu fous là !?
}
$query->CloseCursor();
?>
|
Et le tour est joué !

Pensez cependant aussi à préciser que le topic est verrouillé sur les pages voirtopic.php, et même voirforum.php, avec une icône spéciale, pourquoi pas

.
Vous avez à présent un système de verrouillage / déverrouillage pour les topics de votre forum. Nous allons maintenant voir comment faire pour déplacer un topic

.
Déplacement d'un topic
La correction touche à sa fin et je vois déjà vos mines réjouies... Donc, on va calmer ça tout de suite avec ce qui arrive

.
En fait, ce n'est rien de très compliqué : c'est juste différent de ce qu'on a fait jusqu'ici.
Afficher la liste des forums
Pour déplacer un topic, de quoi j'ai besoin ? D'un forum vers lequel l'envoyer, pardi ! Et comment je le choisis ? Avec une liste déroulante, par exemple

.
J'en ai déjà un peu parlé plus haut, donc on va voir cela plus concrètement.
Déjà, on va afficher cette liste sur la page voirtopic.php, tout en bas entre 'supprimer' et 'verrouiller' le topic. Pensez donc à vérifier encore une fois les autorisations (enfin vous n'avez besoin de le faire qu'une fois dans la page, hein ?

)
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | <?php
$query=$db->prepare('SELECT forum_id, forum_name FROM forum_forum WHERE forum_id <> :forum');
$query->bindValue(':forum',$forum,PDO::PARAM_INT);
$query->execute();
//$forum a été définie tout en haut de la page !
echo'<p>Déplacer vers :</p>
<form method="post" action=postok.php?action=deplacer&t='.$topic.'>
<select name="dest">';
while($data=$query->fetch())
{
echo'<option value='.$data['forum_id'].' id='.$data['forum_id'].'>'.$data['forum_name'].'</option>';
}
$query->CloseCursor();
echo'
</select>
<input type="hidden" name="from" value='.$forum.'>
<input type="submit" name="submit" value="Envoyer" />
</form>';
?>
|
Vous remarquez que je passe plusieurs infos à la page postok.php. Déjà l'id du topic à déplacer, mais aussi le forum d'origine ainsi que la destination. Vous comprendrez mieux pourquoi dans 2 minutes

.
Voilà déjà la liste qui est faite

: ça devrait vous donner quelque chose comme ça :

.
Passons maintenant au code de la page postok.php (pour changer

).
Traitement
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100 | <?php
case "deplacer":
$topic = (int) $_GET['t'];
$query= $db->prepare('SELECT forum_topic.forum_id, auth_modo
FROM forum_topic
LEFT JOIN forum_forum
ON forum_forum.forum_id = forum_topic.forum_id
WHERE topic_id =:topic');
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$data=$query->fetch();
if (!verif_auth($data['auth_modo']))
{
// Si cette condition n'est pas remplie ça va barder :o
erreur(ERR_AUTH_MOVE);
}
else //Sinon ça roule et on continue
{
$query->CloseCursor();
$destination = (int) $_POST['dest'];
$origine = (int) $_POST['from'];
//On déplace le topic
$query=$db->prepare('UPDATE forum_topic SET forum_id = :dest WHERE topic_id = :topic');
$query->bindValue(':dest',$destination,PDO::PARAM_INT);
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
//On déplace les posts
$query=$db->prepare('UPDATE forum_post SET post_forum_id = :dest
WHERE topic_id = :topic');
$query->bindValue(':dest',$destination,PDO::PARAM_INT);
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
//On s'occupe d'ajouter / enlever les nombres de post / topic aux
//forum d'origine et de destination
//Pour cela on compte le nombre de post déplacé
$query=$db->prepare('SELECT COUNT(*) AS nombre_post
FROM forum_post WHERE topic_id = :topic');
$query->bindValue(':topic',$topic,PDO::PARAM_INT);
$query->execute();
$data = $query->fetch();
$nombrepost = $data['nombre_post'];
$query->CloseCursor();
//Il faut également vérifier qu'on a pas déplacé un post qui été
//l'ancien premier post du forum (champ forum_last_post_id)
$query=$db->prepare('SELECT post_id FROM forum_post WHERE post_forum_id = :ori
ORDER BY post_id DESC LIMIT 0,1');
$query->bindValue(':ori',$origine,PDO::PARAM_INT);
$query->execute();
$data=$query->fetch();
$last_post=$data['post_id'];
$query->CloseCursor();
//Puis on met à jour le forum d'origine
$query=$db->prepare('UPDATE forum_forum SET forum_post = forum_post - :nbr, forum_topic = forum_topic - 1,
forum_last_post_id = :id
WHERE forum_id = :ori');
$query->bindValue(':nbr',$nombrepost,PDO::PARAM_INT);
$query->bindValue(':ori',$origine,PDO::PARAM_INT);
$query->bindValue(':id',$last_post,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
//Avant de mettre à jour le forum de destination il faut
//vérifier la valeur de forum_last_post_id
$query=$db->prepare('SELECT post_id FROM forum_post WHERE post_forum_id = :dest
ORDER BY post_id DESC LIMIT 0,1');
$query->bindValue(':dest',$destination,PDO::PARAM_INT);
$query->execute();
$data=$query->fetch();
$last_post=$data['post_id'];
$query->CloseCursor();
//Et on met à jour enfin !
$query=$db->prepare('UPDATE forum_forum SET forum_post = forum_post + :nbr,
forum_topic = forum_topic + 1,
forum_last_post_id = :last
WHERE forum_id = :forum');
$query->bindValue(':nbr',$nombrepost,PDO::PARAM_INT);
$query->bindValue(':last',$last_post,PDO::PARAM_INT);
$query->bindValue(':forum',$destination,PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
//C'est gagné ! On affiche le message
echo'<p>Le topic a bien été déplacé <br />
Cliquez <a href="./voirtopic.php?t='.$topic.'">ici</a> pour revenir au topic<br />
Cliquez <a href="./index.php">ici</a> pour revenir à l index du forum</p>';
}
break;
?>
|
Piuu... ça en fait des choses à modifier...

. C'était la difficulté majeure de ces codes, ne pas oublier de modifier un seul champ, car sinon, on a vite fait de se retrouver avec des problèmes sur son forum.
C'est ce qui fait le nombre assez élevé de requêtes : donc, il ne faut pas se perdre. N'hésitez pas à reprendre les codes, et ne les utilisez qu'une fois compris (je les ai piégés, et ils vont tout faire sauter, sinon

).
Comme je l'ai déjà dit, il existe autant de façons de créer un forum qu'il y a de codeurs php. C'est-à-dire que les choix que j'ai fait ne sont pas forcément les seuls possibles. Notamment concernant les champs qui lient certaines tables : il ne tient qu'à vous de les supprimer, et de les contourner avec une jointure lorsque vous en avez besoin, ce qui permet de passer plus vite ce genre de code en en faisant qu'un seul update.
En tout cas, la correction est terminée et par la même occasion, la partie modération !