3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
6 * Copyright (c) 2001-2012 *
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 if (!defined('_ECRIRE_INC_VERSION')) return;
16 include_spip('inc/rechercher');
17 if (!defined('_DELAI_CACHE_resultats')) define('_DELAI_CACHE_resultats', 600);
20 * Preparer les listes id_article IN (...) pour les parties WHERE
21 * et points = des requetes du moteur de recherche
22 * http://doc.spip.org/@inc_prepare_recherche_dist
24 * Le parametre $serveur est utilise pour savoir sur quelle base on cherche
25 * mais l'index des resultats est toujours stock� sur le serveur principal
26 * car on ne sait pas si la base distante dispose d'une table spip_resultats
27 * ni meme si on aurait le droit d'ecrire dedans
29 * @param string $recherche
31 * @param string $table
32 * table dans laquelle porte la recherche
34 * critere conditionnel sur {recherche?}
35 * @param string $serveur
36 * serveur de base de donnees
37 * @param array $modificateurs
38 * modificateurs de boucle, ie liste des criteres presents
39 * @param string $primary
40 * cle primaire de la table de recherche
43 function inc_prepare_recherche_dist($recherche, $table='articles', $cond=false, $serveur='', $modificateurs = array(), $primary='') {
44 static $cache = array();
45 $delai_fraicheur = min(_DELAI_CACHE_resultats
,time()-$GLOBALS['meta']['derniere_modif']);
47 // si recherche n'est pas dans le contexte, on va prendre en globals
48 // ca permet de faire des inclure simple.
49 if (!isset($recherche) AND isset($GLOBALS['recherche']))
50 $recherche = $GLOBALS['recherche'];
52 // traiter le cas {recherche?}
53 if ($cond AND !strlen($recherche))
54 return array("0 as points" /* as points */, /* where */ '');
59 if (!isset($cache[$serveur][$table][$recherche])){
60 $hash_serv = ($serveur?
substr(md5($serveur),0,16):'');
61 $hash = substr(md5($recherche . $table),0,16);
62 $where = "(resultats.recherche='$hash' AND resultats.table_objet=".sql_quote($table)." AND resultats.serveur='$hash_serv')";
63 $row = sql_fetsel('UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(resultats.maj) AS fraicheur','spip_resultats AS resultats',$where,'','fraicheur DESC','0,1');
65 OR ($row['fraicheur']>$delai_fraicheur)
66 OR (defined('_VAR_MODE') AND _VAR_MODE
=='recalcul')){
71 // si on n'a pas encore traite les donnees dans une boucle precedente
73 //$tables = liste_des_champs();
74 $x = objet_type($table);
75 $points = recherche_en_base($recherche,
83 // pas de résultat, pas de point
84 $points = isset($points[$x]) ?
$points[$x] : array();
86 // permettre aux plugins de modifier le resultat
87 $points = pipeline('prepare_recherche',array(
88 'args'=>array('type'=>$x,'recherche'=>$recherche,'serveur'=>$serveur,'modificateurs'=>$modificateurs),
92 // supprimer les anciens resultats de cette recherche
93 // et les resultats trop vieux avec une marge
94 // pas de AS resultats dans un delete (mysql)
95 $whered = str_replace(array("resultats.recherche","resultats.table_objet","resultats.serveur"),array("recherche","table_objet","serveur"),$where);
96 sql_delete('spip_resultats', 'NOT(' .sql_date_proche('maj', (0-($delai_fraicheur+
100)), " SECOND") . ") OR ($whered)");
98 // inserer les resultats dans la table de cache des resultats
100 $tab_couples = array();
101 foreach ($points as $id => $p){
102 $tab_couples[] = array(
103 'recherche' => $hash,
105 'points' => $p['score'],
106 'table_objet' => $table,
107 'serveur' => $hash_serv,
110 sql_insertq_multi('spip_resultats',$tab_couples,array());
114 if (!isset($cache[$serveur][$table][$recherche])){
116 $cache[$serveur][$table][$recherche] = array("resultats.points AS points",$where);
118 if (sql_countsel('spip_resultats as resultats',$where))
119 $rows = sql_allfetsel('resultats.id,resultats.points','spip_resultats as resultats',$where);
120 $cache[$serveur][$table][$recherche] = generer_select_where_explicites($table, $primary, $rows, $serveur);
124 return $cache[$serveur][$table][$recherche];
129 * Generer le select et where qui contiennent explicitement
130 * les id et points (ie comme dans SPIP 1.9.x)
131 * quand on fait une recherche sur une table externe
133 * @param string $table
134 * @param string $primary
136 * @param string $serveur
139 function generer_select_where_explicites($table, $primary, $rows, $serveur){
140 # calculer le {id_article IN()} et le {... as points}
142 return array("''", "0=1");
145 $listes_ids = array();
147 foreach ($rows as $r)
148 $listes_ids[$r['points']][] = $r['id'];
150 foreach ($listes_ids as $p => $ids)
152 sql_in("$table.$primary", $ids,'',$serveur)
155 return array("$select AS points ",calcul_mysql_in("$table.$primary",array_map('reset',$rows),'',$serveur));