Changeset 88307 in spip-zone for _plugins_/fulltext


Ignore:
Timestamp:
Mar 31, 2015, 7:14:51 AM (5 years ago)
Author:
cedric@…
Message:

Report de https://core.spip.net/projects/spip/repository/revisions/21502

File:
1 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/fulltext/trunk/inc/rechercher.php

    r85859 r88307  
    8686
    8787        $u = $GLOBALS['meta']['pcre_u'];
     88        if ($u AND strpos($options['preg_flags'],$u)===false)
     89                $options['preg_flags'] .= $u;
    8890        include_spip('inc/charsets');
    89         $recherche = trim(translitteration($recherche));
     91        $recherche = trim($recherche);
    9092
    9193        // retirer les + de +truc et les * de truc*
     
    9395        $recherche = preg_replace(",(\w)\*($|\s),Uims","$1$2",$recherche);
    9496
     97        $is_preg = false;
     98        if (substr($recherche,0,1)=='/' AND substr($recherche,-1,1)=='/'){
     99                // c'est une preg
     100                $recherche_trans = translitteration($recherche);
     101                $preg = $recherche_trans.$options['preg_flags'];
     102                $is_preg = true;
     103        }
     104        else{
    95105        // s'il y a plusieurs mots il faut les chercher tous : oblige REGEXP
    96         $recherche = preg_replace(',\s+,'.$u, '|', $recherche);
    97 
    98         $preg = '/'.str_replace('/', '\\/', $recherche).'/' . $options['preg_flags'];
     106                // sauf ceux de moins de 4 lettres (on supprime ainsi 'le', 'les', 'un',
     107                // 'une', 'des' ...)
     108                if (preg_match(",\s+,".$u, $recherche)){
     109                        $is_preg = true;
     110                        $recherche_inter = '|';
     111                        $recherche_mots = explode(' ', $recherche);
     112                        $min_long = defined('_RECHERCHE_MIN_CAR') ? _RECHERCHE_MIN_CAR : 4;
     113                        foreach ($recherche_mots as $mot) {
     114                                if (strlen($mot) >= $min_long) {
     115                                        $recherche_inter .= $mot.' ';
     116                                }
     117                        }
     118                        // mais on cherche quand même l'expression complète, même si elle
     119                        // comporte des mots de moins de quatre lettres
     120                        $recherche = rtrim($recherche.preg_replace(',\s+,'.$u, '|', $recherche_inter), '|');
     121                        $recherche_trans = translitteration($recherche);
     122                }
     123
     124                $preg = '/'.str_replace('/', '\\/', $recherche_trans).'/' . $options['preg_flags'];
     125        }
     126
    99127        // Si la chaine est inactive, on va utiliser LIKE pour aller plus vite
    100128        // ou si l'expression reguliere est invalide
    101         if (preg_quote($recherche, '/') == $recherche
     129        if (!$is_preg
    102130        OR (@preg_match($preg,'')===FALSE) ) {
    103131                $methode = 'LIKE';
    104132                $u = $GLOBALS['meta']['pcre_u'];
    105                 // eviter les parentheses qui interferent avec pcre par la suite (dans le preg_match_all) s'il y a des reponses
     133                // 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
    106134                $recherche = str_replace(
    107                         array('(',')','?','[', ']'),
    108                         array('\(','\)','[?]', '\[', '\]'),
     135                        array('(',')','?','[', ']', '+', '*', '/'),
     136                        array('\(','\)','[?]', '\[', '\]', '\+', '\*', '\/'),
    109137                        $recherche);
    110                 $recherche_mod = $recherche;
     138                $recherche_trans = translitteration($recherche);
     139                $recherche_mod = $recherche_trans;
    111140               
    112141                // echapper les % et _
     
    136165        } else {
    137166                $methode = 'REGEXP';
    138                 $q = sql_quote($recherche);
     167                $q = sql_quote(trim($recherche, '/'));
     168        }
     169
     170        // tous les caracteres transliterables de $q sont remplaces par un joker
     171        // permet de matcher en SQL meme si on est sensible aux accents (SQLite)
     172        $q_t = $q;
     173        for($i = 0;$i<spip_strlen($q);$i++){
     174                $char = spip_substr($q,$i,1);
     175                if (!is_ascii($char)
     176                  AND $char_t = translitteration($char)
     177                  AND $char_t !== $char){
     178                        $q_t = str_replace($char,$is_preg?".":"_", $q_t);
     179                }
     180        }
     181
     182        $q = $q_t;
     183
     184        // fix : SQLite 3 est sensible aux accents, on jokerise les caracteres
     185        // les plus frequents qui peuvent etre accentues
     186        // (oui c'est tres dicustable...)
     187        if (isset($GLOBALS['connexions'][$options['serveur']?$options['serveur']:0]['type'])
     188          AND strncmp($GLOBALS['connexions'][$options['serveur']?$options['serveur']:0]['type'],'sqlite',6)==0){
     189                $q_t = strtr($q,"aeuioc",$is_preg?"......":"______");
     190                // si il reste au moins un char significatif...
     191                if (preg_match(",[^'%_.],",$q_t))
     192                        $q = $q_t;
    139193        }
    140194
     
    212266                );
    213267                ##var_dump($results[$table]);
     268
    214269
    215270                spip_log("recherche $table ($recherche) : ".count($results[$table])." resultats ".spip_timer('rech'),'recherche');
Note: See TracChangeset for help on using the changeset viewer.