Searching procedures | > Module written by Matt Mecham | > Date started: 24th February 2002 | | > Module Version Number: 1.1.0 +-------------------------------------------------------------------------- | | MODULE NOTES: | ------------- | | I've been deliberating whether we should implement some kind of WORD ID / | search logging table for index. | iB3 PERL had such a feature, but that was to aide the DBM searches, which | were slow at best. | The biggest complaint we had was that adding a word ID / search logging table | effectively doubled the amount of space needed in the mySQL database. I've seen | this complaint echo'd on the support boards of other forum software. | The other downside to such a feature would be the overhaul needed to update it | with new posts/topics and topic movement / deletion. | | I figure that people post more than they search, so a full table scan once per | search request is offset against the CPU to keep the search log tables up to date | | I'm going to stick my neck out and go the full table scan route. It's not as effecient | as a search table would be, but the benefits include no overhead updating it, and a smaller | overall DB size - which is vital to some people on certain hosts. | | This may change if it becomes apparent that it's not very efficient in the long run +-------------------------------------------------------------------------- */ // $idx = new Search; class Search { var $output = ""; var $page_title = ""; var $nav = array(); var $html = ""; var $first = 0; var $search_type = 'posts'; var $sort_order = 'desc'; var $sort_key = 'last_post'; var $search_in = 'posts'; var $prune = '30'; var $st_time = array(); var $end_time = array(); var $st_stamp = ""; var $end_stamp = ""; var $result_type = "topics"; var $parser = ""; function Search() { global $ibforums, $DB, $std, $print; if (! $ibforums->vars['allow_search']) { $std->Error( array( LEVEL => 1, MSG => 'search_off') ); } if ($ibforums->member['g_use_search'] != 1) { $std->Error( array( 'LEVEL' => 1, 'MSG' => 'no_permission' ) ); } if ($ibforums->input['CODE'] == "") $ibforums->input['CODE'] = '00'; //-------------------------------------------- // Require the HTML and language modules //-------------------------------------------- $ibforums->lang = $std->load_words($ibforums->lang, 'lang_search', $ibforums->lang_id ); $ibforums->lang = $std->load_words($ibforums->lang, 'lang_forum' , $ibforums->lang_id ); $this->html = $std->load_template('skin_search'); $this->base_url = "{$ibforums->vars['board_url']}/index.{$ibforums->vars['php_ext']}?s={$ibforums->session_id}"; if (isset($ibforums->input['st']) ) { $this->first = $ibforums->input['st']; } //-------------------------------------------- // What to do? //-------------------------------------------- if (! isset($ibforums->member['g_use_search']) ) { $std->Error( array( LEVEL => 1, MSG => 'cant_use_feature') ); } switch($ibforums->input['CODE']) { case '01': $this->do_search(); break; case 'getnew': $this->get_new_posts(); break; case 'getactive': $this->get_active(); break; case 'show': $this->show_results(); break; case 'getreplied': $this->get_replies(); break; case 'lastten': $this->get_last_ten(); break; case 'getalluser': $this->get_all_user(); break; default: $this->show_form(); break; } // If we have any HTML to print, do so... $print->add_output("$this->output"); $print->do_output( array( 'TITLE' => $this->page_title, 'JS' => 0, NAV => $this->nav ) ); } //--------------------------------- function get_all_user() { global $ibforums, $DB, $std, $HTTP_POST_VARS, $print; //------------------------------------ // Do we have flood control enabled? //------------------------------------ if ($ibforums->member['g_search_flood'] > 0) { $flood_time = time() - $ibforums->member['g_search_flood']; // Get any old search results.. $DB->query("SELECT id FROM ibf_search_results WHERE (member_id='".$ibforums->member['id']."' OR ip_address='".$ibforums->input['IP_ADDRESS']."') AND search_date > '$flood_time'"); if ( $DB->get_num_rows() ) { $std->Error( array( 'LEVEL' => 1, 'MSG' => 'search_flood', 'EXTRA' => $ibforums->member['g_search_flood']) ); } } $ibforums->input['forums'] = 'all'; $forums = $this->get_searchable_forums(); $mid = intval($ibforums->input['mid']); //------------------------------------ // Do we have any forums to search in? //------------------------------------ if ($forums == "") { $std->Error( array( 'LEVEL' => 1, 'MSG' => 'no_search_forum') ); } if ($mid == "") { $std->Error( array( 'LEVEL' => 1, 'MSG' => 'no_search_results' ) ); } //------------------------------------------------ // Get the topic ID's to serialize and store into // the database //------------------------------------------------ $DB->query("SELECT pid FROM ibf_posts WHERE queued <> 1 AND forum_id IN($forums) AND author_id=$mid"); $max_hits = $DB->get_num_rows(); $posts = ""; while ($row = $DB->fetch_row() ) { $posts .= $row['pid'].","; } $DB->free_result(); $posts = preg_replace( "/,$/", "", $posts ); //------------------------------------------------ // Do we have any results? //------------------------------------------------ if ($posts == "") { $std->Error( array( 'LEVEL' => 1, 'MSG' => 'no_search_results' ) ); } //------------------------------------------------ // If we are still here, store the data into the database... //------------------------------------------------ $unique_id = md5(uniqid(microtime(),1)); $str = $DB->compile_db_insert_string( array ( 'id' => $unique_id, 'search_date'=> time(), 'post_id' => $posts, 'post_max' => $max_hits, 'sort_key' => $this->sort_key, 'sort_order' => $this->sort_order, 'member_id' => $ibforums->member['id'], 'ip_address' => $ibforums->input['IP_ADDRESS'], ) ); $DB->query("INSERT INTO ibf_search_results ({$str['FIELD_NAMES']}) VALUES ({$str['FIELD_VALUES']})"); $print->redirect_screen( $ibforums->lang['search_redirect'] , "act=Search&nav=lv&CODE=show&searchid=$unique_id&search_in=posts&result_type=posts" ); exit(); } //--------------------------------- function get_new_posts() { global $ibforums, $DB, $std, $HTTP_POST_VARS, $print; //------------------------------------ // Do we have flood control enabled? //------------------------------------ if ($ibforums->member['g_search_flood'] > 0) { $flood_time = time() - $ibforums->member['g_search_flood']; // Get any old search results.. $DB->query("SELECT id FROM ibf_search_results WHERE (member_id='".$ibforums->member['id']."' OR ip_address='".$ibforums->input['IP_ADDRESS']."') AND search_date > '$flood_time'"); if ( $DB->get_num_rows() ) { $std->Error( array( 'LEVEL' => 1, 'MSG' => 'search_flood', 'EXTRA' => $ibforums->member['g_search_flood']) ); } } $ibforums->input['forums'] = 'all'; $ibforums->input['nav'] = 'lv'; $forums = $this->get_searchable_forums(); //------------------------------------ // Do we have any forums to search in? //------------------------------------ if ($forums == "") { $std->Error( array( 'LEVEL' => 1, 'MSG' => 'no_search_forum') ); } //------------------------------------------------ // Get the topic ID's to serialize and store into // the database //------------------------------------------------ $DB->query("SELECT pid FROM ibf_posts WHERE queued <> 1 AND forum_id IN($forums) AND post_date > '".$ibforums->member['last_visit']."'"); $max_hits = $DB->get_num_rows(); $posts = ""; while ($row = $DB->fetch_row() ) { $posts .= $row['pid'].","; } $DB->free_result(); $posts = preg_replace( "/,$/", "", $posts ); //------------------------------------------------ // Do we have any results? //------------------------------------------------ if ($posts == "") { $std->Error( array( 'LEVEL' => 1, 'MSG' => 'no_search_results' ) ); } //------------------------------------------------ // If we are still here, store the data into the database... //------------------------------------------------ $unique_id = md5(uniqid(microtime(),1)); $str = $DB->compile_db_insert_string( array ( 'id' => $unique_id, 'search_date'=> time(), 'post_id' => $posts, 'post_max' => $max_hits, 'sort_key' => $this->sort_key, 'sort_order' => $this->sort_order, 'member_id' => $ibforums->member['id'], 'ip_address' => $ibforums->input['IP_ADDRESS'], ) ); $DB->query("INSERT INTO ibf_search_results ({$str['FIELD_NAMES']}) VALUES ({$str['FIELD_VALUES']})"); $print->redirect_screen( $ibforums->lang['search_redirect'] , "act=Search&nav=lv&CODE=show&searchid=$unique_id&search_in=posts&result_type=posts" ); exit(); } //-------------------------------------------------------- function get_last_ten() { global $ibforums, $DB, $std, $HTTP_POST_VARS, $print; $ibforums->input['forums'] = 'all'; $forums = $this->get_searchable_forums(); //------------------------------------ // Do we have any forums to search in? //------------------------------------ if ($forums == "") { $std->Error( array( 'LEVEL' => 1, 'MSG' => 'no_search_forum') ); } if ( $read = $std->my_getcookie('topicsread') ) { $this->read_array = unserialize(stripslashes($read)); } //------------------------------------------------ // Get the topic ID's to serialize and store into // the database //------------------------------------------------ $DB->query("SELECT p.*, t.*, f.id as forum_id, f.name as forum_name FROM ibf_forums f, ibf_posts p, ibf_topics t WHERE p.queued <> 1 AND p.forum_id IN($forums) AND p.author_id='".$ibforums->member['id']."' AND t.tid=p.topic_id AND f.id=p.forum_id ORDER BY p.post_date DESC LIMIT 0,10"); if ( $DB->get_num_rows() ) { require "./sources/lib/post_parser.php"; $this->parser = new post_parser(); $this->output .= $this->html->start_as_post( array( 'SHOW_PAGES' => $links ) ); while ($row = $DB->fetch_row() ) { $row['keywords'] = $url_words; $row['post_date'] = $std->get_date( $row['post_date'],'LONG' ); $this->output .= $this->html->RenderPostRow( $this->parse_entry($row, 1) ); } $this->output .= $this->html->end_as_post(array( 'SHOW_PAGES' => $links )); } else { $std->Error( array( 'LEVEL' => 1, 'MSG' => 'no_search_results' ) ); } $DB->free_result(); $this->page_title = $ibforums->lang['nav_lt']; $this->nav = array( $ibforums->lang['nav_lt'] ); } //-------------------------------------------------------- function get_replies() { global $ibforums, $DB, $std, $HTTP_POST_VARS, $print; //------------------------------------ // Do we have flood control enabled? //------------------------------------ if ($ibforums->member['g_search_flood'] > 0) { $flood_time = time() - $ibforums->member['g_search_flood']; // Get any old search results.. $DB->query("SELECT id FROM ibf_search_results WHERE (member_id='".$ibforums->member['id']."' OR ip_address='".$ibforums->input['IP_ADDRESS']."') AND search_date > '$flood_time'"); if ( $DB->get_num_rows() ) { $std->Error( array( 'LEVEL' => 1, 'MSG' => 'search_flood', 'EXTRA' => $ibforums->member['g_search_flood']) ); } } $ibforums->input['forums'] = 'all'; $ibforums->input['nav'] = 'lv'; $forums = $this->get_searchable_forums(); //------------------------------------ // Do we have any forums to search in? //------------------------------------ if ($forums == "") { $std->Error( array( 'LEVEL' => 1, 'MSG' => 'no_search_forum') ); } //------------------------------------------------ // Get the topic ID's to serialize and store into // the database //------------------------------------------------ $DB->query("SELECT tid FROM ibf_topics WHERE starter_id='".$ibforums->member['id']."' AND last_post > ".$ibforums->member['last_visit']." AND forum_id IN($forums) AND approved=1"); $max_hits = $DB->get_num_rows(); $topics = ""; while ($row = $DB->fetch_row() ) { $topics .= $row['tid'].","; } $DB->free_result(); $topics = preg_replace( "/,$/", "", $topics ); //------------------------------------------------ // Do we have any results? //------------------------------------------------ if ($topics == "") { $std->Error( array( 'LEVEL' => 1, 'MSG' => 'no_search_results' ) ); } //------------------------------------------------ // If we are still here, store the data into the database... //------------------------------------------------ $unique_id = md5(uniqid(microtime(),1)); $str = $DB->compile_db_insert_string( array ( 'id' => $unique_id, 'search_date'=> time(), 'topic_id' => $topics, 'topic_max' => $max_hits, 'sort_key' => $this->sort_key, 'sort_order' => $this->sort_order, 'member_id' => $ibforums->member['id'], 'ip_address' => $ibforums->input['IP_ADDRESS'], ) ); $DB->query("INSERT INTO ibf_search_results ({$str['FIELD_NAMES']}) VALUES ({$str['FIELD_VALUES']})"); $print->redirect_screen( $ibforums->lang['search_redirect'] , "act=Search&nav=gr&CODE=show&searchid=$unique_id&search_in=posts&result_type=topics" ); exit(); } function show_form() { global $DB, $std, $ibforums; $last_cat_id = -1; $the_hiddens = ""; $DB->query("SELECT f.id as forum_id, f.name as forum_name, f.position, f.read_perms, c.id as cat_id, c.name as cat_name from ibf_forums f, ibf_categories c where c.id=f.category ORDER BY c.position, f.position"); $forums = "\n" ."