source: spip-zone/_core_/plugins/forum/inc/forum.php

Last change on this file was 113294, checked in by spip.franck@…, 2 months ago

Il parait que le futur c'est maintenant :-D

File size: 9.6 KB
Line 
1<?php
2
3/***************************************************************************\
4 *  SPIP, Systeme de publication pour l'internet                           *
5 *                                                                         *
6 *  Copyright (c) 2001-2019                                                *
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")) {
14        return;
15}
16include_spip('inc/actions');
17
18/**
19 * recuperer le critere SQL qui selectionne nos forums
20 * https://code.spip.net/@critere_statut_controle_forum
21 *
22 * @param string $type
23 * @param int|array $id_secteur
24 * @param string $recherche
25 * @return array
26 */
27function critere_statut_controle_forum($type, $id_secteur = 0, $recherche = '') {
28
29        if (!$id_secteur) {
30                $from = 'spip_forum AS F';
31                $where = "";
32                $and = "";
33        } else {
34                if (!is_array($id_secteur)) {
35                        $id_secteur = explode(',', $id_secteur);
36                }
37                $from = 'spip_forum AS F, spip_articles AS A';
38                $where = sql_in("A.id_secteur", $id_secteur) . " AND F.objet='article' AND F.id_objet=A.id_article";
39                $and = ' AND ';
40        }
41
42        switch ($type) {
43                case 'public':
44                        $and .= "F.statut IN ('publie', 'off', 'prop', 'spam') AND F.texte!=''";
45                        break;
46                case 'prop':
47                        $and .= "F.statut='prop'";
48                        break;
49                case 'spam':
50                        $and .= "F.statut='spam'";
51                        break;
52                case 'interne':
53                        $and .= "F.statut IN ('prive', 'privrac', 'privoff', 'privadm') AND F.texte!=''";
54                        break;
55                case 'vide':
56                        $and .= "F.statut IN ('publie', 'off', 'prive', 'privrac', 'privoff', 'privadm') AND F.texte=''";
57                        break;
58                default:
59                        $where = '0=1';
60                        $and = '';
61                        break;
62        }
63
64        if ($recherche) {
65                # recherche par IP
66                if (preg_match(',^\d+\.\d+\.(\*|\d+\.(\*|\d+))$,', $recherche)) {
67                        $and .= " AND ip LIKE " . sql_quote(str_replace('*', '%', $recherche));
68                } else {
69                        include_spip('inc/rechercher');
70                        if ($a = recherche_en_base($recherche, 'forum')) {
71                                $and .= " AND " . sql_in('id_forum',
72                                                array_keys(array_pop($a)));
73                        } else {
74                                $and .= " AND 0=1";
75                        }
76                }
77        }
78
79        return array($from, "$where$and");
80}
81
82// Index d'invalidation des forums
83// obsolete, remplace par l'appel systematique a 2 invalideurs :
84// - forum/id_forum
85// - objet/id_objet
86// https://code.spip.net/@calcul_index_forum
87function calcul_index_forum($objet, $id_objet) {
88        return substr($objet, 0, 1) . $id_objet;
89}
90
91//
92// Recalculer tous les threads
93//
94// https://code.spip.net/@calculer_threads
95function calculer_threads() {
96        // fixer les id_thread des debuts de discussion
97        sql_update('spip_forum', array('id_thread' => 'id_forum'), "id_parent=0");
98        // reparer les messages qui n'ont pas l'id_secteur de leur parent
99        do {
100                $discussion = "0";
101                $precedent = 0;
102                $r = sql_select("fille.id_forum AS id,  maman.id_thread AS thread", 'spip_forum AS fille, spip_forum AS maman',
103                        "fille.id_parent = maman.id_forum AND fille.id_thread <> maman.id_thread", '', "thread");
104                while ($row = sql_fetch($r)) {
105                        if ($row['thread'] == $precedent) {
106                                $discussion .= "," . $row['id'];
107                        } else {
108                                if ($precedent) {
109                                        sql_updateq("spip_forum", array("id_thread" => $precedent), "id_forum IN ($discussion)");
110                                }
111                                $precedent = $row['thread'];
112                                $discussion = $row['id'];
113                        }
114                }
115                sql_updateq("spip_forum", array("id_thread" => $precedent), "id_forum IN ($discussion)");
116        } while ($discussion != "0");
117}
118
119// Calculs des URLs des forums (pour l'espace public)
120// https://code.spip.net/@racine_forum
121function racine_forum($id_forum) {
122        if (!$id_forum = intval($id_forum)) {
123                return false;
124        }
125
126        $row = sql_fetsel("id_parent, objet, id_objet, id_thread", "spip_forum", "id_forum=" . $id_forum);
127
128        if (!$row) {
129                return false;
130        }
131
132        if ($row['id_parent']
133                and $row['id_thread'] != $id_forum
134        ) // eviter boucle infinie
135        {
136                return racine_forum($row['id_thread']);
137        }
138
139        return array($row['objet'], $row['id_objet'], $id_forum);
140}
141
142
143// https://code.spip.net/@parent_forum
144function parent_forum($id_forum) {
145        if (!$id_forum = intval($id_forum)) {
146                return;
147        }
148        $row = sql_fetsel("id_parent, objet, id_objet", "spip_forum", "id_forum=" . $id_forum);
149        if (!$row) {
150                return array();
151        }
152        if ($row['id_parent']) {
153                return array('forum', $row['id_parent']);
154        } else {
155                return array($row['objet'], $row['id_objet']);
156        }
157}
158
159
160/**
161 * Pour compatibilite : remplacer les appels par son contenu
162 *
163 * @param unknown_type $id_forum
164 * @param unknown_type $args
165 * @param unknown_type $ancre
166 * @return unknown
167 */
168function generer_url_forum_dist($id_forum, $args = '', $ancre = '') {
169        $generer_url_forum = charger_fonction('generer_url_forum', 'urls');
170
171        return $generer_url_forum($id_forum, $args, $ancre);
172}
173
174
175// https://code.spip.net/@generer_url_forum_parent
176function generer_url_forum_parent($id_forum) {
177        if ($id_forum = intval($id_forum)) {
178                list($type, $id) = parent_forum($id_forum);
179                if ($type) {
180                        return generer_url_entite($id, $type);
181                }
182        }
183
184        return '';
185}
186
187
188// Quand on edite un forum, on tient a conserver l'original
189// sous forme d'un forum en reponse, de statut 'original'
190// https://code.spip.net/@conserver_original
191function conserver_original($id_forum) {
192        $s = sql_fetsel("id_forum", "spip_forum", "id_parent=" . intval($id_forum) . " AND statut='original'");
193
194        if ($s) {
195                return '';
196        } // pas d'erreur
197
198        // recopier le forum
199        $t = sql_fetsel("*", "spip_forum", "id_forum=" . intval($id_forum));
200
201        if ($t) {
202                unset($t['id_forum']);
203                $id_copie = sql_insertq('spip_forum', $t);
204                if ($id_copie) {
205                        sql_updateq('spip_forum', array('id_parent' => $id_forum, 'statut' => 'original'), "id_forum=$id_copie");
206
207                        return ''; // pas d'erreur
208                }
209        }
210
211        return '&erreur';
212}
213
214// appelle conserver_original(), puis modifie le contenu via l'API inc/modifier
215// https://code.spip.net/@enregistre_et_modifie_forum
216function enregistre_et_modifie_forum($id_forum, $c = false) {
217        if ($err = conserver_original($id_forum)) {
218                spip_log("erreur de sauvegarde de l'original, $err");
219
220                return;
221        }
222
223        include_spip('action/editer_forum');
224
225        return revision_forum($id_forum, $c);
226}
227
228
229/**
230 * Trouver le titre d'un objet publie
231 *
232 * @param string $objet
233 * @param int $id_objet
234 * @param int $id_forum
235 * @param bool $publie
236 * @return bool|string
237 */
238function forum_recuperer_titre_dist($objet, $id_objet, $id_forum = 0, $publie = true) {
239        include_spip('inc/filtres');
240        $titre = "";
241
242        if ($f = charger_fonction($objet . '_forum_extraire_titre', 'inc', true)) {
243                $titre = $f($id_objet);
244        } else {
245                include_spip('base/objets');
246                if ($publie and !objet_test_si_publie($objet, $id_objet)) {
247                        return false;
248                }
249
250                $titre = generer_info_entite($id_objet, $objet, 'titre', '*');
251        }
252
253        if ($titre and $id_forum) {
254                $titre_m = sql_getfetsel('titre', 'spip_forum', "id_forum = " . intval($id_forum));
255                if (!$titre_m) {
256                        return false; // URL fabriquee
257                }
258                $titre = $titre_m;
259        }
260
261        $titre = supprimer_numero($titre);
262        $titre = str_replace('~', ' ', extraire_multi($titre));
263
264        return $titre;
265}
266
267
268/**
269 * Retourne pour un couple objet/id_objet donne
270 * de quelle maniere les forums sont acceptes dessus
271 * non: pas de forum
272 * pos: a posteriori, acceptes et eventuellements moderes ensuite
273 * pri: a priori, doivent etre valides par un admin
274 * abo: les personnes doivent au prealable etre identifiees
275 *
276 * https://code.spip.net/@controler_forum
277 *
278 * @param string $objet
279 *   objet a tester
280 * @param int $id_objet
281 *   identifiant de l'objet
282 * @return string
283 *   chaine de 3 caractere parmi 'non','pos','pri','abo'
284 */
285function controler_forum($objet, $id_objet) {
286        // Valeur par defaut
287        $accepter_forum = $GLOBALS['meta']["forums_publics"];
288
289        // il y a un cas particulier pour l'acceptation de forum d'article...
290        if ($f = charger_fonction($objet . '_accepter_forums_publics', 'inc', true)) {
291                $accepter_forum = $f($id_objet);
292        }
293
294        return substr($accepter_forum, 0, 3);
295}
296
297
298/**
299 * Verifier la presence du jeton de secu post previsu
300 * https://code.spip.net/@forum_insert_noprevisu
301 *
302 * @return bool
303 */
304function forum_insert_noprevisu() {
305        // simuler une action venant de l'espace public
306        // pour se conformer au cas general.
307        set_request('action', 'ajout_forum');
308        // Creer une session s'il n'y en a pas (cas du postage sans cookie)
309        $securiser_action = charger_fonction('securiser_action', 'inc');
310        $arg = $securiser_action();
311
312        $file = _DIR_TMP . "forum_" . preg_replace('/[^0-9]/', '', $arg) . ".lck";
313        if (!file_exists($file)) {
314                # ne pas tracer cette erreur, peut etre due a un double POST
315                # tracer_erreur_forum('session absente');
316                return true;
317        }
318        unlink($file);
319
320        // antispam : si le champ au nom aleatoire verif_$hash n'est pas 'ok'
321        // on meurt
322        if (_request('verif_' . _request('hash')) != 'ok') {
323                tracer_erreur_forum('champ verif manquant');
324
325                return true;
326        }
327
328        return false;
329}
330
331
332/**
333 * recuperer tous les objets dont on veut pouvoir obtenir l'identifiant
334 * directement dans l'environnement
335 *
336 * @return array
337 */
338function forum_get_objets_depuis_env() {
339        static $objets = null;
340        if ($objets === null) {
341                // on met une cle (le type d'objet) pour qu'un appel du pipeline
342                // puisse facilement soustraire un objet qu'il ne veut pas avec
343                // unset($objets['rubrique']) par exemple.
344                $objets = pipeline('forum_objets_depuis_env', array(
345                        'article' => id_table_objet('article'),
346                        'rubrique' => id_table_objet('rubrique'),
347                        'site' => id_table_objet('site'),
348                        'breve' => id_table_objet('breve')
349                ));
350                asort($objets);
351        }
352
353        return $objets;
354}
355
356
357// https://code.spip.net/@reduce_strlen
358function reduce_strlen($n, $c) {
359        return $n - (is_string($c) ? strlen($c) : 0);
360}
Note: See TracBrowser for help on using the repository browser.