X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=www%2Fecrire%2Finc%2Frechercher.php;fp=www%2Fecrire%2Finc%2Frechercher.php;h=e289c73e705506088948225c2e92b9fc5e9ed0a8;hb=a33c2ba9d919664b3bb0f565f8e9a8b9d8530cdb;hp=0000000000000000000000000000000000000000;hpb=8945248b3d948385798d9aa355c70e7089aca2b3;p=lhc%2Fweb%2Fclavette_www.git diff --git a/www/ecrire/inc/rechercher.php b/www/ecrire/inc/rechercher.php new file mode 100644 index 0000000..e289c73 --- /dev/null +++ b/www/ecrire/inc/rechercher.php @@ -0,0 +1,300 @@ +$infos){ + if ($infos['rechercher_champs']){ + $liste[$infos['type']] = $infos['rechercher_champs']; + } + } + // puis passer dans le pipeline + $liste = pipeline('rechercher_liste_des_champs', $liste); + } + return $liste; +} + + +// Recherche des auteurs et mots-cles associes +// en ne regardant que le titre ou le nom +// http://doc.spip.org/@liste_des_jointures +function liste_des_jointures() { + static $liste=null; + if (is_null($liste)) { + $liste = array(); + // recuperer les tables_objets_sql declarees + include_spip('base/objets'); + $tables_objets = lister_tables_objets_sql(); + foreach($tables_objets as $t=>$infos){ + if ($infos['rechercher_jointures']){ + $liste[$infos['type']] = $infos['rechercher_jointures']; + } + } + // puis passer dans le pipeline + $liste = pipeline('rechercher_liste_des_jointures', $liste); + } + return $liste; +} + +function expression_recherche($recherche, $options) { + // ne calculer qu'une seule fois l'expression par hit + // (meme si utilisee dans plusieurs boucles) + static $expression = array(); + $key = serialize(array($recherche, $options['preg_flags'])); + if (isset($expression[$key])) + return $expression[$key]; + + $u = $GLOBALS['meta']['pcre_u']; + if ($u AND strpos($options['preg_flags'],$u)===false) + $options['preg_flags'] .= $u; + include_spip('inc/charsets'); + $recherche = trim($recherche); + + $is_preg = false; + if (substr($recherche,0,1)=='/' AND substr($recherche,-1,1)=='/'){ + // c'est une preg + $recherche_trans = translitteration($recherche); + $preg = $recherche_trans.$options['preg_flags']; + $is_preg = true; + } + else{ + // s'il y a plusieurs mots il faut les chercher tous : oblige REGEXP + // sauf ceux de moins de 4 lettres (on supprime ainsi 'le', 'les', 'un', + // 'une', 'des' ...) + if (preg_match(",\s+,".$u, $recherche)){ + $is_preg = true; + $recherche_inter = '|'; + $recherche_mots = explode(' ', $recherche); + $min_long = defined('_RECHERCHE_MIN_CAR') ? _RECHERCHE_MIN_CAR : 4; + foreach ($recherche_mots as $mot) { + if (strlen($mot) >= $min_long) { + $recherche_inter .= $mot.' '; + } + } + // mais on cherche quand même l'expression complète, même si elle + // comporte des mots de moins de quatre lettres + $recherche = rtrim($recherche.preg_replace(',\s+,'.$u, '|', $recherche_inter), '|'); + $recherche_trans = translitteration($recherche); + } + + $preg = '/'.str_replace('/', '\\/', $recherche_trans).'/' . $options['preg_flags']; + } + + // Si la chaine est inactive, on va utiliser LIKE pour aller plus vite + // ou si l'expression reguliere est invalide + if (!$is_preg + OR (@preg_match($preg,'')===FALSE) ) { + $methode = 'LIKE'; + $u = $GLOBALS['meta']['pcre_u']; + // eviter les parentheses et autres caractères qui interferent avec pcre par la suite (dans le preg_match_all) s'il y a des reponses + $recherche = str_replace( + array('(',')','?','[', ']', '+', '*', '/'), + array('\(','\)','[?]', '\[', '\]', '\+', '\*', '\/'), + $recherche); + $recherche_trans = translitteration($recherche); + $recherche_mod = $recherche_trans; + + // echapper les % et _ + $q = str_replace(array('%','_'), array('\%', '\_'), trim($recherche)); + // les expressions entre " " sont un mot a chercher tel quel + // -> on remplace les espaces par un _ et on enleve les guillemets + if (preg_match(',["][^"]+["],Uims',$q,$matches)){ + foreach($matches as $match){ + // corriger le like dans le $q + $word = preg_replace(",\s+,Uims","_",$match); + $word = trim($word,'"'); + $q = str_replace($match,$word,$q); + // corriger la regexp + $word = preg_replace(",\s+,Uims","[\s]",$match); + $word = trim($word,'"'); + $recherche_mod = str_replace($match,$word,$recherche_mod); + } + } + $q = sql_quote( + "%" + . preg_replace(",\s+,".$u, "%", $q) + . "%" + ); + + $preg = '/'.preg_replace(",\s+,".$u, ".+", trim($recherche_mod)).'/' . $options['preg_flags']; + + } else { + $methode = 'REGEXP'; + $q = sql_quote(trim($recherche, '/')); + } + + // tous les caracteres transliterables de $q sont remplaces par un joker + // permet de matcher en SQL meme si on est sensible aux accents (SQLite) + $q_t = $q; + for($i = 0;$i 'UimsS', + 'toutvoir' => false, + 'champs' => false, + 'score' => false, + 'matches' => false, + 'jointures' => false, + 'serveur' => $serveur + ), + $options + ); + + $results = array(); + + // Utiliser l'iterateur (DATA:recherche) + // pour recuperer les couples (id_objet, score) + // Le resultat est au format { + // id1 = { 'score' => x, attrs => { } }, + // id2 = { 'score' => x, attrs => { } }, + // } + include_spip('inc/memoization'); + foreach ($tables as $table => $champs) { + # lock via memoization, si dispo + if (function_exists('cache_lock')) + cache_lock($lock = 'recherche '.$table.' '.$recherche); + + spip_timer('rech'); + + // TODO: ici plutot charger un iterateur via l'API iterateurs + include_spip('inc/recherche_to_array'); + $to_array = charger_fonction('recherche_to_array', 'inc'); + $results[$table] = $to_array($recherche, + array_merge($options, array('table' => $table, 'champs' => $champs)) + ); + ##var_dump($results[$table]); + + + spip_log("recherche $table ($recherche) : ".count($results[$table])." resultats ".spip_timer('rech'),'recherche'); + + if (isset($lock)) + cache_unlock($lock); + } + + return $results; +} + + +// Effectue une recherche sur toutes les tables de la base de donnees +// http://doc.spip.org/@remplace_en_base +function remplace_en_base($recherche='', $remplace=NULL, $tables=NULL, $options=array()) { + include_spip('inc/modifier'); + + // options par defaut + $options = array_merge(array( + 'preg_flags' => 'UimsS', + 'toutmodifier' => false + ), + $options + ); + $options['champs'] = true; + + + if (!is_array($tables)) + $tables = liste_des_champs(); + + $results = recherche_en_base($recherche, $tables, $options); + + $preg = '/'.str_replace('/', '\\/', $recherche).'/' . $options['preg_flags']; + + foreach ($results as $table => $r) { + $_id_table = id_table_objet($table); + foreach ($r as $id => $x) { + if ($options['toutmodifier'] + OR autoriser('modifier', $table, $id)) { + $modifs = array(); + foreach ($x['champs'] as $key => $val) { + if ($key == $_id_table) next; + $repl = preg_replace($preg, $remplace, $val); + if ($repl <> $val) + $modifs[$key] = $repl; + } + if ($modifs) + objet_modifier_champs($table, $id, + array( + 'champs' => array_keys($modifs), + ), + $modifs); + } + } + } +} + +?>