/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
- * Copyright (c) 2001-2012 *
+ * Copyright (c) 2001-2016 *
* Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
* *
* Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
}
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(translitteration($recherche));
+ $recherche = trim($recherche);
$is_preg = false;
- if (substr($recherche,0,1)=='/' AND substr($recherche,-1,1)=='/'){
+ if (substr($recherche, 0, 1) == '/' and substr($recherche, -1, 1) == '/' and strlen($recherche) > 2) {
// c'est une preg
- $preg = $recherche.$options['preg_flags'];
+ $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 = preg_replace(',\s+,'.$u, '|', $recherche);
+ $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).'/' . $options['preg_flags'];
+ $preg = '/'.str_replace('/', '\\/', $recherche_trans).'/' . $options['preg_flags'];
}
// Si la chaine est inactive, on va utiliser LIKE pour aller plus vite
array('(',')','?','[', ']', '+', '*', '/'),
array('\(','\)','[?]', '\[', '\]', '\+', '\*', '\/'),
$recherche);
- $recherche_mod = $recherche;
+ $recherche_trans = translitteration($recherche);
+ $recherche_mod = $recherche_trans;
// echapper les % et _
$q = str_replace(array('%','_'), array('\%', '\_'), trim($recherche));
$q = sql_quote(trim($recherche, '/'));
}
- return array($methode, $q, $preg);
+ // 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<spip_strlen($q);$i++){
+ $char = spip_substr($q,$i,1);
+ if (!is_ascii($char)
+ AND $char_t = translitteration($char)
+ AND $char_t !== $char){
+ $q_t = str_replace($char,$is_preg?".":"_", $q_t);
+ }
+ }
+
+ $q = $q_t;
+
+ // fix : SQLite 3 est sensible aux accents, on jokerise les caracteres
+ // les plus frequents qui peuvent etre accentues
+ // (oui c'est tres dicustable...)
+ if (isset($GLOBALS['connexions'][$options['serveur']?$options['serveur']:0]['type'])
+ AND strncmp($GLOBALS['connexions'][$options['serveur']?$options['serveur']:0]['type'],'sqlite',6)==0){
+ $q_t = strtr($q,"aeuioc",$is_preg?"......":"______");
+ // si il reste au moins un char significatif...
+ if (preg_match(",[^'%_.],",$q_t))
+ $q = $q_t;
+ }
+
+ return $expression[$key] = array($methode, $q, $preg);
}