diff -r 96524a56d475 -r 2d4bb97fa75a plugins/SpecialSearch.php --- a/plugins/SpecialSearch.php Wed Nov 21 15:11:51 2007 -0500 +++ b/plugins/SpecialSearch.php Wed Nov 21 15:13:06 2007 -0500 @@ -52,7 +52,12 @@ function page_Special_Search() { global $db, $session, $paths, $template, $plugins; // Common objects - if(!$q = $paths->getParam(0)) $q = ( isset($_GET['q']) ) ? $_GET['q'] : false; + global $aggressive_optimize_html; + $aggressive_optimize_html = false; + + if ( !$q = $paths->getParam(0) ) + $q = ( isset($_GET['q']) ) ? $_GET['q'] : ''; + if(isset($_GET['words_any'])) { $q = ''; @@ -85,184 +90,162 @@ } $q = trim($q); - if ( !empty($q) && !isset($_GET['search']) ) + $template->header(); + + $qin = ( isset($q) ) ? str_replace('"', '\"', htmlspecialchars($q)) : ''; + $search_form = '
+   + ' . ( $session->auth_level > USER_LEVEL_MEMBER ? '' : '' ) . ' +
'; + + if ( !empty($q) ) { - list($pid, $ns) = RenderMan::strToPageID($q); - $pid = sanitize_page_id($pid); - $key = $paths->nslist[$ns] . $pid; - if ( isPage($key) ) - { - redirect(makeUrl($key), 'Results', 'found page', 0); - } - } - - $template->header(); - if(!empty($q)) - { - // See if any pages directly match the title + $search_start = microtime_float(); + + $results = perform_search($q, $warn, ( isset($_GET['match_case']) )); + $warn = array_unique($warn); - if ( strlen($q) >= 4 ) + if ( file_exists( ENANO_ROOT . '/themes/' . $template->theme . '/search-result.tpl' ) ) + { + $parser = $template->makeParser('search-result.tpl'); + } + else { - for ( $i = 0; $i < count ( $paths->pages ) / 2; $i++ ) - { - $pg =& $paths->pages[$i]; - $q_lc = strtolower( str_replace(' ', '_', $q) ); - $q_tl = strtolower( str_replace('_', ' ', $q) ); - $p_lc = strtolower($pg['urlname']); - $p_tl = strtolower($pg['name']); - if ( strstr($p_tl, $q_tl) || strstr($p_lc, $q_lc) && $pg['visible'] == 1 ) - { - echo '
Perhaps you were looking for ' . htmlspecialchars($pg['name']) . '?
'; - break; - } - } + $tpl_code = << + +
+

+

{PAGE_NOTE}{PAGE_TITLE}

+ {PAGE_TEXT} + {PAGE_URL} - + {PAGE_LENGTH} {PAGE_LENGTH_UNIT} - + Relevance: {RELEVANCE_SCORE}% +

+
+ + + +LONGSTRING; + $parser = $template->makeParserText($tpl_code); } - - switch(SEARCH_MODE) + foreach ( $results as $i => $_ ) { + $result =& $results[$i]; + $result['page_text'] = str_replace(array('', ''), array('', ''), $result['page_text']); + if ( !empty($result['page_text']) ) + $result['page_text'] .= '
'; + $result['page_name'] = str_replace(array('', ''), array('', ''), $result['page_name']); + if ( $result['page_length'] >= 1048576 ) + { + $result['page_length'] = round($result['page_length'] / 1048576, 1); + $length_unit = 'MB'; + } + else if ( $result['page_length'] >= 1024 ) + { + $result['page_length'] = round($result['page_length'] / 1024, 1); + $length_unit = 'KB'; + } + else + { + $length_unit = 'bytes'; + } + $url = makeUrlComplete($result['namespace'], $result['page_id']); + $url = preg_replace('/\?.+$/', '', $url); + $parser->assign_vars(array( + 'PAGE_TITLE' => $result['page_name'], + 'PAGE_TEXT' => $result['page_text'], + 'PAGE_LENGTH' => $result['page_length'], + 'RELEVANCE_SCORE' => $result['score'], + 'RESULT_URL' => makeUrlNS($result['namespace'], $result['page_id'], false, true), + 'PAGE_LENGTH_UNIT' => $length_unit, + 'PAGE_URL' => $url, + 'PAGE_NOTE' => ( isset($result['page_note']) ? $result['page_note'] . ' ' : '' ) + )); + $has_content = ( $result['namespace'] == 'Special' ); - 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); + $code = $plugins->setHook('search_global_results'); + foreach ( $code as $cmd ) + { + eval($cmd); + } + + $parser->assign_bool(array( + 'special_page' => $has_content + )); + $result = $parser->run(); + } + unset($result); + + $per_page = 10; + $start = ( isset($_GET['start']) ? intval($_GET['start']) : 0 ); + $start_string = $start + 1; + $per_string = $start_string + $per_page - 1; + $num_results = count($results); + if ( $per_string > $num_results ) + $per_string = $num_results; + + $search_time = microtime_float() - $search_start; + $search_time = round($search_time, 3); + + $q_trim = ( strlen($q) > 30 ) ? substr($q, 0, 27) . '...' : $q; + $q_trim = htmlspecialchars($q_trim); + + $result_string = ( count($results) > 0 ) ? "Results $start_string - $per_string of about $num_results for " . $q_trim . " in {$search_time}s." : 'No results.'; + + echo '
+
+ ' . $result_string . ' +
+ Site search +
+
+ ' . $search_form . ' +
'; - // 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 '
No pages that matched your search criteria could be found.
'; - } - $texts = Array(); - foreach ( $results as $result ) - { - $texts[] = render_fulltext_result($result, $query); - } - - // Store the result in the search cache...if someone makes the same query later we can skip searching and rendering - // This cache is cleared when an affected page is saved. - - $results = serialize($texts); - - $sql = $db->sql_query('INSERT INTO '.table_prefix.'search_cache(search_time,query,results) VALUES('.time().', \''.$db->escape($q).'\', \''.$db->escape($results).'\');'); - if($sql) - { - search_render_fulltext_results(unserialize($results), $offset, $q); - } - else - { - $db->_die('Error inserting search into cache'); - } - - } - break; - - case "BUILTIN": - $titles = $paths->makeTitleSearcher(isset($_GET['match_case'])); - 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_show_results(intval($row['search_id']), $offset); - } - else - { - $titles->search($q, $paths->get_page_titles()); - $search = $paths->makeSearcher(isset($_GET['match_case'])); - $texts = $paths->fetch_page_search_resource(); - $search->searchMySQL($q, $texts); - - $results = Array(); - $results['text'] = $search->results; - $results['page'] = $titles->results; - $results['warn'] = $search->warnings; - - $results = serialize($results); - - $sql = $db->sql_query('INSERT INTO '.table_prefix.'search_cache(search_time,query,results) VALUES('.time().', \''.$db->escape($q).'\', \''.$db->escape($results).'\');'); - if($sql) - { - search_render_results(unserialize($results), $offset, $q); - } - else - { - $db->_die('Error inserting search into cache'); - } - } - break; + if ( count($warn) > 0 ) + { + echo '
'; + echo 'Some problems were encountered during your search.
+ There was a problem with your search query, and as a result there may be a reduced number of search results.'; + echo ''; + echo '
'; } - $code = $plugins->setHook('search_results'); // , Array('query'=>$q)); - foreach ( $code as $cmd ) + + if ( count($results) > 0 ) { - eval($cmd); + $html = paginate_array( + $results, + count($results), + makeUrlNS('Special', 'Search', 'q=' . str_replace('%', '%%', htmlspecialchars(urlencode($q))) . '&start=%s'), + $start, + $per_page + ); + echo $html; } - ?> -
-

- sid_super ): ?> - - - - - - Advanced Search -

-
- Your search for "' . htmlspecialchars($q) . '" didn\'t turn up any results.'; + echo '

There are a few things you can try:

'; + echo ''; + } } else { - ?> -
+ ?>
- + auth_level > USER_LEVEL_MEMBER ? '' : '' ); + endif; ?>
@@ -298,255 +281,10 @@
Advanced Search
- footer(); } -function search_show_results($search_id, $start = 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_results($results, $start, $row['query']); -} - -function search_render_results($results, $start = 0, $q = '') -{ - global $db, $session, $paths, $template, $plugins; // Common objects - $nr1 = sizeof($results['page']); - $nr2 = sizeof($results['text']); - $nr = ( $nr1 > $nr2 ) ? $nr1 : $nr2; - $results['page'] = array_slice($results['page'], $start, SEARCH_RESULTS_PER_PAGE); - $results['text'] = array_slice($results['text'], $start, SEARCH_RESULTS_PER_PAGE); - - // Pagination - $pagination = ''; - if ( $nr1 > SEARCH_RESULTS_PER_PAGE || $nr2 > SEARCH_RESULTS_PER_PAGE ) - { - $pagination .= '
- - - '; - $num_pages = ceil($nr / SEARCH_RESULTS_PER_PAGE); - $j = 0; - for ( $i = 1; $i <= $num_pages; $i++ ) - { - if ($j == $start) - $pagination .= ''; - else - $pagination .= ''; - $j = $j + SEARCH_RESULTS_PER_PAGE; - } - $pagination .= '
Page:' . $i . '' . $i . '
'; - } - - echo $pagination; - - if ( $nr1 >= $start ) - { - echo '

Page title matches

'; - if(count($results['page']) < 1) - { - echo '
No pages with a title that matched your search criteria could be found.
'; - } - else - { - echo '

'; - foreach($results['page'] as $page => $text) - { - echo ''.$paths->pages[$page]['name'].'
'; - } - echo '

'; - } - } - if ( $nr2 >= $start ) - { - echo '

Page text matches

'; - if(count($results['text']) < 1) - { - echo '
No page text that matched your search criteria could be found.
'; - } - else - { - foreach($results['text'] as $kpage => $text) - { - preg_match('#^ns=('.implode('|', array_keys($paths->nslist)).');pid=(.*?)$#i', $kpage, $matches); - $page = $paths->nslist[$matches[1]] . $matches[2]; - echo '

'.$paths->pages[$page]['name'].'
'.$text.'

'; - } - } - } - if(count($results['warn']) > 0) - echo '
Your search may not include all results.
The following errors were encountered during the search:
'; - echo $pagination; -} - -function render_fulltext_result($result, $query) -{ - global $db, $session, $paths, $template, $plugins; // Common objects - preg_match('#^ns=('.implode('|', array_keys($paths->nslist)).');pid=(.*?)$#i', $result['page_identifier'], $matches); - $page = $paths->nslist[$matches[1]] . $matches[2]; - //$score = round($result['score'] * 100, 1); - $score = number_format($result['score'], 2); - $char_length = $result['length']; - $result_template = << -

{TITLE}

-

{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', htmlspecialchars($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 '
No page text that matched your search criteria could be found.
'; - return null; - } - - $html = paginate_array($results, sizeof($results), makeUrlNS('Special', 'Search', 'q=' . urlencode($query) . '&offset=%s'), $offset, 10); - echo $html . '
'; - -} - ?>