includes/search.php
changeset 756 e8cf18383425
parent 685 17ebe24cdf85
child 757 7ba7b85e1195
equal deleted inserted replaced
755:9b4cd3ef42f3 756:e8cf18383425
   103 {
   103 {
   104   global $db, $session, $paths, $template, $plugins; // Common objects
   104   global $db, $session, $paths, $template, $plugins; // Common objects
   105   global $lang;
   105   global $lang;
   106   
   106   
   107   $warnings = array();
   107   $warnings = array();
       
   108   
       
   109   //
       
   110   // STAGE 0: PARSE SEARCH QUERY
       
   111   // Identify all terms of the query. Separate between what is required and what is not, and what should be sent through the index as
       
   112   // opposed to straight-out LIKE-selected.
       
   113   //
   108 
   114 
   109   $query = parse_search_query($query, $warnings);
   115   $query = parse_search_query($query, $warnings);
   110 
   116 
   111   // Segregate search terms containing spaces
   117   // Segregate search terms containing spaces
   112   $query_phrase = array(
   118   $query_phrase = array(
   536 
   542 
   537   // At this point, all of our normal results are in. However, we can also allow plugins to hook into the system and score their own
   543   // At this point, all of our normal results are in. However, we can also allow plugins to hook into the system and score their own
   538   // pages and add text, etc. as necessary.
   544   // pages and add text, etc. as necessary.
   539   // Plugins are COMPLETELY responsible for using the search terms and handling Boolean logic properly
   545   // Plugins are COMPLETELY responsible for using the search terms and handling Boolean logic properly
   540 
   546 
       
   547   inject_custom_search_results($query, $query_phrase, $scores, $page_data, $case_sensitive, $word_list);
       
   548   
   541   $code = $plugins->setHook('search_global_inner');
   549   $code = $plugins->setHook('search_global_inner');
   542   foreach ( $code as $cmd )
   550   foreach ( $code as $cmd )
   543   {
   551   {
   544     eval($cmd);
   552     eval($cmd);
   545   }
   553   }
   920                      'the');
   928                      'the');
   921   
   929   
   922   return $stopwords;
   930   return $stopwords;
   923 }
   931 }
   924 
   932 
       
   933 /**
       
   934  * Private function to inject custom results into a search.
       
   935  */
       
   936 
       
   937 function inject_custom_search_results(&$query, &$query_phrase, &$scores, &$page_data, &$case_sensitive, &$word_list)
       
   938 {
       
   939   global $db, $session, $paths, $template, $plugins; // Common objects
       
   940   global $lang;
       
   941   
       
   942   global $search_handlers;
       
   943   
       
   944   // global functions
       
   945   $terms = array(
       
   946       'any' => array_merge($query['any'], $query_phrase['any']),
       
   947       'req' => array_merge($query['req'], $query_phrase['req']),
       
   948       'not' => $query['not']
       
   949     );
       
   950   
       
   951   foreach ( $search_handlers as &$options )
       
   952   {
       
   953     $where = array('any' => array(), 'req' => array(), 'not' => array());
       
   954     $where_any =& $where['any'];
       
   955     $where_req =& $where['req'];
       
   956     $where_not =& $where['not'];
       
   957     $title_col = ( $case_sensitive ) ? $options['titlecolumn'] : 'lcase(' . $options['titlecolumn'] . ')';
       
   958     if ( isset($options['datacolumn']) )
       
   959       $desc_col = ( $case_sensitive ) ? $options['datacolumn'] : 'lcase(' . $options['datacolumn'] . ')';
       
   960     else
       
   961       $desc_col = "''";
       
   962     foreach ( $terms['any'] as $term )
       
   963     {
       
   964       $term = escape_string_like($term);
       
   965       if ( !$case_sensitive )
       
   966         $term = strtolower($term);
       
   967       $where_any[] = "( $title_col LIKE '%{$term}%' OR $desc_col LIKE '%{$term}%' )";
       
   968     }
       
   969     foreach ( $terms['req'] as $term )
       
   970     {
       
   971       $term = escape_string_like($term);
       
   972       if ( !$case_sensitive )
       
   973         $term = strtolower($term);
       
   974       $where_req[] = "( $title_col LIKE '%{$term}%' OR $desc_col LIKE '%{$term}%' )";
       
   975     }
       
   976     foreach ( $terms['not'] as $term )
       
   977     {
       
   978       $term = escape_string_like($term);
       
   979       if ( !$case_sensitive )
       
   980         $term = strtolower($term);
       
   981       $where_not[] = "$title_col NOT LIKE '%{$term}%' AND $desc_col NOT LIKE '%{$term}%'";
       
   982     }
       
   983     if ( empty($where_any) )
       
   984       unset($where_any, $where['any']);
       
   985     if ( empty($where_req) )
       
   986       unset($where_req, $where['req']);
       
   987     if ( empty($where_not) )
       
   988       unset($where_not, $where['not']);
       
   989     
       
   990     $where_any = '(' . implode(' OR ', $where_any) . '' . ( isset($where['req']) || isset($where['not']) ? ' OR 1 = 1' : '' ) . ')';
       
   991     
       
   992     if ( isset($where_req) )
       
   993       $where_req = implode(' AND ', $where_req);
       
   994     if ( isset($where_not) )
       
   995     $where_not = implode( 'AND ', $where_not);
       
   996     
       
   997     $where = implode(' AND ', $where);
       
   998     
       
   999     $columns = $options['titlecolumn'];
       
  1000     if ( isset($options['datacolumn']) )
       
  1001       $columns .= ", {$options['datacolumn']}";
       
  1002     if ( isset($options['additionalcolumns']) )
       
  1003       $columns .= ', ' . implode(', ', $options['additionalcolumns']);
       
  1004     
       
  1005     $sql = "SELECT $columns FROM " . table_prefix . "{$options['table']} WHERE ( $where ) $additionalwhere;";
       
  1006   
       
  1007     if ( !($q = $db->sql_unbuffered_query($sql)) )
       
  1008     {
       
  1009       $db->_die('Automatically generated search query');
       
  1010     }
       
  1011     
       
  1012     if ( $row = $db->fetchrow() )
       
  1013     {
       
  1014       do
       
  1015       {
       
  1016         $parser = $template->makeParserText($options['uniqueid']);
       
  1017         $parser->assign_vars($row);
       
  1018         $idstring = $parser->run();
       
  1019         
       
  1020         // Score this result
       
  1021         foreach ( $word_list as $term )
       
  1022         {
       
  1023           if ( $case_sensitive )
       
  1024           {
       
  1025             if ( strstr($row[$options['titlecolumn']], $term) )
       
  1026             {
       
  1027               ( isset($scores[$idstring]) ) ? $scores[$idstring] += 1.5 : $scores[$idstring] = 1.5;
       
  1028             }
       
  1029             else if ( isset($options['datacolumn']) && strstr($row[$options['datacolumn']], $term) )
       
  1030             {
       
  1031               ( isset($scores[$idstring]) ) ? $scores[$idstring]++ : $scores[$idstring] = 1;
       
  1032             }
       
  1033           }
       
  1034           else
       
  1035           {
       
  1036             if ( stristr($row[$options['titlecolumn']], $term) )
       
  1037             {
       
  1038               ( isset($scores[$idstring]) ) ? $scores[$idstring] += 1.5 : $scores[$idstring] = 1.5;
       
  1039             }
       
  1040             else if ( isset($options['datacolumn']) && stristr($row[$options['datacolumn']], $term) )
       
  1041             {
       
  1042               ( isset($scores[$idstring]) ) ? $scores[$idstring]++ : $scores[$idstring] = 1;
       
  1043             }
       
  1044           }
       
  1045         }
       
  1046         // Generate text...
       
  1047         $text = '';
       
  1048         if ( isset($options['datacolumn']) && !isset($options['formatcallback']) )
       
  1049         {
       
  1050           $text = highlight_and_clip_search_result(htmlspecialchars($row[$options['datacolumn']]), $word_list);
       
  1051         }
       
  1052         else if ( isset($options['formatcallback']) )
       
  1053         {
       
  1054           if ( is_callable($options['formatcallback']) )
       
  1055           {
       
  1056             $text = @call_user_func($options['formatcallback'], $row, $word_list);
       
  1057           }
       
  1058           else
       
  1059           {
       
  1060             $parser = $template->makeParserText($options['formatcallback']);
       
  1061             $parser->assign_vars($row);
       
  1062             $text = $parser->run();
       
  1063           }
       
  1064         }
       
  1065         
       
  1066         // Inject result
       
  1067         
       
  1068         if ( isset($scores[$idstring]) )
       
  1069         {
       
  1070           $parser = $template->makeParserText($options['linkformat']['page_id']);
       
  1071           $parser->assign_vars($row);
       
  1072           $page_id = $parser->run();
       
  1073           
       
  1074           $parser = $template->makeParserText($options['linkformat']['namespace']);
       
  1075           $parser->assign_vars($row);
       
  1076           $namespace = $parser->run();
       
  1077           
       
  1078           $page_data[$idstring] = array(
       
  1079             'page_name' => highlight_search_result(htmlspecialchars($row[$options['titlecolumn']]), $word_list),
       
  1080             'page_text' => $text,
       
  1081             'score' => $scores[$idstring],
       
  1082             'page_id' => $page_id,
       
  1083             'namespace' => $namespace,
       
  1084           );
       
  1085           
       
  1086           // Any additional flags that need to be added to the result?
       
  1087           // The small usually-bracketed text to the left of the title
       
  1088           if ( isset($options['resultnote']) )
       
  1089           {
       
  1090             $page_data[$idstring]['page_note'] = $options['resultnote'];
       
  1091           }
       
  1092           // Should we include the length?
       
  1093           if ( isset($options['datacolumn']) )
       
  1094           {
       
  1095             $page_data[$idstring]['page_length'] = strlen($row[$options['datacolumn']]);
       
  1096           }
       
  1097           else
       
  1098           {
       
  1099             $page_data[$idstring]['page_length'] = 0;
       
  1100             $page_data[$idstring]['zero_length'] = true;
       
  1101           }
       
  1102           // Anything to append to result links?
       
  1103           if ( isset($options['linkformat']['append']) )
       
  1104           {
       
  1105             $page_data[$idstring]['url_append'] = $options['linkformat']['append'];
       
  1106           }
       
  1107         }
       
  1108       }
       
  1109       while ( $row = $db->fetchrow($q) );
       
  1110       $db->free_result($q);
       
  1111     }
       
  1112   }
       
  1113 }
       
  1114 
   925 ?>
  1115 ?>