source: spip-zone/_dev_/critere_recherche_directe.php @ 14303

Last change on this file since 14303 was 14303, checked in by fil@…, 13 years ago

un critere de recherche directe qui marche pas mal ; dernier commit avant integration au core

File size: 4.1 KB
Line 
1<?php
2
3#
4#  Dans la version dev de SPIP, une API inc/rechercher
5#  permet de fouiller les tables directement, sans utiliser
6#  l'indexation
7#
8#  En appelant ce fichier depuis mes_fonctions, le moteur de
9#  recherche public utilise cette API au lieu de l'indexation
10#  classique
11#
12#  (Pour l'instant c'est brut de pomme, puisqu'on passe les mots
13#  recherches directement au serveur comme une expression rationnelle (REGEXP)
14#  ce qui n'est pas souhaité ni très sécurisé)
15#
16#  Pour la performance voir tmp/recherche.log
17#
18
19// {recherche} ou {recherche susan}
20// http://www.spip.net/@recherche
21// http://doc.spip.org/@critere_recherche_dist
22function critere_recherche($idb, &$boucles, $crit) {
23        global $table_des_tables;
24        $boucle = &$boucles[$idb];
25        $t = $boucle->id_table;
26        if (in_array($t,$table_des_tables))
27                $t = "spip_$t";
28
29        if (isset($crit->param[0]))
30                $quoi = calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent);
31        else
32                $quoi = '@$Pile[0]["recherche"]';
33
34        // Ne pas executer la requete en cas de hash vide
35        $boucle->hash = '
36        // RECHERCHE
37        list($rech_select, $rech_where) = prepare_recherche_api('.$quoi.', "'.$boucle->primary.'", "'.$boucle->id_table.'", "'.$t.'", "'.$crit->cond.'");
38        ';
39
40        // Sauf si le critere est conditionnel {recherche ?}
41        if (!$crit->cond)
42                $boucle->hash .= '
43        if ($rech_where) ';
44
45        $t = $boucle->id_table . '.' . $boucle->primary;
46        if (!in_array($t, $boucles[$idb]->select))
47          $boucle->select[]= $t; # pour postgres, neuneu ici
48        $boucle->select[]= '$rech_select as points';
49
50        // et la recherche trouve
51        $boucle->where[]= '$rech_where';
52}
53
54function prepare_recherche_api($recherche, $primary = 'id_article', $id_table='articles',$nom_table='spip_articles', $cond=false) {
55        static $cache = array();
56        static $fcache = array();
57
58        // si recherche n'est pas dans le contexte, on va prendre en globals
59        // ca permet de faire des inclure simple.
60        if (!isset($recherche) AND isset($GLOBALS['recherche']))
61                $recherche = $GLOBALS['recherche'];
62
63        // traiter le cas {recherche?}
64        if ($cond AND !strlen($recherche))
65                return array("''" /* as points */, /* where */ '1');
66
67        spip_timer("rechapi");
68        // Premier passage : chercher eventuel un cache des donnees sur le disque
69        if (!$cache[$recherche]['hash']) {
70                $dircache = sous_repertoire(_DIR_CACHE,'rech2');
71                $fcache[$recherche] =
72                        $dircache . substr(md5($recherche),0,10).'.txt';
73                if (lire_fichier($fcache[$recherche], $contenu))
74                        $cache[$recherche] = @unserialize($contenu);
75        }
76
77        // si on n'a pas encore traite les donnees dans une boucle precedente
78        if (!$cache[$recherche][$primary]) {
79                include_spip('inc/rechercher');
80
81                $tables = liste_des_champs();
82                $x = preg_replace(',s$,', '', $id_table);
83                if ($x == 'syndic') $x = 'site';
84                $points = recherche_en_base($recherche,
85                        $x,
86                        array(
87                                'score' => true,
88                                'toutvoir' => true,
89                                'jointures' => true
90                        ));
91                $points = $points[$x];
92
93                # Pour les forums, unifier par id_thread et forcer statut='publie'
94                if ($x == 'forum' AND $points) {
95                        $p2 = array();
96                        $s = spip_query("SELECT id_thread, id_forum FROM spip_forum WHERE statut='publie' AND ".calcul_mysql_in('id_forum', array_keys($points)));
97                        while ($t = spip_fetch_array($s))
98                                $p2[intval($t['id_thread'])]['score']
99                                        += $points[intval($t['id_forum'])]['score'];
100                        $points = $p2;
101                }
102
103                # calculer le {id_article IN()} et le {... as points}
104                if (!count($points)) {
105                        $cache[$recherche][$primary] = array("''", '0');
106                } else {
107                        $listes_ids = array();
108                        $select = '0';
109                        foreach ($points as $id => $p)
110                                $listes_ids[$p['score']] .= ','.$id;
111                        foreach ($listes_ids as $p => $liste_ids)
112                                $select .= "+$p*(".
113                                        calcul_mysql_in("$id_table.$primary", substr($liste_ids, 1))
114                                        .") ";
115
116                        $cache[$recherche][$primary] = array($select,
117                                '('.calcul_mysql_in("$id_table.$primary",
118                                        array_keys($points)).')'
119                                );
120                }
121
122                // ecrire le cache de la recherche sur le disque
123                ecrire_fichier($fcache[$recherche], serialize($cache[$recherche]));
124                // purger le petit cache
125                nettoyer_petit_cache('rech2', 300);
126        }
127
128        spip_log("recherche api ($recherche) de #$primary# : ".spip_timer("rechapi"));
129
130        return $cache[$recherche][$primary];
131}
132
133
134?>
Note: See TracBrowser for help on using the repository browser.