Subversion Repositories Sites.tela-botanica.org

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 david 1
<?php
2
 
3
/***************************************************************************\
4
 *  SPIP, Systeme de publication pour l'internet                           *
5
 *                                                                         *
6
 *  Copyright (c) 2001-2005                                                *
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
 
14
//
15
// Ce fichier ne sera execute qu'une fois
16
if (defined("_ECRIRE_INC_INDEX")) return;
17
define("_ECRIRE_INC_INDEX", "1");
18
 
19
function separateurs_indexation($requete = false) {
20
	// Merci a Herve Lefebvre pour son apport sur cette fonction
21
	$liste = "],:;*\"!\r\n\t\\/)}{[|@<>$%";
22
 
23
	// pour autoriser les recherches en vietnamien,
24
	// ne pas eliminer les accents de translitteration
25
	if (!$requete)
26
		$liste .= "'`?\~.^+(-";
27
 
28
	// windowzeries iso-8859-1
29
	$charset = lire_meta('charset');
30
	if ($charset == 'iso-8859-1')
31
		$liste .= chr(187).chr(171).chr(133).chr(145).chr(146).chr(180).chr(147).chr(148);
32
 
33
	return $liste;
34
}
35
 
36
function nettoyer_chaine_indexation($texte) {
37
	global $translitteration_complexe;
38
	include_ecrire("inc_charsets.php3");
39
 
40
	// translitteration complexe (vietnamien, allemand)
41
	if ($translitteration_complexe) {
42
		$texte_c = translitteration_complexe ($texte);
43
		$texte_c = " ".strtr($texte_c, "'`?~.^+(-", "123456789");
44
	}
45
 
46
	$texte = translitteration($texte).$texte_c;
47
 
48
	return $texte;
49
}
50
 
51
function indexer_chaine($texte, $val = 1, $min_long = 3) {
52
	global $index, $mots, $translitteration_complexe;
53
 
54
	// Nettoyer les tags, entites HTML, signes diacritiques...
55
	$texte = ' '.ereg_replace("<[^>]*>"," ",$texte).' ';
56
	$texte = nettoyer_chaine_indexation($texte);
57
 
58
	// Nettoyer les caracteres non-alphanumeriques
59
	$regs = separateurs_indexation();
60
	$texte = strtr($texte, $regs, ereg_replace('.', ' ', $regs));
61
 
62
	// Cas particulier : sigles d'au moins deux lettres
63
	$texte = ereg_replace(" ([A-Z][0-9A-Z]{1,".($min_long - 1)."}) ", ' \\1___ ', $texte);
64
	$texte = strtolower($texte);
65
 
66
	// Separer les mots
67
	$table = preg_split("/ +/", $texte);
68
 
69
	while (list(, $mot) = each($table)) {
70
		if (strlen($mot) > $min_long) {
71
			$h = substr(md5($mot), 0, 16);
72
			$index[$h] += $val/(1+$translitteration_complexe);
73
			$mots .= ",(0x$h,'$mot')";
74
		}
75
	}
76
}
77
 
78
function deja_indexe($type, $id_objet) {
79
	$table_index = 'spip_index_'.table_objet($type);
80
	$col_id = 'id_'.$type;
81
	$query = "SELECT $col_id FROM $table_index WHERE $col_id=$id_objet LIMIT 0,1";
82
	$n = @spip_num_rows(@spip_query($query));
83
	return ($n > 0);
84
}
85
 
86
 
87
// Extracteur des documents 'txt'
88
function extracteur_txt($fichier, &$charset) {
89
	lire_fichier($fichier, $contenu);
90
 
91
	// Reconnaitre le BOM utf-8 (0xEFBBBF)
92
	include_ecrire('inc_charsets.php3');
93
	if (bom_utf8($contenu))
94
		$charset = 'utf-8';
95
 
96
	return $contenu;
97
}
98
 
99
// Extracteur des documents 'html'
100
function extracteur_html($fichier, &$charset) {
101
	lire_fichier($fichier, $contenu);
102
 
103
	// Importer dans le charset local
104
	include_ecrire('inc_charsets.php3');
105
	$contenu = transcoder_page($contenu);
106
	$charset = lire_meta('charset');
107
 
108
	return $contenu;
109
}
110
 
111
// Quels formats sait-on extraire ?
112
$GLOBALS['extracteur'] = array (
113
	'txt'   => 'extracteur_txt',
114
	'pas'   => 'extracteur_txt',
115
	'c'     => 'extracteur_txt',
116
	'css'   => 'extracteur_txt',
117
	'html'  => 'extracteur_html'
118
);
119
 
120
// Indexer le contenu d'un document
121
function indexer_contenu_document ($row) {
122
	global $extracteur;
123
 
124
	if ($row['mode'] == 'vignette') return;
125
	list($extension) = spip_fetch_array(spip_query(
126
		"SELECT extension FROM spip_types_documents
127
		WHERE id_type = ".$row['id_type']
128
	));
129
 
130
	// Voir si on sait lire le contenu (eventuellement en chargeant le
131
	// fichier extract_pdf.php dans find_in_path() )
132
	if ($plugin = find_in_path('extract_'.$extension.'.php')) {
133
		include_local($plugin);
134
	}
135
	if (function_exists($lire = $extracteur[$extension])) {
136
		// Voir si on a deja une copie du doc distant
137
		// Note: si copie_locale() charge le doc, elle demande une reindexation
138
		if (!$fichier = copie_locale($row['fichier'], 'test')) {
139
			spip_log("pas de copie locale de '$fichier'");
140
			return;
141
		}
142
		// par defaut, on pense que l'extracteur va retourner ce charset
143
		$charset = 'iso-8859-1';
144
		// lire le contenu
145
		$contenu = $lire($fichier, $charset);
146
		if (!$contenu) {
147
			spip_log("Echec de l'extraction de '$fichier'");
148
		} else {
149
			// Ne retenir que les 50 premiers ko
150
			$contenu = substr($contenu, 0, 50000);
151
			// importer le charset
152
			$contenu = importer_charset($contenu, $charset);
153
			// Indexer le texte
154
			indexer_chaine($contenu, 1);
155
		}
156
	} else {
157
		spip_log("pas d'extracteur '$extension' fonctionnel");
158
	}
159
}
160
 
161
 
162
// Indexer les documents, auteurs, mots-cles associes a l'objet
163
function indexer_elements_associes($objet, $id_objet, $associe, $valeur) {
164
	switch ($associe) {
165
		case 'document':
166
			$r = spip_query("SELECT doc.titre, doc.descriptif
167
				FROM spip_documents AS doc,
168
				spip_documents_".table_objet($objet)." AS lien
169
				WHERE lien.".id_table_objet($objet)."=$id_objet
170
				AND doc.id_document=lien.id_document");
171
			while ($row = spip_fetch_array($r)) {
172
				indexer_chaine($row['titre'],2 * $valeur);
173
				indexer_chaine($row['descriptif'],1 * $valeur);
174
			}
175
			break;
176
 
177
		case 'auteur':
178
			$r = spip_query("SELECT auteurs.nom
179
				FROM spip_auteurs AS auteurs,
180
				spip_auteurs_".table_objet($objet)." AS lien
181
				WHERE lien.".id_table_objet($objet)."=$id_objet
182
				AND auteurs.id_auteur=lien.id_auteur");
183
			while ($row = spip_fetch_array($r)) {
184
				indexer_chaine($row['nom'], 1 * $valeur, 2);
185
			}
186
			break;
187
 
188
		case 'mot':
189
			$r = spip_query("SELECT mots.titre, mots.descriptif
190
				FROM spip_mots AS mots,
191
				spip_mots_".table_objet($objet)." AS lien
192
				WHERE lien.".id_table_objet($objet)."=$id_objet
193
				AND mots.id_mot = lien.id_mot");
194
			while ($row = spip_fetch_array($r)) {
195
				indexer_chaine($row['titre'],4 * $valeur);
196
				indexer_chaine($row['descriptif'],1 * $valeur);
197
			}
198
			break;
199
	}
200
}
201
 
202
 
203
function indexer_objet($type, $id_objet, $forcer_reset = true) {
204
	global $index, $mots, $translitteration_complexe;
205
 
206
	$table = 'spip_'.table_objet($type);
207
	$table_index = 'spip_index_'.table_objet($type);
208
	$col_id = id_table_objet($type);
209
 
210
	if (!$id_objet) return;
211
	if (!$forcer_reset AND deja_indexe($type, $id_objet)) {
212
		spip_log ("$type $id_objet deja indexe");
213
		spip_query("UPDATE $table SET idx='oui' WHERE $col_id=$id_objet");
214
		return;
215
	}
216
	// marquer "en cours d'indexation"
217
	spip_query("UPDATE $table SET idx='idx' WHERE $col_id=$id_objet");
218
 
219
	include_ecrire("inc_texte.php3");
220
	include_ecrire("inc_filtres.php3");
221
 
222
	spip_log("indexation $type $id_objet");
223
	$index = '';
224
	$mots = '';
225
 
226
	$query = "SELECT * FROM $table WHERE $col_id=$id_objet";
227
	$result = spip_query($query);
228
	$row = spip_fetch_array($result);
229
 
230
	if (!$row) return;
231
 
232
	// translitteration complexe ?
233
	if (!$lang = $row['lang']) $lang = lire_meta('langue_site');
234
	if ($lang == 'de' OR $lang=='vi') {
235
		$translitteration_complexe = 1;
236
		spip_log ('-> translitteration complexe');
237
	} else $translitteration_complexe = 0;
238
 
239
	switch($type) {
240
	case 'article':
241
		indexer_chaine($row['titre'], 8);
242
		indexer_chaine($row['soustitre'], 5);
243
		indexer_chaine($row['surtitre'], 5);
244
		indexer_chaine($row['descriptif'], 4);
245
		indexer_chaine($row['chapo'], 3);
246
		indexer_chaine($row['texte'], 1);
247
		indexer_chaine($row['ps'], 1);
248
		indexer_chaine($row['nom_site'], 1);
249
		indexer_chaine(@join(' ', unserialize($row['extra'])), 1);
250
		indexer_elements_associes('article', $id_objet, 'document', 1);
251
		indexer_elements_associes('article', $id_objet, 'auteur', 10);
252
		indexer_elements_associes('article', $id_objet, 'mot', 3);
253
		break;
254
 
255
	case 'breve':
256
		indexer_chaine($row['titre'], 8);
257
		indexer_chaine($row['texte'], 2);
258
		indexer_chaine(@join(' ', unserialize($row['extra'])), 1);
259
		indexer_elements_associes('breve', $id_objet, 'document', 1);
260
		indexer_elements_associes('breve', $id_objet, 'mot', 3);
261
		break;
262
 
263
	case 'rubrique':
264
		indexer_chaine($row['titre'], 8);
265
		indexer_chaine($row['descriptif'], 5);
266
		indexer_chaine($row['texte'], 1);
267
		indexer_chaine(@join(' ', unserialize($row['extra'])), 1);
268
		indexer_elements_associes('rubrique', $id_objet, 'document', 1);
269
		indexer_elements_associes('rubrique', $id_objet, 'mot', 3);
270
		break;
271
 
272
	case 'auteur':
273
		indexer_chaine($row['nom'], 5, 2);
274
		indexer_chaine($row['bio'], 1);
275
		indexer_chaine(@join(' ', unserialize($row['extra'])), 1);
276
		break;
277
 
278
	case 'mot':
279
		indexer_chaine($row['titre'], 8);
280
		indexer_chaine($row['descriptif'], 5);
281
		indexer_chaine($row['texte'], 1);
282
		indexer_chaine(@join(' ', unserialize($row['extra'])), 1);
283
		break;
284
 
285
	case 'signature':
286
		indexer_chaine($row['nom_email'], 2, 2);
287
		indexer_chaine($row['ad_email'], 2);
288
		indexer_chaine($row['nom_site'], 2);
289
		indexer_chaine($row['url_site'], 1);
290
		indexer_chaine($row['message'], 1);
291
		break;
292
 
293
	case 'syndic':
294
		indexer_chaine($row['nom_site'], 50);
295
		indexer_chaine($row['descriptif'], 30);
296
		indexer_elements_associes('syndic', $id_objet, 'document', 1);
297
		indexer_elements_associes('syndic', $id_objet, 'mot', 3);
298
 
299
		// Ajouter les titres des articles syndiques de ce site, le cas echeant
300
		if ($row['syndication'] = "oui") {
301
			$query_syndic = "SELECT titre FROM spip_syndic_articles
302
			WHERE id_syndic=$id_objet AND statut='publie'
303
			ORDER BY date DESC LIMIT 0,100";
304
			$result_syndic = spip_query($query_syndic);
305
			while ($row_syndic = spip_fetch_array($result_syndic)) {
306
				indexer_chaine($row_syndic['titre'], 5);
307
			}
308
		}
309
		// Aller chercher la page d'accueil
310
		if (lire_meta("visiter_sites") == "oui") {
311
			include_ecrire ("inc_sites.php3");
312
			spip_log ("indexation contenu syndic ".$row['url_site']);
313
			indexer_chaine(supprimer_tags(
314
				recuperer_page($row['url_site'], true, false, 50000)
315
				), 1);
316
		}
317
		break;
318
 
319
	//
320
	// Cas tres particulier du forum :
321
	// on indexe le thread comme un tout
322
	case 'forum':
323
		// 1. chercher la racine du thread
324
		$id_forum = $id_objet;
325
		while ($row['id_parent']) {
326
			$id_forum = $row['id_parent'];
327
			$s = spip_query("SELECT id_forum,id_parent FROM spip_forum WHERE id_forum=$id_forum");
328
			$row = spip_fetch_array($s);
329
		}
330
 
331
		// 2. chercher tous les forums du thread
332
		// (attention le forum de depart $id_objet n'appartient pas forcement
333
		// a son propre thread car il peut etre le fils d'un forum non 'publie')
334
		$thread="$id_forum";
335
		$fini = false;
336
		while (!$fini) {
337
			$s = spip_query("SELECT id_forum FROM spip_forum WHERE id_parent IN ($thread) AND id_forum NOT IN ($thread) AND statut='publie'");
338
			if (spip_num_rows($s) == 0) $fini = true;
339
			while ($t = spip_fetch_array($s))
340
				$thread.=','.$t['id_forum'];
341
		}
342
 
343
		// 3. marquer le thread comme "en cours d'indexation"
344
		spip_log("-> indexation thread $thread");
345
		spip_query("UPDATE spip_forum SET idx='idx'
346
			WHERE id_forum IN ($thread,$id_objet) AND idx!='non'");
347
 
348
		// 4. Indexer le thread
349
		$s = spip_query("SELECT * FROM spip_forum
350
			WHERE id_forum IN ($thread) AND idx!='non'");
351
		while ($row = spip_fetch_array($s)) {
352
			indexer_chaine($row['titre'], 3);
353
			indexer_chaine($row['texte'], 1);
354
			indexer_chaine($row['auteur'], 2, 2);
355
			indexer_chaine($row['email_auteur'], 2);
356
			indexer_chaine($row['nom_site'], 2);
357
			indexer_chaine($row['url_site'], 1);
358
		}
359
 
360
		// 5. marquer le thread comme "indexe"
361
		spip_query("UPDATE spip_forum SET idx='oui'
362
			WHERE id_forum IN ($thread,$id_objet) AND idx!='non'");
363
 
364
		// 6. Changer l'id_objet en id_forum de la racine du thread
365
		$id_objet = $id_forum;
366
 
367
		break;
368
 
369
 
370
	case 'document':
371
		// 1. Indexer le descriptif
372
		indexer_chaine($row['titre'], 20);
373
		indexer_chaine($row['descriptif'], 10);
374
		indexer_chaine(preg_replace(',^(IMG/|.*://),', '', $row['fichier']), 1);
375
		indexer_elements_associes('document', $id_objet, 'mot', 3);
376
 
377
		// 2. Indexer le contenu si on sait le lire
378
		indexer_contenu_document($row);
379
		break;
380
 
381
 
382
	} // switch
383
 
384
	$query = "DELETE FROM $table_index WHERE $col_id=$id_objet";
385
	$result = spip_query($query);
386
 
387
	if ($index) {
388
		if ($mots) {
389
			$mots = "INSERT IGNORE INTO spip_index_dico (hash, dico) VALUES ".substr($mots,1);	// supprimer la virgule du debut
390
			spip_query($mots);
391
		}
392
		reset($index);
393
		unset($q);
394
		while (list($hash, $points) = each($index)) $q[] = "(0x$hash,".ceil($points).",$id_objet)";
395
		spip_query("INSERT INTO $table_index (hash, points, $col_id) VALUES ".join(',',$q));
396
	}
397
 
398
	// marquer "indexe"
399
	spip_query("UPDATE $table SET idx='oui' WHERE $col_id=$id_objet");
400
}
401
 
402
/*
403
	Valeurs du champ 'idx' de la table spip_objet(s)
404
	'' ne sait pas
405
	'1' ˆ (re)indexer
406
	'oui' deja indexe
407
	'idx' en cours
408
	'non' ne jamais indexer
409
*/
410
 
411
// API pour l'espace prive
412
function marquer_indexer ($objet, $id_objet) {
413
	spip_log ("demande indexation $objet $id_objet");
414
	$table = 'spip_'.table_objet($objet);
415
	$id = id_table_objet($objet);
416
	spip_query ("UPDATE $table SET idx='1' WHERE $id=$id_objet AND idx!='non'");
417
}
418
 
419
// A garder pour compatibilite bouton memo...
420
function indexer_article($id_article) {
421
	marquer_indexer('article', $id_article);
422
}
423
 
424
// n'indexer que les objets publies
425
function critere_indexation($type) {
426
	switch ($type) {
427
		case 'article':
428
		case 'breve':
429
		case 'rubrique':
430
		case 'syndic':
431
		case 'forum':
432
		case 'signature':
433
			$critere = "statut='publie'";
434
			break;
435
		case 'auteur':
436
			$critere = "statut IN ('0minirezo', '1comite')";
437
			break;
438
		case 'mot':
439
		case 'document':
440
		default:
441
			$critere = '1=1';
442
			break;
443
	}
444
	return $critere;
445
}
446
 
447
function effectuer_une_indexation($nombre_indexations = 1) {
448
 
449
	// chercher un objet a indexer dans chacune des tables d'objets
450
	$vu = array();
451
	$types = array('article','auteur','breve','mot','rubrique','signature','syndic','forum','document');
452
 
453
	while (list(,$type) = each($types)) {
454
		$table_objet = 'spip_'.table_objet($type);
455
		$table_index = 'spip_index_'.table_objet($type);
456
 
457
		$critere = critere_indexation($type);
458
 
459
		if ($type == 'syndic' OR $type == 'document')
460
			$limit = 1;
461
		else
462
			$limit = $nombre_indexations;
463
 
464
		$s = spip_query("SELECT id_$type, idx FROM $table_objet WHERE idx IN ('','1','idx') AND $critere ORDER BY idx='idx',idx='' LIMIT 0,$limit");
465
		while ($t = spip_fetch_array($s)) {
466
			$vu[$type] .= $t[0].", ";
467
			indexer_objet($type, $t[0], $t[1]);
468
		}
469
	}
470
	return $vu;
471
}
472
 
473
function executer_une_indexation_syndic() {
474
	$id_syndic = 0;
475
	if ($row = spip_fetch_array(spip_query("SELECT id_syndic FROM spip_syndic WHERE statut='publie' AND date_index < DATE_SUB(NOW(), INTERVAL 7 DAY) ORDER BY date_index LIMIT 0,1"))) {
476
		$id_syndic = $row['id_syndic'];
477
		spip_query("UPDATE spip_syndic SET date_index=NOW() WHERE id_syndic=$id_syndic");
478
		marquer_indexer('syndic', $id_syndic);
479
	}
480
	return $id_syndic;
481
}
482
 
483
function creer_liste_indexation() {
484
	$types = array('article','auteur','breve','mot','rubrique','syndic','forum','signature','document');
485
	while (list(,$type) = each($types)) {
486
		$table = 'spip_'.table_objet($type);
487
		spip_query("UPDATE $table SET idx='1' WHERE idx!='non'");
488
	}
489
}
490
 
491
function purger_index() {
492
		spip_query("DELETE FROM spip_index_articles");
493
		spip_query("DELETE FROM spip_index_auteurs");
494
		spip_query("DELETE FROM spip_index_breves");
495
		spip_query("DELETE FROM spip_index_mots");
496
		spip_query("DELETE FROM spip_index_rubriques");
497
		spip_query("DELETE FROM spip_index_syndic");
498
		spip_query("DELETE FROM spip_index_forum");
499
		spip_query("DELETE FROM spip_index_signatures");
500
		spip_query("DELETE FROM spip_index_documents");
501
		spip_query("DELETE FROM spip_index_dico");
502
}
503
 
504
// cree la requete pour une recherche en txt integral
505
function requete_txt_integral($objet, $hash_recherche) {
506
	$table = "spip_".table_objet($objet);
507
	$index_table = "spip_index_".table_objet($objet);
508
	$id_objet = "id_".$objet;
509
	return "SELECT objet.*, SUM(rec.points) AS points
510
		FROM $table AS objet, $index_table AS rec
511
		WHERE objet.$id_objet = rec.$id_objet
512
		AND rec.hash IN ($hash_recherche)
513
		GROUP BY objet.$id_objet
514
		ORDER BY points DESC
515
		LIMIT 0,10";
516
}
517
 
518
// rechercher un mot dans le dico
519
// retourne deux methodes : lache puis strict
520
function requete_dico($val) {
521
	$min_long = 3;
522
 
523
	// cas normal
524
	if (strlen($val) > $min_long) {
525
		return array("dico LIKE '".addslashes($val)."%'", "dico = '".addslashes($val)."'");
526
	} else
527
		return array("dico = '".addslashes($val)."___'", "dico = '".addslashes($val)."___'");
528
}
529
 
530
 
531
// decode la chaine recherchee et la traduit en hash
532
function requete_hash ($rech) {
533
	// recupere les mots de la recherche
534
	$translitteration_complexe = true;
535
	$rech = nettoyer_chaine_indexation($rech);
536
	$regs = separateurs_indexation(true)." ";
537
	$rech = strtr($rech, $regs, ereg_replace('.', ' ', $regs));
538
	$s = preg_split("/ +/", $rech);
539
	unset($dico);
540
	unset($h);
541
 
542
	// cherche les mots dans le dico
543
	while (list(, $val) = each($s)) {
544
		list($rq, $rq_strict) = requete_dico ($val);
545
		if ($rq)
546
			$dico[] = $rq;
547
		if ($rq_strict)
548
			$dico_strict[] = $rq_strict;
549
	}
550
 
551
	// Attention en MySQL 3.x il faut passer par HEX(hash)
552
	// alors qu'en MySQL 4.1 c'est interdit !
553
	$vers = spip_fetch_array(spip_query("SELECT VERSION()"));
554
	if (substr($vers[0], 0, 1) >= 4
555
	AND substr($vers[0], 2, 1) >= 1 ) {
556
		$hex_fmt = '';
557
		$select_hash = 'hash AS h';
558
	} else {
559
		$hex_fmt = '0x';
560
		$select_hash = 'HEX(hash) AS h';
561
	}
562
 
563
	// compose la recherche dans l'index
564
	if ($dico_strict) {
565
		$query2 = "SELECT $select_hash FROM spip_index_dico WHERE "
566
			.join(" OR ", $dico_strict);
567
		$result2 = spip_query($query2);
568
		while ($row2 = spip_fetch_array($result2))
569
			$h_strict[] = $hex_fmt.$row2['h'];
570
	}
571
	if ($dico) {
572
		$query2 = "SELECT $select_hash FROM spip_index_dico WHERE "
573
			.join(" OR ", $dico);
574
		$result2 = spip_query($query2);
575
		while ($row2 = spip_fetch_array($result2))
576
			$h[] = $hex_fmt.$row2['h'];
577
	}
578
	if ($h_strict)
579
		$hash_recherche_strict = join(",", $h_strict);
580
	else
581
		$hash_recherche_strict = "0";
582
 
583
	if ($h)
584
		$hash_recherche = join(",", $h);
585
	else
586
		$hash_recherche = "0";
587
 
588
	return array($hash_recherche, $hash_recherche_strict);
589
}
590
 
591
 
592
function prepare_recherche($recherche, $type = 'id_article', $table='articles') {
593
	static $cache = array();
594
 
595
	if (!$cache[$type][$recherche]) {
596
 
597
		if (!$cache['hash'][$recherche])
598
			$cache['hash'][$recherche] = requete_hash($recherche);
599
		list($hash_recherche, $hash_recherche_strict)
600
			= $cache['hash'][$recherche];
601
 
602
		$strict = array();
603
		if ($hash_recherche_strict)
604
			foreach (split(',',$hash_recherche_strict) as $h)
605
				$strict[$h] = 99;
606
 
607
		$points = array();
608
		$s = spip_query ("SELECT hash,points,$type as id
609
			FROM spip_index_$table
610
			WHERE hash IN ($hash_recherche)");
611
 
612
		while ($r = spip_fetch_array($s))
613
			$points[$r['id']]
614
			+= (1 + $strict[$r['hash']]) * $r['points'];
615
		spip_free_result($s);
616
 
617
		arsort($points, SORT_NUMERIC);
618
 
619
		# calculer le {id_article IN()} et le {... as points}
620
		if (!count($points)) {
621
			$cache[$type][$recherche] = array('', '');
622
		} else {
623
			$ids = array();
624
			$select = '0';
625
			foreach ($points as $id => $p)
626
				$listes_ids[$p] .= ','.$id;
627
			foreach ($listes_ids as $p => $liste_ids)
628
				$select .= "+$p*(".calcul_mysql_in("$table.$type", substr($liste_ids, 1)).") ";
629
 
630
			$cache[$type][$recherche] = array($select,
631
							  '('.calcul_mysql_in("$table.$type", join(',',array_keys($points))).')');
632
		}
633
	}
634
 
635
	return $cache[$type][$recherche];
636
}
637
 
638
?>