Changeset 108346 in spip-zone
- Timestamp:
- Jan 4, 2018, 9:18:38 AM (3 years ago)
- Location:
- _plugins_/fulltext/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
_plugins_/fulltext/trunk/inc/rechercher.php
r104327 r108346 4 4 * SPIP, Systeme de publication pour l'internet * 5 5 * * 6 * Copyright (c) 2001-201 4*6 * Copyright (c) 2001-2017 * 7 7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * 8 8 * * … … 11 11 \***************************************************************************/ 12 12 13 /** 14 * Gestion des recherches 15 * 16 * @package SPIP\Core\Recherche 17 **/ 13 18 14 19 if (!defined('_ECRIRE_INC_VERSION')) { 15 20 return; 16 }17 18 19 // Donne la liste des champs/tables ou l'on sait chercher/remplacer20 // avec un poids pour le score21 // https://code.spip.net/@liste_des_champs22 function liste_des_champs() {23 static $liste=null;24 if (is_null($liste)) {25 $liste = array();26 // recuperer les tables_objets_sql declarees27 include_spip('base/objets');28 $tables_objets = lister_tables_objets_sql();29 foreach ($tables_objets as $t => $infos) {30 if ($infos['rechercher_champs']) {31 $liste[$infos['type']] = $infos['rechercher_champs'];32 }33 }34 // puis passer dans le pipeline35 $liste = pipeline('rechercher_liste_des_champs', $liste);36 }37 return $liste;38 }39 40 41 // Recherche des auteurs et mots-cles associes42 // en ne regardant que le titre ou le nom43 // https://code.spip.net/@liste_des_jointures44 function liste_des_jointures() {45 static $liste=null;46 if (is_null($liste)) {47 $liste = array();48 // recuperer les tables_objets_sql declarees49 include_spip('base/objets');50 $tables_objets = lister_tables_objets_sql();51 foreach ($tables_objets as $t => $infos) {52 if ($infos['rechercher_jointures']) {53 $liste[$infos['type']] = $infos['rechercher_jointures'];54 }55 }56 // puis passer dans le pipeline57 $liste = pipeline('rechercher_liste_des_jointures', $liste);58 }59 return $liste;60 21 } 61 22 … … 79 40 } 80 41 42 /* 43 * Le reste du fichier est identique au core SPIP 3 44 */ 45 46 defined('_RECHERCHE_LOCK_KEY') || define('_RECHERCHE_LOCK_KEY', 'fulltext'); 47 48 /** 49 * Donne la liste des champs/tables où l'on sait chercher / remplacer 50 * avec un poids pour le score 51 * 52 * Utilise l'information `rechercher_champs` sur la déclaration 53 * des objets éditoriaux. 54 * 55 * @pipeline_appel rechercher_liste_des_champs 56 * @uses lister_tables_objets_sql() 57 * 58 * @return array Couples (type d'objet => Couples (champ => score)) 59 */ 60 function liste_des_champs() { 61 static $liste = null; 62 if (is_null($liste)) { 63 $liste = array(); 64 // recuperer les tables_objets_sql declarees 65 include_spip('base/objets'); 66 $tables_objets = lister_tables_objets_sql(); 67 foreach ($tables_objets as $t => $infos) { 68 if ($infos['rechercher_champs']) { 69 $liste[$infos['type']] = $infos['rechercher_champs']; 70 } 71 } 72 // puis passer dans le pipeline 73 $liste = pipeline('rechercher_liste_des_champs', $liste); 74 } 75 76 return $liste; 77 } 78 79 80 // Recherche des auteurs et mots-cles associes 81 // en ne regardant que le titre ou le nom 82 // http://code.spip.net/@liste_des_jointures 83 function liste_des_jointures() { 84 static $liste = null; 85 if (is_null($liste)) { 86 $liste = array(); 87 // recuperer les tables_objets_sql declarees 88 include_spip('base/objets'); 89 $tables_objets = lister_tables_objets_sql(); 90 foreach ($tables_objets as $t => $infos) { 91 if ($infos['rechercher_jointures']) { 92 $liste[$infos['type']] = $infos['rechercher_jointures']; 93 } 94 } 95 // puis passer dans le pipeline 96 $liste = pipeline('rechercher_liste_des_jointures', $liste); 97 } 98 99 return $liste; 100 } 81 101 82 102 function expression_recherche($recherche, $options) { … … 101 121 102 122 $is_preg = false; 103 if (substr($recherche, 0, 1) == '/' and substr($recherche, -1, 1) == '/' ) {123 if (substr($recherche, 0, 1) == '/' and substr($recherche, -1, 1) == '/' and strlen($recherche) > 2) { 104 124 // c'est une preg 105 125 $recherche_trans = translitteration($recherche); 106 $preg = $recherche_trans .$options['preg_flags'];126 $preg = $recherche_trans . $options['preg_flags']; 107 127 $is_preg = true; 108 128 } else { 109 // s'il y a plusieurs mots il faut les chercher tous : oblige REGEXP 129 // s'il y a plusieurs mots il faut les chercher tous : oblige REGEXP, 110 130 // sauf ceux de moins de 4 lettres (on supprime ainsi 'le', 'les', 'un', 111 131 // 'une', 'des' ...) 112 if (preg_match(',\s+,'. $u, $recherche)) { 132 133 // attention : plusieurs mots entre guillemets sont a rechercher tels quels 134 $recherche_trans = $recherche_mod = $recherche; 135 136 // les expressions entre " " sont un mot a chercher tel quel 137 // -> on remplace les espaces par un \x1 et on enleve les guillemets 138 if (preg_match(',["][^"]+["],Uims', $recherche_mod, $matches)) { 139 foreach ($matches as $match) { 140 $word = preg_replace(",\s+,Uims", "\x1", $match); 141 $word = trim($word, '"'); 142 $recherche_mod = str_replace($match, $word, $recherche_mod); 143 } 144 } 145 146 if (preg_match(",\s+," . $u, $recherche_mod)) { 113 147 $is_preg = true; 148 114 149 $recherche_inter = '|'; 115 $recherche_mots = explode(' ', $recherche );150 $recherche_mots = explode(' ', $recherche_mod); 116 151 $min_long = defined('_RECHERCHE_MIN_CAR') ? _RECHERCHE_MIN_CAR : 4; 117 152 foreach ($recherche_mots as $mot) { 118 153 if (strlen($mot) >= $min_long) { 119 $recherche_inter .= $mot.' '; 154 // echapper les caracteres de regexp qui sont eventuellement dans la recherche 155 $recherche_inter .= preg_quote($mot) . ' '; 120 156 } 121 157 } 122 // mais on cherche quand meme l'expression complete, meme si elle 158 $recherche_inter = str_replace("\x1", '\s', $recherche_inter); 159 160 // mais on cherche quand même l'expression complète, même si elle 123 161 // comporte des mots de moins de quatre lettres 124 $recherche = rtrim( $recherche.preg_replace(',\s+,'.$u, '|', $recherche_inter), '|');125 }126 127 $recherche_trans = translitteration($recherche); 128 $preg = '/' .str_replace('/', '\\/', $recherche_trans).'/' . $options['preg_flags'];162 $recherche = rtrim(preg_quote($recherche) . preg_replace(',\s+,' . $u, '|', $recherche_inter), '|'); 163 $recherche_trans = translitteration($recherche); 164 } 165 166 $preg = '/' . str_replace('/', '\\/', $recherche_trans) . '/' . $options['preg_flags']; 129 167 } 130 168 … … 132 170 // ou si l'expression reguliere est invalide 133 171 if (!$is_preg 134 or (@preg_match($preg, '') === false) ) { 172 or (@preg_match($preg, '') === false) 173 ) { 135 174 $methode = 'LIKE'; 136 175 $u = $GLOBALS['meta']['pcre_u']; 137 // eviter les parentheses et autres caracteres qui interferent avec pcre 138 // par la suite (dans le preg_match_all) s'il y a des reponses 139 $recherche = str_replace( 140 array('(',')','?','[', ']', '+', '*', '/'), 141 array('\(','\)','[?]', '\[', '\]', '\+', '\*', '\/'), 142 $recherche 143 ); 176 177 // echapper les % et _ 178 $q = str_replace(array('%', '_'), array('\%', '\_'), trim($recherche)); 179 180 // 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 181 $recherche = preg_quote($recherche, '/'); 144 182 $recherche_trans = translitteration($recherche); 145 183 $recherche_mod = $recherche_trans; 146 184 147 // echapper les % et _148 $q = str_replace(array('%','_'), array('\%', '\_'), trim($recherche));149 185 // les expressions entre " " sont un mot a chercher tel quel 150 186 // -> on remplace les espaces par un _ et on enleve les guillemets 187 // corriger le like dans le $q 151 188 if (preg_match(',["][^"]+["],Uims', $q, $matches)) { 152 189 foreach ($matches as $match) { 153 // corriger le like dans le $q 154 $word = preg_replace(',\s+,Uims', '_', $match); 190 $word = preg_replace(",\s+,Uims", "_", $match); 155 191 $word = trim($word, '"'); 156 192 $q = str_replace($match, $word, $q); 157 // corriger la regexp 158 $word = preg_replace(',\s+,Uims', '[\s]', $match); 193 } 194 } 195 // corriger la regexp 196 if (preg_match(',["][^"]+["],Uims', $recherche_mod, $matches)) { 197 foreach ($matches as $match) { 198 $word = preg_replace(",\s+,Uims", "[\s]", $match); 159 199 $word = trim($word, '"'); 160 200 $recherche_mod = str_replace($match, $word, $recherche_mod); … … 162 202 } 163 203 $q = sql_quote( 164 '%'165 . preg_replace( ',\s+,' . $u, '%', $q)166 . '%'204 "%" 205 . preg_replace(",\s+," . $u, "%", $q) 206 . "%" 167 207 ); 168 208 169 $preg = '/'.preg_replace(',\s+,' . $u, '.+', trim($recherche_mod)).'/' . $options['preg_flags']; 209 $preg = '/' . preg_replace(",\s+," . $u, ".+", trim($recherche_mod)) . '/' . $options['preg_flags']; 210 170 211 } else { 171 212 $methode = 'REGEXP'; … … 180 221 if (!is_ascii($char) 181 222 and $char_t = translitteration($char) 182 and $char_t !== $char) { 183 $q_t = str_replace($char, $is_preg ? '.' : '_', $q_t); 223 and $char_t !== $char 224 ) { 225 $q_t = str_replace($char, $is_preg ? "." : "_", $q_t); 184 226 } 185 227 } … … 191 233 // (oui c'est tres dicustable...) 192 234 if (isset($GLOBALS['connexions'][$options['serveur'] ? $options['serveur'] : 0]['type']) 193 and strncmp($GLOBALS['connexions'][$options['serveur'] ? $options['serveur'] : 0]['type'], 'sqlite', 6) == 0) { 194 $q_t = strtr($q, 'aeuioc', $is_preg ? '......' : '______'); 235 and strncmp($GLOBALS['connexions'][$options['serveur'] ? $options['serveur'] : 0]['type'], 'sqlite', 6) == 0 236 ) { 237 $q_t = strtr($q, "aeuioc", $is_preg ? "......" : "______"); 195 238 // si il reste au moins un char significatif... 196 239 if (preg_match(",[^'%_.],", $q_t)) { … … 203 246 204 247 205 // Effectue une recherche sur toutes les tables de la base de donnees 206 // options : 207 // - toutvoir pour eviter autoriser(voir) 208 // - flags pour eviter les flags regexp par defaut (UimsS) 209 // - champs pour retourner les champs concernes 210 // - score pour retourner un score 211 // On peut passer les tables, ou une chaine listant les tables souhaitees 212 // https://code.spip.net/@recherche_en_base 248 249 /** 250 * Effectue une recherche sur toutes les tables de la base de données 251 * 252 * @uses liste_des_champs() 253 * @uses inc_recherche_to_array_dist() 254 * 255 * @param string $recherche 256 * Le terme de recherche 257 * @param null|array|string $tables 258 * - null : toutes les tables acceptant des recherches 259 * - array : liste des tables souhaitées 260 * - string : une chaîne listant les tables souhaitées, séparées par des virgules (préférer array cependant) 261 * @param array $options { 262 * @var $toutvoir pour éviter autoriser(voir) 263 * @var $flags pour éviter les flags regexp par défaut (UimsS) 264 * @var $champs pour retourner les champs concernés 265 * @var $score pour retourner un score 266 * } 267 * @param string $serveur 268 * @return array 269 */ 213 270 function recherche_en_base($recherche = '', $tables = null, $options = array(), $serveur = '') { 214 271 include_spip('base/abstract_sql'); … … 218 275 219 276 if (is_string($tables) 220 and $tables != '') { 277 and $tables != '' 278 ) { 221 279 $toutes = array(); 222 280 foreach (explode(',', $tables) as $t) { … … 240 298 241 299 // options par defaut 242 $options = array_merge( 243 array( 244 'preg_flags' => 'UimsS', 245 'toutvoir' => false, 246 'champs' => false, 247 'score' => false, 248 'matches' => false, 249 'jointures' => false, 250 'serveur' => $serveur 251 ), 300 $options = array_merge(array( 301 'preg_flags' => 'UimsS', 302 'toutvoir' => false, 303 'champs' => false, 304 'score' => false, 305 'matches' => false, 306 'jointures' => false, 307 'serveur' => $serveur 308 ), 252 309 $options 253 310 ); … … 262 319 // } 263 320 264 include_spip('inc/memoization');265 321 include_spip('inc/recherche_to_array'); 266 322 … … 268 324 # lock via memoization, si dispo 269 325 if (function_exists('cache_lock')) { 270 cache_lock($lock = 'fulltext '.$table.' '.$recherche);326 cache_lock($lock = _RECHERCHE_LOCK_KEY . ' ' . $table . ' ' . $recherche); 271 327 } 272 328 … … 281 337 282 338 283 spip_log("recherche $table ($recherche) : " . count($results[$table]) . ' resultats ' . spip_timer('rech'), 'recherche'); 339 spip_log("recherche $table ($recherche) : " . count($results[$table]) . " resultats " . spip_timer('rech'), 340 'recherche'); 284 341 285 342 if (isset($lock)) { … … 293 350 294 351 // Effectue une recherche sur toutes les tables de la base de donnees 295 // http s://code.spip.net/@remplace_en_base352 // http://code.spip.net/@remplace_en_base 296 353 function remplace_en_base($recherche = '', $remplace = null, $tables = null, $options = array()) { 297 354 include_spip('inc/modifier'); 298 355 299 356 // options par defaut 300 $options = array_merge( 301 array( 302 'preg_flags' => 'UimsS', 303 'toutmodifier' => false 304 ), 357 $options = array_merge(array( 358 'preg_flags' => 'UimsS', 359 'toutmodifier' => false 360 ), 305 361 $options 306 362 ); … … 314 370 $results = recherche_en_base($recherche, $tables, $options); 315 371 316 $preg = '/' .str_replace('/', '\\/', $recherche).'/' . $options['preg_flags'];372 $preg = '/' . str_replace('/', '\\/', $recherche) . '/' . $options['preg_flags']; 317 373 318 374 foreach ($results as $table => $r) { … … 320 376 foreach ($r as $id => $x) { 321 377 if ($options['toutmodifier'] 322 or autoriser('modifier', $table, $id)) { 378 or autoriser('modifier', $table, $id) 379 ) { 323 380 $modifs = array(); 324 381 foreach ($x['champs'] as $key => $val) { 325 382 if ($key == $_id_table) { 326 next;383 continue; 327 384 } 328 385 $repl = preg_replace($preg, $remplace, $val); … … 332 389 } 333 390 if ($modifs) { 334 objet_modifier_champs( 335 $table, 336 $id, 391 objet_modifier_champs($table, $id, 337 392 array( 338 393 'champs' => array_keys($modifs), 339 394 ), 340 $modifs 341 ); 395 $modifs); 342 396 } 343 397 } -
_plugins_/fulltext/trunk/paquet.xml
r106544 r108346 2 2 prefix="fulltext" 3 3 categorie="navigation" 4 version="1.1.2 0"4 version="1.1.21" 5 5 etat="test" 6 6 compatibilite="[3.0.1;3.2.*]"
Note: See TracChangeset
for help on using the changeset viewer.