diff -r 000000000000 -r 902822492a68 plugins/SpecialSearch.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/SpecialSearch.php Wed Jun 13 16:03:00 2007 -0400 @@ -0,0 +1,511 @@ +attachHook('base_classes_initted', ' + global $paths; + $paths->add_page(Array( + \'name\'=>\'Rebuild search index\', + \'urlname\'=>\'SearchRebuild\', + \'namespace\'=>\'Special\', + \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', + )); + + $paths->add_page(Array( + \'name\'=>\'Search\', + \'urlname\'=>\'Search\', + \'namespace\'=>\'Special\', + \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', + )); + '); + +function page_Special_SearchRebuild() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + if(!$session->get_permissions('mod_misc')) die_friendly('Unauthorized', '
You need to be an administrator to rebuild the search index
'); + $template->header(); + if($paths->rebuild_search_index()) + echo 'Index rebuilt!
'; + else + echo 'Index was not rebuilt due to an error.'; + $template->footer(); +} + +function page_Special_Search() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + if(!$q = $paths->getParam(0)) $q = ( isset($_GET['q']) ) ? $_GET['q'] : false; + if(isset($_GET['words_any'])) + { + $q = ''; + if(!empty($_GET['words_any'])) + { + $q .= $_GET['words_any'] . ' '; + } + if(!empty($_GET['exact_phrase'])) + { + $q .= '"' . $_GET['exact_phrase'] . '" '; + } + if(!empty($_GET['exclude_words'])) + { + $not = explode(' ', $_GET['exclude_words']); + foreach ( $not as $i => $foo ) + { + $not[$i] = '-' . $not[$i]; + } + $q .= implode(' ', $not); + } + if(!empty($_GET['require_words'])) + { + $req = explode(' ', $_GET['require_words']); + foreach ( $req as $i => $foo ) + { + $req[$i] = '+' . $req[$i]; + } + $q .= implode(' ', $req); + } + } + $template->header(); + if(!empty($q)) + { + switch(SEARCH_MODE) + { + + case "FULLTEXT": + if ( isset($_GET['offset']) ) + { + $offset = intval($_GET['offset']); + } + else + { + $offset = 0; + } + $sql = $db->sql_query('SELECT search_id FROM '.table_prefix.'search_cache WHERE query=\''.$db->escape($q).'\';'); + if(!$sql) + { + $db->_die('Error scanning search query cache'); + } + if($db->numrows() > 0) + { + $row = $db->fetchrow(); + $db->free_result(); + search_fetch_fulltext_results(intval($row['search_id']), $offset); + } + else + { + // Perform search + + $search = new MySQL_Fulltext_Search(); + + // Parse the query + $parse = new Searcher(); + $query = $parse->parseQuery($q); + unset($parse); + + // Send query to MySQL + $sql = $search->search($q); + $results = Array(); + if ( $row = $db->fetchrow($sql) ) + { + do { + $results[] = $row; + } while ( $row = $db->fetchrow($sql) ); + } + else + { + // echo '
Page: | '; + $num_pages = ceil($nr / SEARCH_RESULTS_PER_PAGE); + $j = 0; + for ( $i = 1; $i <= $num_pages; $i++ ) + { + if ($j == $start) + $pagination .= '' . $i . ' | '; + else + $pagination .= '' . $i . ' | '; + $j = $j + SEARCH_RESULTS_PER_PAGE; + } + $pagination .= '
---|
';
+ foreach($results['page'] as $page => $text)
+ {
+ echo ''.$paths->pages[$page]['name'].'
';
+ }
+ echo '
'.$paths->pages[$page]['name'].'
'.$text.'
{TEXT}
++ {NAMESPACE} - Relevance score: {SCORE} ({LENGTH} bytes) +
+ +TPLCODE; + $parser = $template->makeParserText($result_template); + + $pt =& $result['page_text']; + $space_chars = Array("\t", "\n", "\r", " "); + + $words = array_merge($query['any'], $query['req']); + $pt = htmlspecialchars($pt); + $words2 = array(); + + for ( $i = 0; $i < sizeof($words); $i++) + { + if(!empty($words[$i])) + $words2[] = preg_quote($words[$i]); + } + + $regex = '/(' . implode('|', $words2) . ')/i'; + $pt = preg_replace($regex, '\\1', $pt); + + $title = preg_replace($regex, '\\1', $paths->pages[$page]['name']); + + $cut_off = false; + + foreach ( $words as $word ) + { + // Boldface searched words + $ptlen = strlen($pt); + for ( $i = 0; $i < $ptlen; $i++ ) + { + $len = strlen($word); + if ( strtolower(substr($pt, $i, $len)) == strtolower($word) ) + { + $chunk1 = substr($pt, 0, $i); + $chunk2 = substr($pt, $i, $len); + $chunk3 = substr($pt, ( $i + $len )); + $pt = $chunk1 . $chunk2 . $chunk3; + $ptlen = strlen($pt); + // Cut off text to 150 chars or so + if ( !$cut_off ) + { + $cut_off = true; + if ( $i - 75 > 0 ) + { + // Navigate backwards until a space character is found + $chunk = substr($pt, 0, ( $i - 75 )); + $final_chunk = $chunk; + for ( $j = strlen($chunk); $j > 0; $j = $j - 1 ) + { + if ( in_array($chunk{$j}, $space_chars) ) + { + $final_chunk = substr($chunk, $j + 1); + break; + } + } + $mid_chunk = substr($pt, ( $i - 75 ), 75); + + $clipped = '...' . $final_chunk . $mid_chunk . $chunk2; + + $chunk = substr($pt, ( $i + strlen($chunk2) + 75 )); + $final_chunk = $chunk; + for ( $j = 0; $j < strlen($chunk); $j++ ) + { + if ( in_array($chunk{$j}, $space_chars) ) + { + $final_chunk = substr($chunk, 0, $j); + break; + } + } + + $end_chunk = substr($pt, ( $i + strlen($chunk2) ), 75 ); + + $clipped .= $end_chunk . $final_chunk . '...'; + + $pt = $clipped; + } + else if ( strlen($pt) > 200 ) + { + $mid_chunk = substr($pt, ( $i - 75 ), 75); + + $clipped = $chunk1 . $chunk2; + + $chunk = substr($pt, ( $i + strlen($chunk2) + 75 )); + $final_chunk = $chunk; + for ( $j = 0; $j < strlen($chunk); $j++ ) + { + if ( in_array($chunk{$j}, $space_chars) ) + { + $final_chunk = substr($chunk, 0, $j); + break; + } + } + + $end_chunk = substr($pt, ( $i + strlen($chunk2) ), 75 ); + + $clipped .= $end_chunk . $final_chunk . '...'; + + $pt = $clipped; + + } + break 2; + } + } + } + $cut_off = false; + } + + $parser->assign_vars(Array( + 'TITLE' => $title, + 'TEXT' => $pt, + 'NAMESPACE' => $matches[1], + 'SCORE' => $score, + 'LENGTH' => $char_length, + 'HREF' => makeUrl($page) + )); + + return $parser->run(); + +} + +function search_fetch_fulltext_results($search_id, $offset = 0) +{ + global $db, $session, $paths, $template, $plugins; // Common objects + $q = $db->sql_query('SELECT query,results,search_time FROM '.table_prefix.'search_cache WHERE search_id='.intval($search_id).';'); + if(!$q) + return $db->get_error('Error selecting cached search results'); + $row = $db->fetchrow(); + $db->free_result(); + $results = unserialize($row['results']); + search_render_fulltext_results($results, $offset, $row['query']); +} + +function search_render_fulltext_results($results, $offset = 0, $query) +{ + $num_results = sizeof($results); + $slice = array_slice($results, $offset, SEARCH_RESULTS_PER_PAGE); + + if ( $num_results < 1 ) + { + echo '