Changeset 683

Show
Ignore:
Timestamp:
12/28/06 21:50:43 (2 years ago)
Author:
Connor
Message:

Lots of changes to allow for fulltext searching, indexing now disabled and tables removed for mysql(i), and fulltext indexes added, search.php majorly reworked to support fulltext and to not cache quicksearches.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/punbb-1.3-dev/extras/db_update.php

    r671 r683  
    327327                $db->query('ALTER TABLE '.$db->prefix.'online ADD UNIQUE INDEX '.$db->prefix.'online_user_id_ident_idx (user_id,ident)') or error('Unable to alter DB structure.', __FILE__, __LINE__, $db->error()); 
    328328         
     329        // Get rid of the old search tables for mysql/mysqli 
     330        if (($db_type == 'mysql' || $db_type == 'mysqli') && $db->table_exists($db_prefix.'search_cache') && $db->table_exists($db_prefix.'search_matches') && $db->table_exists($db_prefix.'search_words')) 
     331        { 
     332                $db->query('DROP TABLE '.$db->prefix.'search_cache, '.$db->prefix.'search_matches, '.$db->prefix.'search_words;') or error('Unable to drop search tables.', __FILE__, __LINE__, $db->error()); 
     333        } 
     334         
     335        // Add fulltext indexes for mysql/mysqli 
     336        if (($db_type == 'mysql' || $db_type == 'mysqli') && $db->index_exists($db->prefix.'posts', $db->prefix.'posts_message_idx')) 
     337                $db->query('ALTER TABLE '.$db_prefix.'posts ADD FULLTEXT '.$db_prefix.'posts_message_idx(message)') or error('Unable to alter DB structure.', __FILE__, __LINE__, $db->error()); 
     338        if (($db_type == 'mysql' || $db_type == 'mysqli') && $db->index_exists($db->prefix.'topics', $db->prefix.'topics_subject_idx')) 
     339                $db->query('ALTER TABLE '.$db_prefix.'topics ADD FULLTEXT '.$db_prefix.'topics_subject_idx(subject)') or error('Unable to alter DB structure.', __FILE__, __LINE__, $db->error()); 
     340         
    329341        // Finally, we update the version number 
    330342        $db->query('UPDATE '.$db->prefix.'config SET conf_value=\''.$update_to.'\' WHERE conf_name=\'o_cur_version\'') or error('Unable to update version.', __FILE__, __LINE__, $db->error()); 
  • branches/punbb-1.3-dev/upload/admin/maintenance.php

    r641 r683  
    3434if ($pun_user['g_id'] > PUN_ADMIN) 
    3535        message($lang_common['No permission']); 
     36         
     37if ($db_type == 'mysql' || $db_type == 'mysqli') 
     38        message($lang_common['Bad request']); 
    3639 
    3740// Load the admin.php language file 
     
    5457                confirm_referrer('admin/maintenance.php'); 
    5558 
    56                 $truncate_sql = ($db_type != 'sqlite' && $db_type != 'pgsql') ? 'TRUNCATE TABLE ' : 'DELETE FROM '; 
    57                  
    58                 $db->query($truncate_sql.$db->prefix.'search_matches') or error('Unable to empty search index match table', __FILE__, __LINE__, $db->error()); 
    59                 $db->query($truncate_sql.$db->prefix.'search_words') or error('Unable to empty search index words table', __FILE__, __LINE__, $db->error()); 
     59                $db->query('DELETE FROM '.$db->prefix.'search_matches') or error('Unable to empty search index match table', __FILE__, __LINE__, $db->error()); 
     60                $db->query('DELETE FROM '.$db->prefix.'search_words') or error('Unable to empty search index words table', __FILE__, __LINE__, $db->error()); 
    6061 
    6162                // Reset the sequence for the search words (not needed for SQLite) 
    62                 switch ($db_type) 
    63                 { 
    64                         case 'mysql': 
    65                         case 'mysqli': 
    66                                 $result = $db->query('ALTER TABLE '.$db->prefix.'search_words auto_increment=1') or error('Unable to update table auto_increment', __FILE__, __LINE__, $db->error()); 
    67                                 break; 
    68  
    69                         case 'pgsql'; 
    70                                 $result = $db->query('SELECT setval(\''.$db->prefix.'search_words_id_seq\', 1, false)') or error('Unable to update sequence', __FILE__, __LINE__, $db->error()); 
    71                 } 
     63                if ($db_type == 'pgsql') 
     64                        $result = $db->query('SELECT setval(\''.$db->prefix.'search_words_id_seq\', 1, false)') or error('Unable to update sequence', __FILE__, __LINE__, $db->error()); 
    7265        } 
    7366 
  • branches/punbb-1.3-dev/upload/delete.php

    r646 r683  
    7070                confirm_referrer('delete.php'); 
    7171 
    72         require PUN_ROOT.'include/search_idx.php'; 
     72        if ($db_type != 'mysql' && $db_type != 'mysqli') 
     73                require PUN_ROOT.'include/search_idx.php'; 
    7374 
    7475        if ($is_topic_post) 
  • branches/punbb-1.3-dev/upload/edit.php

    r648 r683  
    111111                $edited_sql = (!isset($_POST['silent']) || !$is_admmod) ? $edited_sql = ', edited='.time().', edited_by=\''.$db->escape($pun_user['username']).'\'' : ''; 
    112112 
    113                 require PUN_ROOT.'include/search_idx.php'; 
     113                if ($db_type != 'mysql' && $db_type != 'mysqli') 
     114                        require PUN_ROOT.'include/search_idx.php'; 
    114115 
    115116                if ($can_edit_subject) 
     
    119120 
    120121                        // We changed the subject, so we need to take that into account when we update the search words 
    121                         update_search_index('edit', $id, $message, $subject); 
     122                        if ($db_type != 'mysql' && $db_type != 'mysqli') 
     123                                update_search_index('edit', $id, $message, $subject); 
    122124                } 
    123                 else 
     125                else if ($db_type != 'mysql' && $db_type != 'mysqli') 
    124126                        update_search_index('edit', $id, $message); 
    125127 
  • branches/punbb-1.3-dev/upload/include/common.php

    r678 r683  
    2828// This displays all executed queries in the page footer. 
    2929// DO NOT enable this in a production environment! 
    30 //define('PUN_SHOW_QUERIES', 1); 
     30define('PUN_SHOW_QUERIES', 1); 
    3131 
    3232if (!defined('PUN_ROOT')) 
  • branches/punbb-1.3-dev/upload/include/common_admin.php

    r624 r683  
    3333function generate_admin_menu() 
    3434{ 
    35         global $pun_config, $pun_url, $pun_user, $lang_admin
     35        global $pun_config, $pun_url, $pun_user, $lang_admin, $db_type
    3636 
    3737        $is_admin = $pun_user['g_id'] == PUN_ADMIN ? true : false; 
     
    7878                $adnav_links[] = '<li'.((PUN_PAGE == 'admin-bans') ? ' class="isactive">' : '>').'<a href="'.pun_link($pun_url['admin_bans']).'">'.$lang_admin['Bans'].'</a></li>'; 
    7979                $adnav_links[] = '<li'.((PUN_PAGE == 'admin-prune') ? ' class="isactive">' : '>').'<a href="'.pun_link($pun_url['admin_prune']).'">'.$lang_admin['Prune'].'</a></li>'; 
    80                 $adnav_links[] = '<li'.((PUN_PAGE == 'admin-maintenance') ? ' class="isactive">' : '>').'<a href="'.pun_link($pun_url['admin_maintenance']).'">'.$lang_admin['Maintenance'].'</a></li>'; 
     80                if ($db_type != 'mysql' && $db_type != 'mysqli') 
     81                        $adnav_links[] = '<li'.((PUN_PAGE == 'admin-maintenance') ? ' class="isactive">' : '>').'<a href="'.pun_link($pun_url['admin_maintenance']).'">'.$lang_admin['Maintenance'].'</a></li>'; 
    8182                $adnav_links[] = '<li'.((PUN_PAGE == 'admin-reports') ? ' class="isactive">' : '>').'<a href="'.pun_link($pun_url['admin_reports']).'">'.$lang_admin['Reports'].'</a></li>'; 
    8283                $adnav_links[] = '<li'.((PUN_PAGE == 'admin-extensions') ? ' class="isactive">' : '>').'<a href="'.pun_link($pun_url['admin_extensions']).'">'.$lang_admin['Extensions'].'</a></li>'; 
     
    160161 
    161162                        // We removed a bunch of posts, so now we have to update the search index 
    162                         require_once PUN_ROOT.'include/search_idx.php'; 
    163                         strip_search_index($post_ids); 
     163                        if ($db_type != 'mysql' && $db_type != 'mysqli') 
     164                        { 
     165                                require_once PUN_ROOT.'include/search_idx.php'; 
     166                                strip_search_index($post_ids); 
     167                        } 
    164168                } 
    165169        } 
  • branches/punbb-1.3-dev/upload/include/functions.php

    r678 r683  
    455455function delete_topic($topic_id) 
    456456{ 
    457         global $db
     457        global $db, $db_type
    458458 
    459459        // Delete the topic and any redirect topics 
     
    469469        if ($post_ids != '') 
    470470        { 
    471                 strip_search_index($post_ids); 
     471                if ($db_type != 'mysql' && $db_type != 'mysqli') 
     472                        strip_search_index($post_ids); 
    472473 
    473474                // Delete posts in topic 
     
    485486function delete_post($post_id, $topic_id) 
    486487{ 
    487         global $db
     488        global $db, $db_type
    488489 
    489490        $result = $db->query('SELECT id, poster, posted FROM '.$db->prefix.'posts WHERE topic_id='.$topic_id.' ORDER BY id DESC LIMIT 2') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); 
     
    494495        $db->query('DELETE FROM '.$db->prefix.'posts WHERE id='.$post_id) or error('Unable to delete post', __FILE__, __LINE__, $db->error()); 
    495496 
    496         strip_search_index($post_id); 
     497        if ($db_type != 'mysql' && $db_type != 'mysqli') 
     498                strip_search_index($post_id); 
    497499 
    498500        // Count number of replies in the topic 
  • branches/punbb-1.3-dev/upload/install.php

    r682 r683  
    969969        switch ($db_type) 
    970970        { 
    971                 case 'mysql': 
    972                 case 'mysqli': 
    973                         $sql = 'CREATE TABLE '.$db_prefix."search_cache ( 
    974                                         id INT(10) UNSIGNED NOT NULL DEFAULT 0, 
    975                                         ident VARCHAR(200) NOT NULL DEFAULT '', 
    976                                         search_data TEXT, 
    977                                         PRIMARY KEY (id) 
    978                                         ) TYPE=MyISAM;"; 
    979                         break; 
    980  
    981971                case 'pgsql': 
    982972                        $sql = 'CREATE TABLE '.$db_prefix."search_cache ( 
     
    998988        } 
    999989 
    1000         $db->query($sql) or error('Unable to create table '.$db_prefix.'search_cache. Please check your settings and try again.',  __FILE__, __LINE__, $db->error()); 
    1001  
    1002  
    1003  
    1004         switch ($db_type) 
    1005         { 
    1006                 case 'mysql': 
    1007                 case 'mysqli': 
    1008                         $sql = 'CREATE TABLE '.$db_prefix."search_matches ( 
    1009                                         post_id INT(10) UNSIGNED NOT NULL DEFAULT 0, 
    1010                                         word_id MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT 0, 
    1011                                         subject_match TINYINT(1) NOT NULL DEFAULT 0 
    1012                                         ) TYPE=MyISAM;"; 
    1013                         break; 
    1014  
     990        if ($db_type != 'mysql' && $db_type != 'mysqli') 
     991                $db->query($sql) or error('Unable to create table '.$db_prefix.'search_cache. Please check your settings and try again.',  __FILE__, __LINE__, $db->error()); 
     992 
     993 
     994 
     995        switch ($db_type) 
     996        { 
    1015997                case 'pgsql': 
    1016998                        $sql = 'CREATE TABLE '.$db_prefix."search_matches ( 
     
    10301012        } 
    10311013 
    1032         $db->query($sql) or error('Unable to create table '.$db_prefix.'search_matches. Please check your settings and try again.',  __FILE__, __LINE__, $db->error()); 
    1033  
    1034  
    1035  
    1036         switch ($db_type) 
    1037         { 
    1038                 case 'mysql': 
    1039                 case 'mysqli': 
    1040                         $sql = 'CREATE TABLE '.$db_prefix."search_words ( 
    1041                                         id MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT, 
    1042                                         word VARCHAR(20) BINARY NOT NULL DEFAULT '', 
    1043                                         PRIMARY KEY (word), 
    1044                                         KEY ".$db_prefix."search_words_id_idx (id) 
    1045                                         ) TYPE=MyISAM;"; 
    1046                         break; 
    1047  
     1014        if ($db_type != 'mysql' && $db_type != 'mysqli') 
     1015                $db->query($sql) or error('Unable to create table '.$db_prefix.'search_matches. Please check your settings and try again.',  __FILE__, __LINE__, $db->error()); 
     1016 
     1017 
     1018 
     1019        switch ($db_type) 
     1020        { 
    10481021                case 'pgsql': 
    10491022                        $sql = 'CREATE TABLE '.$db_prefix."search_words ( 
     
    10641037        } 
    10651038 
    1066         $db->query($sql) or error('Unable to create table '.$db_prefix.'search_words. Please check your settings and try again.',  __FILE__, __LINE__, $db->error()); 
     1039        if ($db_type != 'mysql' && $db_type != 'mysqli') 
     1040                $db->query($sql) or error('Unable to create table '.$db_prefix.'search_words. Please check your settings and try again.',  __FILE__, __LINE__, $db->error()); 
    10671041 
    10681042 
     
    13111285                        $queries[] = 'ALTER TABLE '.$db_prefix.'posts ADD INDEX '.$db_prefix.'posts_topic_id_idx(topic_id)'; 
    13121286                        $queries[] = 'ALTER TABLE '.$db_prefix.'posts ADD INDEX '.$db_prefix.'posts_multi_idx(poster_id, topic_id)'; 
     1287                        $queries[] = 'ALTER TABLE '.$db_prefix.'posts ADD FULLTEXT '.$db_prefix.'posts_message_idx(message)'; 
    13131288                        $queries[] = 'ALTER TABLE '.$db_prefix.'reports ADD INDEX '.$db_prefix.'reports_zapped_idx(zapped)'; 
    1314                         $queries[] = 'ALTER TABLE '.$db_prefix.'search_matches ADD INDEX '.$db_prefix.'search_matches_word_id_idx(word_id)'; 
    1315                         $queries[] = 'ALTER TABLE '.$db_prefix.'search_matches ADD INDEX '.$db_prefix.'search_matches_post_id_idx(post_id)'; 
    13161289                        $queries[] = 'ALTER TABLE '.$db_prefix.'topics ADD INDEX '.$db_prefix.'topics_forum_id_idx(forum_id)'; 
    13171290                        $queries[] = 'ALTER TABLE '.$db_prefix.'topics ADD INDEX '.$db_prefix.'topics_moved_to_idx(moved_to)'; 
     1291                        $queries[] = 'ALTER TABLE '.$db_prefix.'topics ADD FULLTEXT '.$db_prefix.'topics_subject_idx(subject)'; 
    13181292                        $queries[] = 'ALTER TABLE '.$db_prefix.'users ADD INDEX '.$db_prefix.'users_registered_idx(registered)'; 
    1319                         $queries[] = 'ALTER TABLE '.$db_prefix.'search_cache ADD INDEX '.$db_prefix.'search_cache_ident_idx(ident(8))'; 
    13201293                        $queries[] = 'ALTER TABLE '.$db_prefix.'users ADD INDEX '.$db_prefix.'users_username_idx(username(8))'; 
    13211294                        break; 
     
    14551428 
    14561429        // Add new post to search table 
    1457         require PUN_ROOT.'include/search_idx.php'; 
    1458         update_search_index('post', $db->insert_id(), $message, $subject); 
    1459  
     1430        if ($db_type != 'mysql' && $db_type != 'mysqli') 
     1431        { 
     1432                require PUN_ROOT.'include/search_idx.php'; 
     1433                update_search_index('post', $db->insert_id(), $message, $subject); 
     1434        } 
     1435         
    14601436        $db->query('INSERT INTO '.$db_prefix."ranks (rank, min_posts) VALUES('New member', 0)") 
    14611437                or error('Unable to insert into table '.$db_prefix.'ranks. Please check your configuration and try again.'); 
  • branches/punbb-1.3-dev/upload/moderate.php

    r675 r683  
    104104                        $db->query('DELETE FROM '.$db->prefix.'posts WHERE id IN('.$posts.')') or error('Unable to delete posts', __FILE__, __LINE__, $db->error()); 
    105105 
    106                         require PUN_ROOT.'include/search_idx.php'; 
    107                         strip_search_index($posts); 
     106                        if ($db_type != 'mysql' && $db_type != 'mysqli') 
     107                        { 
     108                                require PUN_ROOT.'include/search_idx.php'; 
     109                                strip_search_index($posts); 
     110                        } 
    108111 
    109112                        // Get last_post, last_post_id, and last_poster for the topic after deletion 
     
    453456                        message($lang_common['Bad request']); 
    454457 
    455                 require PUN_ROOT.'include/search_idx.php'; 
     458                if ($db_type != 'mysql' && $db_type != 'mysqli') 
     459                        require PUN_ROOT.'include/search_idx.php'; 
    456460 
    457461                // Delete the topics and any redirect topics 
     
    469473 
    470474                // We have to check that we actually have a list of post ID's since we could be deleting just a redirect topic 
    471                 if ($post_ids != ''
     475                if ($post_ids != '' && $db_type != 'mysql' && $db_type != 'mysqli'
    472476                        strip_search_index($post_ids); 
    473477 
  • branches/punbb-1.3-dev/upload/post.php

    r648 r683  
    161161        } 
    162162 
    163  
    164         require PUN_ROOT.'include/search_idx.php'; 
     163        if ($db_type != 'mysql' && $db_type != 'mysqli') 
     164               require PUN_ROOT.'include/search_idx.php'; 
    165165 
    166166        $hide_smilies = isset($_POST['hide_smilies']) ? 1 : 0; 
     
    204204                        $db->query('UPDATE '.$db->prefix.'topics SET num_replies='.$num_replies.', last_post='.$now.', last_post_id='.$new_pid.', last_poster=\''.$db->escape($username).'\' WHERE id='.$tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); 
    205205 
    206                         update_search_index('post', $new_pid, $message); 
     206                        if ($db_type != 'mysql' && $db_type != 'mysqli') 
     207                                update_search_index('post', $new_pid, $message); 
    207208 
    208209                        update_forum($cur_posting['id']); 
     
    313314                        $db->query('UPDATE '.$db->prefix.'topics SET last_post_id='.$new_pid.' WHERE id='.$new_tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error()); 
    314315 
    315                         update_search_index('post', $new_pid, $message, $subject); 
     316                        if ($db_type != 'mysql' && $db_type != 'mysqli') 
     317                                update_search_index('post', $new_pid, $message, $subject); 
    316318 
    317319                        update_forum($fid); 
  • branches/punbb-1.3-dev/upload/profile.php

    r648 r683  
    582582                if (isset($_POST['delete_posts'])) 
    583583                { 
    584                         require PUN_ROOT.'include/search_idx.php'; 
     584                        if ($db_type != 'mysql' && $db_type != 'mysqli') 
     585                                require PUN_ROOT.'include/search_idx.php'; 
    585586                        @set_time_limit(0); 
    586587 
  • branches/punbb-1.3-dev/upload/search.php

    r681 r683  
    4848if (isset($_GET['action']) || isset($_GET['search_id'])) 
    4949{ 
     50        // 
     51        // Grab and validate all the submitted data. 
     52        // 
     53         
    5054        $action = (isset($_GET['action'])) ? $_GET['action'] : null; 
    5155        $forum = (isset($_GET['forum'])) ? intval($_GET['forum']) : -1; 
     
    5761        { 
    5862                $search_id = intval($_GET['search_id']); 
     63                if ($db_type == 'mysql' || $db_type == 'mysqli') 
     64                        message($lang_common['Bad request']); 
    5965                if ($search_id < 1) 
    6066                        message($lang_common['Bad request']); 
     
    95101        } 
    96102 
    97  
    98         // If a valid search_id was supplied we attempt to fetch the search results from the db 
    99         if (isset($search_id)) 
    100         { 
    101                 $ident = ($pun_user['is_guest']) ? get_remote_address() : $pun_user['username']; 
    102  
    103                 $result = $db->query('SELECT search_data FROM '.$db->prefix.'search_cache WHERE id='.$search_id.' AND ident=\''.$db->escape($ident).'\'') or error('Unable to fetch search results', __FILE__, __LINE__, $db->error()); 
    104                 if ($row = $db->fetch_assoc($result)) 
    105                 { 
    106                         $temp = unserialize($row['search_data']); 
    107  
    108                         $search_results = $temp['search_results']; 
    109                         $sort_by = $temp['sort_by']; 
    110                         $sort_dir = $temp['sort_dir']; 
    111                         $show_as = $temp['show_as']; 
    112  
    113                         unset($temp); 
    114                 } 
    115                 else 
    116                         message($lang_search['No hits']); 
    117         } 
    118         else 
    119         { 
     103        // 
     104        // First of all lets find out if we need to cache the results, we only need to do this for detailed queries, not quicksearches or for mysql(i). 
     105        // 
     106         
     107        if ($db_type != 'mysql' && $db_type != 'mysqli' && (isset($keywords) || isset($author))) 
     108        { 
     109                // We need to grab results, insert them into the cache and reload with a search id before showing them 
     110                                 
    120111                $keyword_results = $author_results = array(); 
    121112 
     
    123114                $forum_sql = ($forum != -1) ? ' AND t.forum_id = '.$forum : ''; 
    124115 
    125                 if (!empty($author) || !empty($keywords)) 
    126                 { 
    127                         // If it's a search for keywords 
    128                         if ($keywords) 
    129                         { 
    130                                 $stopwords = (array)@file(PUN_ROOT.'lang/'.$pun_user['language'].'/stopwords.txt'); 
    131                                 $stopwords = array_map('trim', $stopwords); 
    132  
    133                                 // Are we searching for multibyte charset text? 
    134                                 if ($multibyte) 
     116                // If it's a search for keywords 
     117                if ($keywords) 
     118                { 
     119                        $stopwords = (array)@file(PUN_ROOT.'lang/'.$pun_user['language'].'/stopwords.txt'); 
     120                        $stopwords = array_map('trim', $stopwords); 
     121 
     122                        // Are we searching for multibyte charset text? 
     123                        if ($multibyte) 
     124                        { 
     125                                // Strip out excessive whitespace 
     126                                $keywords = trim(preg_replace('#\s+#', ' ', $keywords)); 
     127 
     128                                $keywords_array = explode(' ', $keywords); 
     129                        } 
     130                        else 
     131                        { 
     132                                // Filter out non-alphabetical chars 
     133                                $noise_match = array('^', '$', '&', '(', ')', '<', '>', '`', '\'', '"', '|', ',', '@', '_', '?', '%', '~', '[', ']', '{', '}', ':', '\\', '/', '=', '#', '\'', ';', '!', '€'); 
     134                                $noise_replace = array(' ', ' ', ' ', ' ', ' ', ' ', ' ', '',  '',   ' ', ' ', ' ', ' ', '',  ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '' ,  ' ', ' ', ' ', ' ',  ' ', ' ', ' '); 
     135                                $keywords = str_replace($noise_match, $noise_replace, $keywords); 
     136 
     137                                // Strip out excessive whitespace 
     138                                $keywords = trim(preg_replace('#\s+#', ' ', $keywords)); 
     139 
     140                                // Fill an array with all the words 
     141                                $keywords_array = explode(' ', $keywords); 
     142 
     143                                if (empty($keywords_array)) 
     144                                        message($lang_search['No hits']); 
     145 
     146                                while (list($i, $word) = @each($keywords_array)) 
    135147                                { 
    136                                         // Strip out excessive whitespace 
    137                                         $keywords = trim(preg_replace('#\s+#', ' ', $keywords)); 
    138  
    139                                         $keywords_array = explode(' ', $keywords); 
     148                                        $num_chars = pun_strlen($word); 
     149 
     150                                        if ($num_chars < 3 || $num_chars > 20 || in_array($word, $stopwords)) 
     151                                               unset($keywords_array[$i]); 
    140152                                } 
    141                                 else 
     153 
     154                                // Should we search in message body or topic subject specifically? 
     155                                $search_in_cond = ($search_in) ? (($search_in > 0) ? ' AND m.subject_match = 0' : ' AND m.subject_match = 1') : ''; 
     156                        } 
     157 
     158                        $word_count = 0; 
     159                        $match_type = 'and'; 
     160                        $result_list = array(); 
     161                        @reset($keywords_array); 
     162                        while (list(, $cur_word) = @each($keywords_array)) 
     163                        { 
     164                                switch ($cur_word) 
    142165                                { 
    143                                         // Filter out non-alphabetical chars 
    144                                         $noise_match = array('^', '$', '&', '(', ')', '<', '>', '`', '\'', '"', '|', ',', '@', '_', '?', '%', '~', '[', ']', '{', '}', ':', '\\', '/', '=', '#', '\'', ';', '!', '€'); 
    145                                         $noise_replace = array(' ', ' ', ' ', ' ', ' ', ' ', ' ', '',  '',   ' ', ' ', ' ', ' ', '',  ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '' ,  ' ', ' ', ' ', ' ',  ' ', ' ', ' '); 
    146                                         $keywords = str_replace($noise_match, $noise_replace, $keywords); 
    147  
    148                                         // Strip out excessive whitespace 
    149                                         $keywords = trim(preg_replace('#\s+#', ' ', $keywords)); 
    150  
    151                                         // Fill an array with all the words 
    152                                         $keywords_array = explode(' ', $keywords); 
    153  
    154                                         if (empty($keywords_array)) 
    155                                                 message($lang_search['No hits']); 
    156  
    157                                         while (list($i, $word) = @each($keywords_array)) 
     166                                        case 'and': 
     167                                        case 'or': 
     168                                        case 'not': 
     169                                                $match_type = $cur_word; 
     170                                                break; 
     171 
     172                                        default: 
    158173                                        { 
    159                                                 $num_chars = pun_strlen($word); 
    160  
    161                                                 if ($num_chars < 3 || $num_chars > 20 || in_array($word, $stopwords)) 
    162                                                         unset($keywords_array[$i]); 
    163                                         } 
    164  
    165                                         // Should we search in message body or topic subject specifically? 
    166                                         $search_in_cond = ($search_in) ? (($search_in > 0) ? ' AND m.subject_match = 0' : ' AND m.subject_match = 1') : ''; 
    167                                 } 
    168  
    169                                 $word_count = 0; 
    170                                 $match_type = 'and'; 
    171                                 $result_list = array(); 
    172                                 @reset($keywords_array); 
    173                                 while (list(, $cur_word) = @each($keywords_array)) 
    174                                 { 
    175                                         switch ($cur_word) 
    176                                         { 
    177                                                 case 'and': 
    178                                                 case 'or': 
    179                                                 case 'not': 
    180                                                         $match_type = $cur_word; 
    181                                                         break; 
    182  
    183                                                 default: 
     174                                                // Are we searching for multibyte charset text? 
     175                                                if ($multibyte) 
    184176                                                { 
    185                                                         // Are we searching for multibyte charset text? 
    186                                                         if ($multibyte) 
     177                                                        $cur_word = $db->escape('%'.str_replace('*', '', $cur_word).'%'); 
     178                                                        $cur_word_like = ($db_type == 'pgsql') ? 'ILIKE \''.$cur_word.'\'' : 'LIKE \''.$cur_word.'\''; 
     179 
     180                                                        if ($search_in > 0) 
     181                                                                $sql = 'SELECT id FROM '.$db->prefix.'posts WHERE message '.$cur_word_like; 
     182                                                        else if ($search_in < 0) 
     183                                                                $sql = 'SELECT p.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE t.subject '.$cur_word_like.' GROUP BY p.id, t.id'; 
     184                                                        else 
     185                                                                $sql = 'SELECT p.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE p.message '.$cur_word_like.' OR t.subject '.$cur_word_like.' GROUP BY p.id, t.id'; 
     186                                                } 
     187                                                else 
     188                                                { 
     189                                                        $cur_word = str_replace('*', '%', $cur_word); 
     190                                                        $sql = 'SELECT m.post_id FROM '.$db->prefix.'search_words AS w INNER JOIN '.$db->prefix.'search_matches AS m ON m.word_id = w.id WHERE w.word LIKE \''.$cur_word.'\''.$search_in_cond; 
     191                                                } 
     192 
     193                                                $result = $db->query($sql, true) or error('Unable to search for posts', __FILE__, __LINE__, $db->error()); 
     194 
     195                                                $row = array(); 
     196                                                while ($temp = $db->fetch_row($result)) 
     197                                                { 
     198                                                        $row[$temp[0]] = 1; 
     199 
     200                                                        if (!$word_count) 
     201                                                                $result_list[$temp[0]] = 1; 
     202                                                        else if ($match_type == 'or') 
     203                                                                $result_list[$temp[0]] = 1; 
     204                                                        else if ($match_type == 'not') 
     205                                                                $result_list[$temp[0]] = 0; 
     206                                                } 
     207 
     208                                                if ($match_type == 'and' && $word_count) 
     209                                                { 
     210                                                        @reset($result_list); 
     211                                                        while (list($post_id,) = @each($result_list)) 
    187212                                                        { 
    188                                                                 $cur_word = $db->escape('%'.str_replace('*', '', $cur_word).'%'); 
    189                                                                 $cur_word_like = ($db_type == 'pgsql') ? 'ILIKE \''.$cur_word.'\'' : 'LIKE \''.$cur_word.'\''; 
    190  
    191                                                                 if ($search_in > 0) 
    192                                                                         $sql = 'SELECT id FROM '.$db->prefix.'posts WHERE message '.$cur_word_like; 
    193                                                                 else if ($search_in < 0) 
    194                                                                         $sql = 'SELECT p.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE t.subject '.$cur_word_like.' GROUP BY p.id, t.id'; 
    195                                                                 else 
    196                                                                         $sql = 'SELECT p.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE p.message '.$cur_word_like.' OR t.subject '.$cur_word_like.' GROUP BY p.id, t.id'; 
     213                                                                if (!isset($row[$post_id])) 
     214                                                                        $result_list[$post_id] = 0; 
    197215                                                        } 
    198                                                         else 
    199                                                         { 
    200                                                                 $cur_word = str_replace('*', '%', $cur_word); 
    201                                                                 $sql = 'SELECT m.post_id FROM '.$db->prefix.'search_words AS w INNER JOIN '.$db->prefix.'search_matches AS m ON m.word_id = w.id WHERE w.word LIKE \''.$cur_word.'\''.$search_in_cond; 
    202                                                         } 
    203  
    204                                                         $result = $db->query($sql, true) or error('Unable to search for posts', __FILE__, __LINE__, $db->error()); 
    205  
    206                                                         $row = array(); 
    207                                                         while ($temp = $db->fetch_row($result)) 
    208                                                         { 
    209                                                                 $row[$temp[0]] = 1; 
    210  
    211                                                                 if (!$word_count) 
    212                                                                         $result_list[$temp[0]] = 1; 
    213                                                                 else if ($match_type == 'or') 
    214                                                                         $result_list[$temp[0]] = 1; 
    215                                                                 else if ($match_type == 'not') 
    216                                                                         $result_list[$temp[0]] = 0; 
    217                                                         } 
    218  
    219                                                         if ($match_type == 'and' && $word_count) 
    220                                                         { 
    221                                                                 @reset($result_list); 
    222                                                                 while (list($post_id,) = @each($result_list)) 
    223                                                                 { 
    224                                                                         if (!isset($row[$post_id])) 
    225                                                                                 $result_list[$post_id] = 0; 
    226                                                                 } 
    227                                                         } 
    228  
    229                                                         ++$word_count; 
    230                                                         $db->free_result($result); 
    231  
    232                                                         break; 
    233216                                                } 
     217 
     218                                                ++$word_count; 
     219                                                $db->free_result($result); 
     220 
     221                                                break; 
    234222                                        } 
    235223                                } 
    236  
    237                                 @reset($result_list); 
    238                                 while (list($post_id, $matches) = @each($result_list)) 
    239                                 { 
    240                                         if ($matches) 
    241                                                 $keyword_results[] = $post_id; 
    242                                 } 
    243  
    244                                 unset($result_list); 
    245                         } 
    246  
    247                         // If it's a search for author name (and that author name isn't Guest) 
    248                         if ($author && strcasecmp($author, 'Guest') && strcasecmp($author, $lang_common['Guest'])) 
    249                         { 
    250                                 switch ($db_type) 
    251                                 { 
    252                                         case 'pgsql': 
    253                                                 $result = $db->query('SELECT id FROM '.$db->prefix.'users WHERE username ILIKE \''.$db->escape($author).'\'') or error('Unable to fetch users', __FILE__, __LINE__, $db->error()); 
    254                                                 break; 
    255  
    256                                         default: 
    257                                                 $result = $db->query('SELECT id FROM '.$db->prefix.'users WHERE username LIKE \''.$db->escape($author).'\'') or error('Unable to fetch users', __FILE__, __LINE__, $db->error()); 
    258                                                 break; 
    259                                 } 
    260  
    261                                 if ($db->num_rows($result)) 
    262                                 { 
    263                                         $user_ids = ''; 
    264                                         while ($row = $db->fetch_row($result)) 
    265                                                 $user_ids .= (($user_ids != '') ? ',' : '').$row[0]; 
    266  
    267                                         $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE poster_id IN('.$user_ids.')') or error('Unable to fetch matched posts list', __FILE__, __LINE__, $db->error()); 
    268  
    269                                         $search_ids = array(); 
    270                                         while ($row = $db->fetch_row($result)) 
    271                                                 $author_results[] = $row[0]; 
    272  
    273                                         $db->free_result($result); 
    274                       &nbs