1 | <?php |
---|
2 | |
---|
3 | /***************************************************************************\ |
---|
4 | * SPIP, Systeme de publication pour l'internet * |
---|
5 | * * |
---|
6 | * Copyright (c) 2001-2011 * |
---|
7 | * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * |
---|
8 | * * |
---|
9 | * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * |
---|
10 | * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * |
---|
11 | \***************************************************************************/ |
---|
12 | |
---|
13 | if (!defined("_ECRIRE_INC_VERSION")) return; |
---|
14 | include_spip('inc/forum'); |
---|
15 | include_spip('inc/filtres'); |
---|
16 | include_spip('inc/actions'); |
---|
17 | |
---|
18 | // Ce fichier est inclus par dist/formulaires/forum.php |
---|
19 | |
---|
20 | // http://doc.spip.org/@controler_forum_abo |
---|
21 | function controler_forum_abo($retour) |
---|
22 | { |
---|
23 | global $visiteur_session; |
---|
24 | if ($visiteur_session) { |
---|
25 | $statut = $visiteur_session['statut']; |
---|
26 | if (!$statut OR $statut == '5poubelle') { |
---|
27 | ask_php_auth(_T('forum:forum_acces_refuse'), |
---|
28 | _T('forum:forum_cliquer_retour', |
---|
29 | array('retour_forum' => $retour))); |
---|
30 | } |
---|
31 | } else { |
---|
32 | ask_php_auth(_T('forum_non_inscrit'), |
---|
33 | _T('forum:forum_cliquer_retour', |
---|
34 | array('retour_forum' => $retour))); |
---|
35 | } |
---|
36 | } |
---|
37 | |
---|
38 | /** |
---|
39 | * Retourne pour un couple objet/id_objet donne |
---|
40 | * de quelle maniere les forums sont acceptes dessus |
---|
41 | * non: pas de forum |
---|
42 | * pos: a posteriori, acceptes et eventuellements moderes ensuite |
---|
43 | * pri: a priori, doivent etre valides par un admin |
---|
44 | * abo: les personnes doivent au prealable etre identifiees |
---|
45 | * |
---|
46 | * @param string $objet objet a tester |
---|
47 | * @param int $id_objet identifiant de l'objet |
---|
48 | * @param string $res chaine de 3 caractere parmi 'non','pos','pri','abo' |
---|
49 | */ |
---|
50 | // http://doc.spip.org/@controler_forum |
---|
51 | function controler_forum($objet, $id_objet) { |
---|
52 | // Valeur par defaut |
---|
53 | $accepter_forum = $GLOBALS['meta']["forums_publics"]; |
---|
54 | |
---|
55 | // il y a un cas particulier pour l'acceptation de forum d'article... |
---|
56 | if ($f = charger_fonction($objet . '_accepter_forums_publics', 'inc', true)){ |
---|
57 | $accepter_forum = $f($id_objet); |
---|
58 | } |
---|
59 | |
---|
60 | return substr($accepter_forum, 0, 3); |
---|
61 | } |
---|
62 | |
---|
63 | // http://doc.spip.org/@mots_du_forum |
---|
64 | function mots_du_forum($ajouter_mot, $id_message) |
---|
65 | { |
---|
66 | include_spip('action/editer_mot'); |
---|
67 | mot_associer($ajouter_mot, array('forum'=>$id_message)); |
---|
68 | } |
---|
69 | |
---|
70 | |
---|
71 | // http://doc.spip.org/@reduce_strlen |
---|
72 | function reduce_strlen($n, $c) |
---|
73 | { |
---|
74 | return $n - (is_string($c) ? strlen($c) : 0); |
---|
75 | } |
---|
76 | |
---|
77 | |
---|
78 | // http://doc.spip.org/@tracer_erreur_forum |
---|
79 | function tracer_erreur_forum($type='') { |
---|
80 | spip_log("erreur forum ($type): ".print_r($_POST, true)); |
---|
81 | |
---|
82 | define('_TRACER_ERREUR_FORUM', false); |
---|
83 | if (_TRACER_ERREUR_FORUM) { |
---|
84 | $envoyer_mail = charger_fonction('envoyer_mail','inc'); |
---|
85 | $envoyer_mail($GLOBALS['meta']['email_webmaster'], "erreur forum ($type)", |
---|
86 | "erreur sur le forum ($type) :\n\n". |
---|
87 | '$_POST = '.print_r($_POST, true)."\n\n". |
---|
88 | '$_SERVER = '.print_r($_SERVER, true)); |
---|
89 | } |
---|
90 | } |
---|
91 | |
---|
92 | // Un parametre permet de forcer le statut (exemple: plugin antispam) |
---|
93 | // http://doc.spip.org/@inc_forum_insert_dist |
---|
94 | function inc_forum_insert_dist($force_statut = NULL) { |
---|
95 | # en reponse a |
---|
96 | $id_forum = intval(_request('id_forum'))>0?intval(_request('id_forum')):0; |
---|
97 | |
---|
98 | # objet |
---|
99 | $id_objet = intval(_request('id_objet')); |
---|
100 | $objet = _request('objet'); |
---|
101 | |
---|
102 | # temporaire vieux code |
---|
103 | if (!$id_objet OR !$objet) { |
---|
104 | foreach (array('article', 'breve', 'rubrique', 'syndic', 'message','ticket') |
---|
105 | as $ob) { |
---|
106 | if ($id = intval(_request('id_'.$ob))) { |
---|
107 | $objet = $ob; |
---|
108 | $id_objet = $id; |
---|
109 | } |
---|
110 | } |
---|
111 | } |
---|
112 | |
---|
113 | spip_log("insertion de forum sur $objet $id_objet (+$id_forum)", 'forum'); |
---|
114 | |
---|
115 | $reqret = rawurldecode(_request('retour_forum')); |
---|
116 | $retour = ($reqret !== '!') |
---|
117 | ? $reqret |
---|
118 | : forum_insert_nopost($id_forum, $objet, $id_objet); |
---|
119 | |
---|
120 | $c = array('statut'=>'off'); |
---|
121 | $c['objet'] = $objet; |
---|
122 | $c['id_objet'] = $id_objet; |
---|
123 | |
---|
124 | foreach (array( |
---|
125 | 'titre', 'texte', 'nom_site', 'url_site' |
---|
126 | ) as $champ) |
---|
127 | $c[$champ] = _request($champ); |
---|
128 | |
---|
129 | $c['auteur'] = sinon($GLOBALS['visiteur_session']['nom'], |
---|
130 | $GLOBALS['visiteur_session']['session_nom']); |
---|
131 | $c['email_auteur'] = sinon($GLOBALS['visiteur_session']['email'], |
---|
132 | $GLOBALS['visiteur_session']['session_email']); |
---|
133 | |
---|
134 | $c = pipeline('pre_edition',array( |
---|
135 | 'args'=>array( |
---|
136 | 'table' => 'spip_forum', |
---|
137 | 'id_objet' => $id_forum, |
---|
138 | 'action'=>'instituer' |
---|
139 | ), |
---|
140 | 'data'=>forum_insert_statut($c, $retour, $force_statut) |
---|
141 | )); |
---|
142 | |
---|
143 | $id_reponse = forum_insert_base($c, $id_forum, $objet, $id_objet, $c['statut'], $retour); |
---|
144 | |
---|
145 | if (!$id_reponse) { |
---|
146 | spip_log("Echec insertion $retour", 'forum'); |
---|
147 | return array($retour,0); // echec |
---|
148 | } |
---|
149 | else |
---|
150 | spip_log("forum insere' $id_reponse", 'forum'); |
---|
151 | |
---|
152 | // En cas de retour sur (par exemple) {#SELF}, on ajoute quand |
---|
153 | // meme #forum12 a la fin de l'url, sauf si un #ancre est explicite |
---|
154 | if ($reqret !== '!') |
---|
155 | return array( |
---|
156 | strpos($retour, '#') ? $retour : $retour.'#forum'.$id_reponse, |
---|
157 | $id_reponse |
---|
158 | ); |
---|
159 | |
---|
160 | // le retour par defaut envoie sur le thread, ce qui permet |
---|
161 | // de traiter elegamment le cas des forums moderes a priori. |
---|
162 | // Cela assure aussi qu'on retrouve son message dans le thread |
---|
163 | // dans le cas des forums moderes a posteriori, ce qui n'est |
---|
164 | // pas plus mal. |
---|
165 | if (function_exists('generer_url_forum')) { |
---|
166 | $url = generer_url_forum($id_reponse); |
---|
167 | } else { |
---|
168 | $thread = sql_fetsel('id_thread', 'spip_forum', 'id_forum='.$id_reponse); |
---|
169 | spip_log('id_thread='.$thread['id_thread'], 'forum'); |
---|
170 | $url = generer_url_entite($thread['id_thread'], 'forum'); |
---|
171 | } |
---|
172 | |
---|
173 | return array($url, $id_reponse); |
---|
174 | } |
---|
175 | |
---|
176 | // http://doc.spip.org/@forum_insert_base |
---|
177 | function forum_insert_base($c, $id_forum, $objet, $id_objet, $statut, $retour) |
---|
178 | { |
---|
179 | $afficher_texte = (_request('afficher_texte') <> 'non'); |
---|
180 | $ajouter_mot = _request('ajouter_mot'); |
---|
181 | |
---|
182 | // si le statut est vide, c'est qu'on ne veut pas de ce presume spam ! |
---|
183 | if (!$statut) |
---|
184 | return false; |
---|
185 | |
---|
186 | // Si forum avec previsu sans bon hash de securite, echec silencieux |
---|
187 | if (!test_espace_prive() AND $afficher_texte AND forum_insert_noprevisu()) { |
---|
188 | return false; |
---|
189 | } |
---|
190 | |
---|
191 | if (array_reduce($_POST, 'reduce_strlen', (20 * 1024)) < 0) { |
---|
192 | ask_php_auth(_T('forum:forum_message_trop_long'), |
---|
193 | _T('forum:forum_cliquer_retour', |
---|
194 | array('retour_forum' => $retour))); |
---|
195 | } |
---|
196 | |
---|
197 | // Entrer le message dans la base |
---|
198 | $id_reponse = sql_insertq('spip_forum', array( |
---|
199 | 'date_heure'=> date('Y-m-d H:i:s'), |
---|
200 | 'ip' => $GLOBALS['ip'], |
---|
201 | 'id_auteur' => $GLOBALS['visiteur_session']['id_auteur'] |
---|
202 | )); |
---|
203 | |
---|
204 | if ($id_forum>0) { |
---|
205 | $id_thread = sql_getfetsel("id_thread", "spip_forum", "id_forum = $id_forum"); |
---|
206 | } |
---|
207 | else |
---|
208 | $id_thread = $id_reponse; # id_thread oblige INSERT puis UPDATE. |
---|
209 | |
---|
210 | // Entrer les cles |
---|
211 | sql_updateq('spip_forum', array('id_parent' => $id_forum, 'objet' => $objet, 'id_objet' => $id_objet, 'id_thread' => $id_thread, 'statut' => $statut), "id_forum = $id_reponse"); |
---|
212 | |
---|
213 | // Entrer les mots-cles associes |
---|
214 | if ($ajouter_mot) mots_du_forum($ajouter_mot, $id_reponse); |
---|
215 | |
---|
216 | // |
---|
217 | // Entree du contenu et invalidation des caches |
---|
218 | // |
---|
219 | include_spip('action/editer_forum'); |
---|
220 | revision_forum($id_reponse, $c); |
---|
221 | |
---|
222 | // Ajouter un document |
---|
223 | if (isset($_FILES['ajouter_document']) |
---|
224 | AND $_FILES['ajouter_document']['tmp_name']) { |
---|
225 | $files[] = array('tmp_name'=>$_FILES['ajouter_document']['tmp_name'],'name'=>$_FILES['ajouter_document']['name']); |
---|
226 | $ajouter_documents = charger_fonction('ajouter_documents','action'); |
---|
227 | $ajouter_documents( |
---|
228 | 'new', |
---|
229 | $files, |
---|
230 | 'forum', |
---|
231 | $id_reponse, |
---|
232 | 'document'); |
---|
233 | // supprimer le temporaire et ses meta donnees |
---|
234 | spip_unlink($_FILES['ajouter_document']['tmp_name']); |
---|
235 | spip_unlink(preg_replace(',\.bin$,', |
---|
236 | '.txt', $_FILES['ajouter_document']['tmp_name'])); |
---|
237 | } |
---|
238 | |
---|
239 | // Notification |
---|
240 | if ($notifications = charger_fonction('notifications', 'inc')) |
---|
241 | $notifications('forumposte', $id_reponse); |
---|
242 | |
---|
243 | return $id_reponse; |
---|
244 | } |
---|
245 | |
---|
246 | // calcul de l'adresse de retour en cas d'echec du POST |
---|
247 | // mais la veritable adresse de retour sera calculee apres insertion |
---|
248 | |
---|
249 | // http://doc.spip.org/@forum_insert_nopost |
---|
250 | function forum_insert_nopost($id_forum, $objet, $id_objet) |
---|
251 | { |
---|
252 | if ($id_forum>0) |
---|
253 | $r = generer_url_entite($id_forum, 'forum'); |
---|
254 | else |
---|
255 | $r = generer_url_entite($id_objet, $objet); |
---|
256 | |
---|
257 | return str_replace('&','&',$r); |
---|
258 | } |
---|
259 | |
---|
260 | // http://doc.spip.org/@forum_insert_noprevisu |
---|
261 | function forum_insert_noprevisu() |
---|
262 | { |
---|
263 | // simuler une action venant de l'espace public |
---|
264 | // pour se conformer au cas general. |
---|
265 | set_request('action', 'ajout_forum'); |
---|
266 | // Creer une session s'il n'y en a pas (cas du postage sans cookie) |
---|
267 | $securiser_action = charger_fonction('securiser_action', 'inc'); |
---|
268 | $arg = $securiser_action(); |
---|
269 | |
---|
270 | $file = _DIR_TMP ."forum_" . preg_replace('/[^0-9]/', '', $arg) .".lck"; |
---|
271 | if (!file_exists($file)) { |
---|
272 | # ne pas tracer cette erreur, peut etre due a un double POST |
---|
273 | # tracer_erreur_forum('session absente'); |
---|
274 | return true; |
---|
275 | } |
---|
276 | unlink($file); |
---|
277 | |
---|
278 | // antispam : si le champ au nom aleatoire verif_$hash n'est pas 'ok' |
---|
279 | // on meurt |
---|
280 | if (_request('verif_'._request('hash')) != 'ok') { |
---|
281 | tracer_erreur_forum('champ verif manquant'); |
---|
282 | return true; |
---|
283 | } |
---|
284 | return false; |
---|
285 | } |
---|
286 | |
---|
287 | // http://doc.spip.org/@forum_insert_statut |
---|
288 | function forum_insert_statut($champs, $retour, $forcer_statut=NULL) |
---|
289 | { |
---|
290 | $statut = controler_forum($champs['objet'], $champs['id_objet']); |
---|
291 | |
---|
292 | // Ne pas autoriser d'envoi hacke si forum sur abonnement |
---|
293 | if ($statut == 'abo' AND !test_espace_prive()) { |
---|
294 | controler_forum_abo($retour); // demandera une auth http |
---|
295 | } |
---|
296 | |
---|
297 | if ($forcer_statut !== NULL) |
---|
298 | $champs['statut'] = $forcer_statut; |
---|
299 | else |
---|
300 | $champs['statut'] = ($statut == 'non') ? 'off' : (($statut == 'pri') ? 'prop' : 'publie'); |
---|
301 | |
---|
302 | // Antispam basique : |
---|
303 | // si l'input invisible a ete renseigne, ca ne peut etre qu'un bot |
---|
304 | if (strlen(_request(_request('cle_ajouter_document')))) { |
---|
305 | tracer_erreur_forum('champ interdit (nobot) rempli'); |
---|
306 | $champs['statut']=false; |
---|
307 | } |
---|
308 | |
---|
309 | return $champs; |
---|
310 | } |
---|
311 | |
---|
312 | ?> |
---|