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