source: spip-zone/_core_/branches/spip-2.1/plugins/forum/inc/forum_insert.php @ 104360

Last change on this file since 104360 was 104360, checked in by spip.franck@…, 3 years ago

code.spip est maintenant en https, donc j'ajoute le "s" à http

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