Ignore:
Timestamp:
Apr 8, 2014, 10:45:48 PM (10 years ago)
Author:
rvelices
Message:

bug 3056: quick search - fix warning; better management of variants and short words

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/functions_search.inc.php

    r28092 r28128  
    485485  var $modifier;
    486486  var $term; /* the actual word/phrase string*/
     487  var $variants = array();
    487488  var $scope;
    488489
     
    834835  var $images_iids;
    835836  var $iids;
    836 
    837   var $variants;
    838837}
    839838
     
    842841  $qsr->images_iids = array_fill(0, count($expr->stokens), array());
    843842
    844   $inflector = null;
    845   $lang_code = substr(get_default_language(),0,2);
    846   include_once(PHPWG_ROOT_PATH.'include/inflectors/'.$lang_code.'.php');
    847   $class_name = 'Inflector_'.$lang_code;
    848   if (class_exists($class_name))
    849   {
    850     $inflector = new $class_name;
    851   }
    852 
    853   $query_base = 'SELECT id from '.IMAGES_TABLE.' i WHERE ';
     843  $query_base = 'SELECT id from '.IMAGES_TABLE.' i WHERE
     844';
    854845  for ($i=0; $i<count($expr->stokens); $i++)
    855846  {
    856847    $token = $expr->stokens[$i];
    857     $term = $token->term;
    858848    $scope_id = isset($token->scope) ? $token->scope->id : 'photo';
    859849    $clauses = array();
    860850
    861     $like = addslashes($term);
     851    $like = addslashes($token->term);
    862852    $like = str_replace( array('%','_'), array('\\%','\\_'), $like); // escape LIKE specials %_
    863853    $file_like = 'CONVERT(file, CHAR) LIKE \'%'.$like.'%\'';
     
    868858        $clauses[] = $file_like;
    869859
    870         $variants = array();
    871         if (strlen($term)>2
    872           && ($expr->stoken_modifiers[$i] & (QST_QUOTED|QST_WILDCARD))==0
    873           && strcspn($term, '\'0123456789') == strlen($term) )
     860        $variants = array_merge(array($token->term), $token->variants);
     861        $fts = array();
     862        foreach ($variants as $variant)
    874863        {
    875           if ($inflector!=null)
    876             $variants = array_unique( array_diff( $inflector->get_variants($term), array($term) ) );
    877           $variants = trigger_event('qsearch_get_variants', $variants, $token, $expr);
    878           $variants = array_unique( array_diff( $variants, array($term) ) );
    879           $qsr->variants[$term] = $variants;
    880         }
    881 
    882         if (strlen($term)>3) // default minimum full text index
     864          if (mb_strlen($variant)<=3
     865            || strcspn($variant, '!"#$%&()*+,./:;<=>?@[\]^`{|}~') < 3)
     866          {// odd term or too short for full text search; fallback to regex but unfortunately this is diacritic/accent sensitive
     867            $pre = ($token->modifier & QST_WILDCARD_BEGIN) ? '' : '[[:<:]]';
     868            $post = ($token->modifier & QST_WILDCARD_END) ? '' : '[[:>:]]';
     869            foreach( array('i.name', 'i.comment') as $field)
     870              $clauses[] = $field.' REGEXP \''.$pre.addslashes(preg_quote($variant)).$post.'\'';
     871          }
     872          else
     873          {
     874            $ft = $variant;
     875            if ($expr->stoken_modifiers[$i] & QST_QUOTED)
     876              $ft = '"'.$ft.'"';
     877            if ($expr->stoken_modifiers[$i] & QST_WILDCARD_END)
     878              $ft .= '*';
     879            $fts[] = $ft;
     880          }
     881        }
     882
     883        if (count($fts))
    883884        {
    884           $ft = $term;
    885           if ($expr->stoken_modifiers[$i] & QST_QUOTED)
    886             $ft = '"'.$ft.'"';
    887           if ($expr->stoken_modifiers[$i] & QST_WILDCARD_END)
    888             $ft .= '*';
    889           foreach ($variants as $variant)
    890           {
    891             $ft.=' '.$variant;
    892           }
    893           $clauses[] = 'MATCH(i.name, i.comment) AGAINST( \''.addslashes($ft).'\' IN BOOLEAN MODE)';
    894         }
    895         else
    896         {
    897           foreach( array('i.name', 'i.comment') as $field)
    898           {
    899             $clauses[] = $field.' REGEXP \'[[:<:]]'.addslashes(preg_quote($term)).'[[:>:]]\'';
    900           }
     885          $clauses[] = 'MATCH(i.name, i.comment) AGAINST( \''.addslashes(implode(' ',$fts)).'\' IN BOOLEAN MODE)';
    901886        }
    902887        break;
     
    937922    if (!empty($clauses))
    938923    {
    939       $query = $query_base.'('.implode(' OR ', $clauses).')';
     924      $query = $query_base.'('.implode("\n OR ", $clauses).')';
    940925      $qsr->images_iids[$i] = query2array($query,null,'id');
    941926    }
     
    12311216  $scopes = trigger_event('qsearch_get_scopes', $scopes);
    12321217  $expression = new QExpression($q, $scopes);
     1218
     1219  // get inflections for terms
     1220  $inflector = null;
     1221  $lang_code = substr(get_default_language(),0,2);
     1222  @include_once(PHPWG_ROOT_PATH.'include/inflectors/'.$lang_code.'.php');
     1223  $class_name = 'Inflector_'.$lang_code;
     1224  if (class_exists($class_name))
     1225  {
     1226    $inflector = new $class_name;
     1227    foreach( $expression->stokens as $token)
     1228    {
     1229      if (isset($token->scope) && !$token->scope->is_text)
     1230        continue;
     1231      if (strlen($token->term)>2
     1232        && ($token->modifier & (QST_QUOTED|QST_WILDCARD))==0
     1233        && strcspn($token->term, '\'0123456789') == strlen($token->term) )
     1234      {
     1235        $token->variants = array_unique( array_diff( $inflector->get_variants($token->term), array($token->term) ) );
     1236      }
     1237    }
     1238  }
     1239
     1240
    12331241  trigger_action('qsearch_expression_parsed', $expression);
    12341242//var_export($expression);
     
    12521260  {
    12531261    $debug[] = $expression->stokens[$i].': '.count($qsr->tag_ids[$i]).' tags, '.count($qsr->tag_iids[$i]).' tiids, '.count($qsr->images_iids[$i]).' iiids, '.count($qsr->iids[$i]).' iids'
    1254       .( !empty($qsr->variants[$expression->stokens[$i]->term]) ? ' variants: '.implode(', ',$qsr->variants[$expression->stokens[$i]->term]): '');
     1262      .( !empty($expression->stokens[$i]->variants) ? ' variants: '.implode(', ',$expression->stokens[$i]->variants): '');
    12551263  }
    12561264  $debug[] = 'before perms '.count($ids);
Note: See TracChangeset for help on using the changeset viewer.