3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
6 * Copyright (c) 2001-2019 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
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 \***************************************************************************/
14 * Gestion des préparatifs de recherches
16 * @package SPIP\Core\Recherche
19 if (!defined('_ECRIRE_INC_VERSION')) {
23 include_spip('inc/rechercher');
24 if (!defined('_DELAI_CACHE_resultats')) {
25 define('_DELAI_CACHE_resultats', 600);
29 * Préparer les listes `id_article IN (...)` pour les parties WHERE
30 * et calcul des `points` pour la partie SELECT des requêtes du moteur de recherche
32 * Le paramètre $serveur est utilisé pour savoir sur quelle base on cherche
33 * mais l'index des résultats est toujours stocké sur le serveur principal
34 * car on ne sait pas si la base distante dispose d'une table spip_resultats
35 * ni meme si on aurait le droit d'ecrire dedans
37 * @param string $recherche
39 * @param string $table
40 * table dans laquelle porte la recherche
42 * critere conditionnel sur {recherche?}
43 * @param string $serveur
44 * serveur de base de donnees
45 * @param array $modificateurs
46 * modificateurs de boucle, ie liste des criteres presents
47 * @param string $primary
48 * cle primaire de la table de recherche
51 function inc_prepare_recherche_dist(
56 $modificateurs = array(),
59 static $cache = array();
60 $delai_fraicheur = min(_DELAI_CACHE_resultats
,
61 time() - (isset($GLOBALS['meta']['derniere_modif']) ?
$GLOBALS['meta']['derniere_modif'] : 0));
63 // si recherche n'est pas dans le contexte, on va prendre en globals
64 // ca permet de faire des inclure simple.
65 if (!isset($recherche) and isset($GLOBALS['recherche'])) {
66 $recherche = $GLOBALS['recherche'];
69 // traiter le cas {recherche?}
70 if ($cond and !strlen($recherche)) {
72 "0 as points" /* as points */, /* where */
80 $where_resultat_recent = sql_date_proche('maj', (0 - ($delai_fraicheur +
100)), " SECOND");
81 if (!isset($cache[$serveur][$table][$recherche])) {
82 $hash_serv = ($serveur ?
substr(md5($serveur), 0, 16) : '');
83 $hash = substr(md5($recherche . $table), 0, 16);
84 $where = "(resultats.recherche='$hash' AND resultats.table_objet=" . sql_quote($table) . " AND resultats.serveur='$hash_serv')";
85 $row = sql_fetsel('recherche', 'spip_resultats AS resultats',
86 $where . " AND $where_resultat_recent", '', '', '0,1');
88 or (defined('_VAR_MODE') and _VAR_MODE
== 'recalcul')
94 // si on n'a pas encore traite les donnees dans une boucle precedente
96 //$tables = liste_des_champs();
97 $x = objet_type($table);
98 $points = recherche_en_base($recherche,
106 // pas de résultat, pas de point
107 $points = isset($points[$x]) ?
$points[$x] : array();
109 // permettre aux plugins de modifier le resultat
110 $points = pipeline('prepare_recherche', array(
113 'recherche' => $recherche,
114 'serveur' => $serveur,
115 'modificateurs' => $modificateurs
120 // supprimer les anciens resultats de cette recherche
121 // et les resultats trop vieux avec une marge
122 // pas de AS resultats dans un delete (mysql)
123 $whered = str_replace(array("resultats.recherche", "resultats.table_objet", "resultats.serveur"),
124 array("recherche", "table_objet", "serveur"), $where);
126 sql_delete('spip_resultats',
127 "NOT($where_resultat_recent) OR ($whered)");
129 // inserer les resultats dans la table de cache des resultats
130 if (count($points)) {
131 $tab_couples = array();
132 foreach ($points as $id => $p) {
133 $tab_couples[] = array(
134 'recherche' => $hash,
136 'points' => $p['score'],
137 'table_objet' => $table,
138 'serveur' => $hash_serv,
141 sql_insertq_multi('spip_resultats', $tab_couples, array());
145 if (!isset($cache[$serveur][$table][$recherche])) {
147 $cache[$serveur][$table][$recherche] = array("resultats.points AS points", $where);
149 if (sql_countsel('spip_resultats as resultats', $where)) {
150 $rows = sql_allfetsel('resultats.id,resultats.points', 'spip_resultats as resultats', $where);
152 $cache[$serveur][$table][$recherche] = generer_select_where_explicites($table, $primary, $rows, $serveur);
156 return $cache[$serveur][$table][$recherche];
161 * Generer le select et where qui contiennent explicitement
162 * les id et points (ie comme dans SPIP 1.9.x)
163 * quand on fait une recherche sur une table externe
165 * @param string $table
166 * @param string $primary
168 * @param string $serveur
171 function generer_select_where_explicites($table, $primary, $rows, $serveur) {
172 # calculer le {id_article IN()} et le {... as points}
174 return array("''", "0=1");
176 $listes_ids = array();
178 foreach ($rows as $r) {
179 $listes_ids[$r['points']][] = $r['id'];
182 foreach ($listes_ids as $p => $ids) {
184 sql_in("$table.$primary", $ids, '', $serveur)
188 return array("$select AS points ", sql_in("$table.$primary", array_map('reset', $rows), '', $serveur));