function search_text_in_db($searchstr, $base_sql, $where_search, $add_where = array(), $strict = false) { global $db, $config; //$stopword_array = @file($root_path . 'languages/lang_' . $config['default_lang'] . '/search_stopwords.txt'); //$synonym_array = @file($root_path . 'languages/lang_' . $config['default_lang'] . '/search_synonyms.txt'); $match_types = array('or', 'not', 'and'); $add_where = sizeof($add_where) ? ' AND ' . implode(' AND ', $add_where) : ''; $cleansearchstr = searchfield($searchstr); $lower_searchstr = utf_strtolower($searchstr); if ($strict) { $split_search = array($lower_searchstr); } else { $split_search = split_words($cleansearchstr); if ($lower_searchstr != $searchstr) { $search_full_string = true; foreach ($match_types as $_null => $match_type) { if (strpos($lower_searchstr, $match_type) !== false) { $search_full_string = false; } } if ($search_full_string) { $split_search[] = $lower_searchstr; } } } $word_count = 0; $current_match_type = 'and'; $word_match = array(); $result_list = array(); for ($i = 0; $i < sizeof($split_search); $i++) { if (utf_strlen(str_replace(array('*', '%'), '', trim($split_search[$i]))) < $config['search_min_chars'] && !in_array($split_search[$i], $match_types)) { $split_search[$i] = ''; continue; } switch ($split_search[$i]) { case 'and': $current_match_type = 'and'; break; case 'or': $current_match_type = 'or'; break; case 'not': $current_match_type = 'not'; break; default: if (!empty($search_terms)) { $current_match_type = 'and'; } if ($strict) { $search = $where_search . ' = \'' . sqlesc($split_search[$i]) . '\'' . $add_where; } else { $match_word = str_replace('*', '%', $split_search[$i]); $search = $where_search . ' LIKE \'%' . sqlesc($match_word) . '%\'' . $add_where; //$search = $where_search . ' REGEXP \'[[:<:]]' . $db->sql_escape($match_word) . '[[:>:]]\'' . $add_where; } $sql = $base_sql . ' WHERE ' . $search; $result = sql_query($sql); $row = array(); while ($temp_row = mysqli_fetch_row($result)) { $row[$temp_row['id']] = 1; if (!$word_count) { $result_list[$temp_row['id']] = 1; } else { if ($current_match_type == 'or') { $result_list[$temp_row['id']] = 1; } else { if ($current_match_type == 'not') { $result_list[$temp_row['id']] = 0; } } } } if ($current_match_type == 'and' && $word_count) { @reset($result_list); foreach ($result_list as $id => $match_count) { if (!isset($row[$id]) || !$row[$id]) { //$result_list[$id] = 0; @($result_list[$id] -= 1); } else { @($result_list[$id] += 1); } } } $word_count++; mysqli_fetch_assoc($result); } } @reset($result_list); $search_ids = array(); foreach ($result_list as $id => $matches) { if ($matches > 0) { //if ( $matches ) { $search_ids[] = $id; } } unset($result_list); return $search_ids; }
function update_search_index($mode, $post_id, $message, $subject = null) { global $db_type; // Get Slim current session $feather = \Slim\Slim::getInstance(); $message = utf8_strtolower($message); $subject = utf8_strtolower($subject); // Remove any bbcode that we shouldn't index $message = strip_bbcode($message); // Split old and new post/subject to obtain array of 'words' $words_message = split_words($message, true); $words_subject = $subject ? split_words($subject, true) : array(); if ($mode == 'edit') { $select_update_search_index = array('w.id', 'w.word', 'm.subject_match'); $result = \DB::for_table('search_words')->table_alias('w')->select_many($select_update_search_index)->inner_join('search_matches', array('w.id', '=', 'm.word_id'), 'm')->where('m.post_id', $post_id)->find_many(); // Declare here to stop array_keys() and array_diff() from complaining if not set $cur_words['post'] = array(); $cur_words['subject'] = array(); foreach ($result as $row) { $match_in = $row['subject_match'] ? 'subject' : 'post'; $cur_words[$match_in][$row['word']] = $row['id']; } $pdo = \DB::get_db(); $pdo = null; $words['add']['post'] = array_diff($words_message, array_keys($cur_words['post'])); $words['add']['subject'] = array_diff($words_subject, array_keys($cur_words['subject'])); $words['del']['post'] = array_diff(array_keys($cur_words['post']), $words_message); $words['del']['subject'] = array_diff(array_keys($cur_words['subject']), $words_subject); } else { $words['add']['post'] = $words_message; $words['add']['subject'] = $words_subject; $words['del']['post'] = array(); $words['del']['subject'] = array(); } unset($words_message); unset($words_subject); // Get unique words from the above arrays $unique_words = array_unique(array_merge($words['add']['post'], $words['add']['subject'])); if (!empty($unique_words)) { $select_unique_words = array('id', 'word'); $result = \DB::for_table('search_words')->select_many($select_unique_words)->where_in('word', $unique_words)->find_many(); $word_ids = array(); foreach ($result as $row) { $word_ids[$row['word']] = $row['id']; } $pdo = \DB::get_db(); $pdo = null; $new_words = array_values(array_diff($unique_words, array_keys($word_ids))); unset($unique_words); if (!empty($new_words)) { switch ($db_type) { case 'mysql': case 'mysqli': case 'mysql_innodb': case 'mysqli_innodb': // Quite dirty, right? :-) $placeholders = rtrim(str_repeat('(?), ', count($new_words)), ', '); \DB::for_table('search_words')->raw_execute('INSERT INTO ' . $feather->prefix . 'search_words (word) VALUES ' . $placeholders, $new_words); break; default: foreach ($new_words as $word) { $word_insert['word'] = $word; \DB::for_table('search_words')->create()->set($word_insert)->save(); } break; } } unset($new_words); } // Delete matches (only if editing a post) foreach ($words['del'] as $match_in => $wordlist) { $subject_match = $match_in == 'subject' ? 1 : 0; if (!empty($wordlist)) { $sql = array(); foreach ($wordlist as $word) { $sql[] = $cur_words[$match_in][$word]; } \DB::for_table('search_matches')->where_in('word_id', $sql)->where('post_id', $post_id)->where('subject_match', $subject_match)->delete_many(); } } // Add new matches foreach ($words['add'] as $match_in => $wordlist) { $subject_match = $match_in == 'subject' ? 1 : 0; if (!empty($wordlist)) { $wordlist = array_values($wordlist); $placeholders = rtrim(str_repeat('?, ', count($wordlist)), ', '); \DB::for_table('search_words')->raw_execute('INSERT INTO ' . $feather->prefix . 'search_matches (post_id, word_id, subject_match) SELECT ' . $post_id . ', id, ' . $subject_match . ' FROM ' . $feather->prefix . 'search_words WHERE word IN (' . $placeholders . ')', $wordlist); } } unset($words); }
function main($action) { global $template, $lang, $config, $pafiledb_config, $db, $images, $user; if (!$this->auth_global['auth_search']) { if (!$user->data['session_logged_in']) { redirect(append_sid(CMS_PAGE_LOGIN . '?redirect=dload.' . PHP_EXT . '&action=stats', true)); } $message = sprintf($lang['Sorry_auth_search'], $this->auth_global['auth_search_type']); message_die(GENERAL_MESSAGE, $message); } include IP_ROOT_PATH . 'includes/functions_search.' . PHP_EXT; $search_keywords = request_var('search_keywords', '', true); $search_keywords = htmlspecialchars_decode($search_keywords, ENT_COMPAT); $search_author = request_var('search_author', '', true); $search_author = htmlspecialchars_decode($search_author, ENT_COMPAT); $search_id = request_var('search_id', 0); $search_terms = request_var('search_terms', ''); $search_terms = $search_terms == 'all' ? 1 : 0; $cat_id = request_var('cat_id', 0); $comments_search = request_var('comments_search', ''); $comments_search = $comments_search == 'YES' ? 1 : 0; $start = request_var('start', 0); $start = $start < 0 ? 0 : $start; $sort_method = request_var('sort_method', $pafiledb_config['sort_method']); $sort_method = check_var_value($sort_method, array('file_name', 'file_time', 'file_dls', 'file_rating', 'file_update_time')); $sort_method = $sort_method == 'file_rating' ? 'rating' : $sort_method; $sort_order = request_var('order', $pafiledb_config['sort_order']); $sort_order = check_var_value($sort_order, array('DESC', 'ASC')); $limit_sql = $start == 0 ? $pafiledb_config['settings_file_page'] : $start . ',' . $pafiledb_config['settings_file_page']; // encoding match for workaround $multibyte_charset = 'utf-8, big5, shift_jis, euc-kr, gb2312'; if (isset($_POST['submit']) || $search_author != '' || $search_keywords != '' || $search_id) { $store_vars = array('search_results', 'total_match_count', 'split_search', 'sort_method', 'sort_order'); if ($search_author != '' || $search_keywords != '') { if ($search_author != '' && $search_keywords == '') { $search_author = str_replace('*', '%', trim($search_author)); $sql = get_users_sql($search_author, true, false, true, false); $result = $db->sql_query($sql); $matching_userids = ''; if ($row = $db->sql_fetchrow($result)) { do { $matching_userids .= ($matching_userids != '' ? ', ' : '') . $row['user_id']; } while ($row = $db->sql_fetchrow($result)); } else { message_die(GENERAL_MESSAGE, $lang['No_search_match']); } $sql = "SELECT *\n\t\t\t\t\t\tFROM " . PA_FILES_TABLE . "\n\t\t\t\t\t\tWHERE user_id IN ({$matching_userids})"; $result = $db->sql_query($sql); $search_ids = array(); while ($row = $db->sql_fetchrow($result)) { if ($this->auth[$row['file_catid']]['auth_view']) { $search_ids[] = $row['file_id']; } } $db->sql_freeresult($result); $total_match_count = sizeof($search_ids); } elseif ($search_keywords != '') { stopwords_synonyms_init(); $split_search = array(); $split_search = !strstr($multibyte_charset, $lang['ENCODING']) ? split_words(clean_words('search', stripslashes($search_keywords), $stopwords_array, $synonyms_array), 'search') : split(' ', $search_keywords); $word_count = 0; $current_match_type = 'or'; $word_match = array(); $result_list = array(); for ($i = 0; $i < sizeof($split_search); $i++) { switch ($split_search[$i]) { case 'and': $current_match_type = 'and'; break; case 'or': $current_match_type = 'or'; break; case 'not': $current_match_type = 'not'; break; default: if (!empty($search_terms)) { $current_match_type = 'and'; } $match_word = addslashes('%' . str_replace('*', '', $split_search[$i]) . '%'); $sql = "SELECT file_id\n\t\t\t\t\t\t\t\t\tFROM " . PA_FILES_TABLE . "\n\t\t\t\t\t\t\t\t\tWHERE (file_name LIKE '{$match_word}'\n\t\t\t\t\t\t\t\t\tOR file_creator LIKE '{$match_word}'\n\t\t\t\t\t\t\t\t\tOR file_desc LIKE '{$match_word}'\n\t\t\t\t\t\t\t\t\tOR file_longdesc LIKE '{$match_word}')"; $result = $db->sql_query($sql); $row = array(); while ($temp_row = $db->sql_fetchrow($result)) { $row[$temp_row['file_id']] = 1; if (!$word_count) { $result_list[$temp_row['file_id']] = 1; } elseif ($current_match_type == 'or') { $result_list[$temp_row['file_id']] = 1; } elseif ($current_match_type == 'not') { $result_list[$temp_row['file_id']] = 0; } } if ($current_match_type == 'and' && $word_count) { @reset($result_list); while (list($file_id, $match_count) = @each($result_list)) { if (!$row[$file_id]) { $result_list[$file_id] = 0; } } } if ($comments_search) { $sql = "SELECT file_id\n\t\t\t\t\t\t\t\t\tFROM " . PA_COMMENTS_TABLE . "\n\t\t\t\t\t\t\t\t\tWHERE (comments_title LIKE '{$match_word}'\n\t\t\t\t\t\t\t\t\tOR comments_text LIKE '{$match_word}')"; $result = $db->sql_query($sql); $row = array(); while ($temp_row = $db->sql_fetchrow($result)) { $row[$temp_row['file_id']] = 1; if (!$word_count) { $result_list[$temp_row['file_id']] = 1; } else { if ($current_match_type == 'or') { $result_list[$temp_row['file_id']] = 1; } else { if ($current_match_type == 'not') { $result_list[$temp_row['file_id']] = 0; } } } } if ($current_match_type == 'and' && $word_count) { @reset($result_list); while (list($file_id, $match_count) = @each($result_list)) { if (!$row[$file_id]) { $result_list[$file_id] = 0; } } } } $word_count++; $db->sql_freeresult($result); } } @reset($result_list); $search_ids = array(); while (list($file_id, $matches) = each($result_list)) { if ($matches) { $search_ids[] = $file_id; } } unset($result_list); $total_match_count = sizeof($search_ids); } // Author name search if ($search_author != '') { $search_author = str_replace('*', '%', trim($db->sql_escape($search_author))); } if ($total_match_count) { $where_sql = $cat_id ? 'AND file_catid IN (' . $this->gen_cat_ids($cat_id, '') . ')' : ''; if ($search_author == '') { $sql = "SELECT file_id, file_catid\n\t\t\t\t\t\t\tFROM " . PA_FILES_TABLE . "\n\t\t\t\t\t\t\tWHERE file_id IN (" . implode(", ", $search_ids) . ")\n\t\t\t\t\t\t\t\t{$where_sql}\n\t\t\t\t\t\t\tGROUP BY file_id"; } else { $from_sql = PA_FILES_TABLE . " f"; if ($search_author != '') { $from_sql .= ", " . USERS_TABLE . " u"; $where_sql .= " AND u.user_id = f.user_id AND u.username LIKE '{$search_author}' "; } $where_sql .= $cat_id ? 'AND file_catid IN (' . $this->gen_cat_ids($cat_id, '') . ')' : ''; $sql = "SELECT f.file_id, f.file_catid\n\t\t\t\t\t\t\tFROM {$from_sql}\n\t\t\t\t\t\t\tWHERE f.file_id IN (" . implode(", ", $search_ids) . ")\n\t\t\t\t\t\t\t{$where_sql}\n\t\t\t\t\t\t\tGROUP BY f.file_id"; } $result = $db->sql_query($sql); $search_ids = array(); while ($row = $db->sql_fetchrow($result)) { if ($this->auth[$row['file_catid']]['auth_view']) { $search_ids[] = $row['file_id']; } } $db->sql_freeresult($result); $total_match_count = sizeof($search_ids); } else { message_die(GENERAL_MESSAGE, $lang['No_search_match']); } // // Finish building query (for all combinations) // and run it ... // $expiry_time = $current_time - $config['session_length']; $sql = "SELECT session_id\n\t\t\t\t\tFROM " . SESSIONS_TABLE . "\n\t\t\t\t\tWHERE session_time > {$expiry_time}"; $db->sql_return_on_error(true); $result = $db->sql_query($sql); $db->sql_return_on_error(false); if ($result) { $delete_search_ids = array(); while ($row = $db->sql_fetchrow($result)) { $delete_search_ids[] = "'" . $row['session_id'] . "'"; } if (sizeof($delete_search_ids)) { $sql = "DELETE FROM " . SEARCH_TABLE . "\n\t\t\t\t\t\t\tWHERE session_id NOT IN (" . implode(", ", $delete_search_ids) . ")"; $result = $db->sql_query($sql); } } // Store new result data $search_results = implode(', ', $search_ids); $store_search_data = array(); for ($i = 0; $i < sizeof($store_vars); $i++) { $store_search_data[$store_vars[$i]] = ${$store_vars}[$i]; } $result_array = serialize($store_search_data); unset($store_search_data); mt_srand((double) microtime() * 1000000); $search_id = mt_rand(); $sql = "UPDATE " . SEARCH_TABLE . "\n\t\t\t\t\tSET search_id = {$search_id}, search_array = '" . $db->sql_escape($result_array) . "'\n\t\t\t\t\tWHERE session_id = '" . $user->data['session_id'] . "'"; $db->sql_return_on_error(true); $result = $db->sql_query($sql); $db->sql_return_on_error(false); if (!$result || !$db->sql_affectedrows()) { $sql = "INSERT INTO " . SEARCH_TABLE . " (search_id, session_id, search_array)\n\t\t\t\t\t\tVALUES({$search_id}, '" . $user->data['session_id'] . "', '" . $db->sql_escape($result_array) . "')"; $result = $db->sql_query($sql); } } else { $search_id = intval($search_id); if ($search_id) { $sql = "SELECT search_array\n\t\t\t\t\t\tFROM " . SEARCH_TABLE . "\n\t\t\t\t\t\tWHERE search_id = {$search_id}\n\t\t\t\t\t\tAND session_id = '" . $user->data['session_id'] . "'"; $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { $search_data = unserialize($row['search_array']); for ($i = 0; $i < sizeof($store_vars); $i++) { ${$store_vars}[$i] = $search_data[$store_vars[$i]]; } } } } if ($search_results != '') { $sql = "SELECT f1.*, AVG(r.rate_point) AS rating, COUNT(r.votes_file) AS total_votes, u.user_id, u.username, u.user_active, u.user_color, c.cat_id, c.cat_name, COUNT(cm.comments_id) AS total_comments\n\t\t\t\t\tFROM (" . PA_FILES_TABLE . " AS f1, " . PA_CATEGORY_TABLE . " AS c)\n\t\t\t\t\t\tLEFT JOIN " . PA_VOTES_TABLE . " AS r ON f1.file_id = r.votes_file\n\t\t\t\t\t\tLEFT JOIN " . USERS_TABLE . " AS u ON f1.user_id = u.user_id\n\t\t\t\t\t\tLEFT JOIN " . PA_COMMENTS_TABLE . " AS cm ON f1.file_id = cm.file_id\n\t\t\t\t\tWHERE f1.file_id IN ({$search_results})\n\t\t\t\t\tAND c.cat_id = f1.file_catid\n\t\t\t\t\tAND f1.file_approved = '1'\n\t\t\t\t\tGROUP BY f1.file_id\n\t\t\t\t\tORDER BY {$sort_method} {$sort_order}\n\t\t\t\t\tLIMIT {$limit_sql}"; $result = $db->sql_query($sql); $searchset = array(); while ($row = $db->sql_fetchrow($result)) { $searchset[] = $row; } $db->sql_freeresult($result); $l_search_matches = $total_match_count == 1 ? sprintf($lang['Found_search_match'], $total_match_count) : sprintf($lang['Found_search_matches'], $total_match_count); $template->assign_vars(array('L_SEARCH_MATCHES' => $l_search_matches)); for ($i = 0; $i < sizeof($searchset); $i++) { $cat_url = append_sid('dload.' . PHP_EXT . '?action=category&cat_id=' . $searchset[$i]['cat_id']); $file_url = append_sid('dload.' . PHP_EXT . '?action=file&file_id=' . $searchset[$i]['file_id']); //=================================================== // Format the date for the given file //=================================================== $date = create_date_ip($config['default_dateformat'], $searchset[$i]['file_time'], $config['board_timezone']); //=================================================== // Get rating for the file and format it //=================================================== //$rating = ($searchset[$i]['rating'] != 0) ? round($searchset[$i]['rating'], 2) . ' / 10' : $lang['Not_rated']; //$rating2 = ($searchset[$i]['rating'] != 0) ? sprintf("%.1f", round(($searchset[$i]['rating']), 2) / 2) : '0.0'; $rating2 = $searchset[$i]['rating'] != 0 ? sprintf("%.1f", round($searchset[$i]['rating'], 0) / 2) : '0.0'; //=================================================== // If the file is new then put a new image in front of it //=================================================== $is_new = false; if (time() - $pafiledb_config['settings_newdays'] * 24 * 60 * 60 < $searchset[$i]['file_time']) { $is_new = true; } $xs_new = $is_new ? '-new' : ''; //=================================================== // Get the post icon fot this file //=================================================== if ($searchset[$i]['file_pin'] != FILE_PINNED) { if ($searchset[$i]['file_posticon'] == 'none' || $searchset[$i]['file_posticon'] == 'none.gif') { $posticon = '<img src="' . IP_ROOT_PATH . FILES_ICONS_DIR . 'default.png" alt="" />'; //$posticon = ' '; } else { $posticon = '<img src="' . FILES_ICONS_DIR . $searchset[$i]['file_posticon'] . '" alt="" />'; } } else { $posticon = '<img src="' . $images['forum_link'] . '" alt="" />'; } $poster = $searchset[$i]['user_id'] == ANONYMOUS ? $lang['Guest'] : colorize_username($searchset[$i]['user_id'], $searchset[$i]['username'], $searchset[$i]['user_color'], $searchset[$i]['user_active']); $template->assign_block_vars('searchresults', array('CAT_NAME' => $searchset[$i]['cat_name'], 'FILE_NEW_IMAGE' => $images['pa_file_new'], 'PIN_IMAGE' => $posticon, 'L_HOME' => $lang['Home'], 'CURRENT_TIME' => sprintf($lang['Current_time'], create_date($config['default_dateformat'], time(), $config['board_timezone'])), 'XS_NEW' => $xs_new, 'IS_NEW_FILE' => $is_new, 'FILE_NAME' => $searchset[$i]['file_name'], 'FILE_DESC' => $searchset[$i]['file_desc'], 'FILE_SUBMITER' => $poster, 'DATE' => $date, 'RATING' => $rating2, 'DOWNLOADS' => $searchset[$i]['file_dls'], 'U_FILE' => $file_url, 'U_CAT' => $cat_url)); } $base_url = append_sid('dload.' . PHP_EXT . '?action=search&search_id=' . $search_id); $template->assign_vars(array('PAGINATION' => generate_pagination($base_url, $total_match_count, $pafiledb_config['settings_file_page'], $start), 'PAGE_NUMBER' => sprintf($lang['Page_of'], floor($start / $pafiledb_config['settings_file_page']) + 1, ceil($total_match_count / $pafiledb_config['settings_file_page'])), 'DOWNLOAD' => $pafiledb_config['settings_dbname'], 'L_HOME' => $lang['Home'], 'U_INDEX_HOME' => append_sid(CMS_PAGE_HOME), 'U_DOWNLOAD' => append_sid('dload.' . PHP_EXT), 'L_HOME' => $lang['Home'], 'CURRENT_TIME' => sprintf($lang['Current_time'], create_date($config['default_dateformat'], time(), $config['board_timezone'])), 'XS_NEW' => $xs_new, 'L_INDEX' => sprintf($lang['Forum_Index'], $config['sitename']), 'L_RATE' => $lang['DlRating'], 'L_DOWNLOADS' => $lang['Dls'], 'L_DATE' => $lang['Date'], 'L_NAME' => $lang['Name'], 'L_FILE' => $lang['File'], 'L_SUBMITER' => $lang['Submiter'], 'L_CATEGORY' => $lang['Category'], 'L_NEW_FILE' => $lang['New_file'])); $this->display($lang['Download'], 'pa_search_result.tpl'); } else { message_die(GENERAL_MESSAGE, $lang['No_search_match']); } } if (!isset($_POST['submit']) || $search_author == '' && $search_keywords == '' && !$search_id) { $dropmenu = $this->jumpmenu_option(); $template->assign_vars(array('S_SEARCH_ACTION' => append_sid('dload.php'), 'S_CAT_MENU' => $dropmenu, 'DOWNLOAD' => $pafiledb_config['settings_dbname'], 'U_INDEX_HOME' => append_sid(CMS_PAGE_HOME), 'U_DOWNLOAD' => append_sid('dload.' . PHP_EXT), 'L_HOME' => $lang['Home'], 'CURRENT_TIME' => sprintf($lang['Current_time'], create_date($config['default_dateformat'], time(), $config['board_timezone'])), 'XS_NEW' => $xs_new, 'L_YES' => $lang['Yes'], 'L_NO' => $lang['No'], 'L_SEARCH_OPTIONS' => $lang['Search_options'], 'L_SEARCH_KEYWORDS' => $lang['Search_keywords'], 'L_SEARCH_KEYWORDS_EXPLAIN' => $lang['Search_keywords_explain'], 'L_SEARCH_AUTHOR' => $lang['Search_author'], 'L_SEARCH_AUTHOR_EXPLAIN' => $lang['Search_author_explain'], 'L_SEARCH_ANY_TERMS' => $lang['Search_for_any'], 'L_SEARCH_ALL_TERMS' => $lang['Search_for_all'], 'L_INCLUDE_COMMENTS' => $lang['Include_comments'], 'L_SORT_BY' => $lang['Select_sort_method'], 'L_SORT_DIR' => $lang['Order'], 'L_SORT_ASCENDING' => $lang['Sort_Ascending'], 'L_SORT_DESCENDING' => $lang['Sort_Descending'], 'L_INDEX' => sprintf($lang['Forum_Index'], $config['sitename']), 'L_RATING' => $lang['DlRating'], 'L_DOWNLOADS' => $lang['Dls'], 'L_DATE' => $lang['Date'], 'L_NAME' => $lang['Name'], 'L_UPDATE_TIME' => $lang['Update_time'], 'L_SEARCH' => $lang['Search'], 'L_SEARCH_FOR' => $lang['Search_for'], 'L_ALL' => $lang['All'], 'L_CHOOSE_CAT' => $lang['Choose_cat'])); $this->display($lang['Download'], 'pa_search_body.tpl'); } }
function add_search_words($mode, $post_id, $post_text, $post_title = '') { global $db, $phpbb_root_path, $board_config, $lang; $stopword_array = @file($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . "/search_stopwords.txt"); $synonym_array = @file($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . "/search_synonyms.txt"); $search_raw_words = array(); $search_raw_words['text'] = split_words(clean_words('post', $post_text, $stopword_array, $synonym_array)); $search_raw_words['title'] = split_words(clean_words('post', $post_title, $stopword_array, $synonym_array)); @set_time_limit(0); $word = array(); $word_insert_sql = array(); while (list($word_in, $search_matches) = @each($search_raw_words)) { $word_insert_sql[$word_in] = ''; if (!empty($search_matches)) { for ($i = 0; $i < count($search_matches); $i++) { $search_matches[$i] = trim($search_matches[$i]); if ($search_matches[$i] != '') { $word[] = $search_matches[$i]; if (!strstr($word_insert_sql[$word_in], "'" . $search_matches[$i] . "'")) { $word_insert_sql[$word_in] .= $word_insert_sql[$word_in] != "" ? ", '" . $search_matches[$i] . "'" : "'" . $search_matches[$i] . "'"; } } } } } if (count($word)) { sort($word); $prev_word = ''; $word_text_sql = ''; $temp_word = array(); for ($i = 0; $i < count($word); $i++) { if ($word[$i] != $prev_word) { $temp_word[] = $word[$i]; $word_text_sql .= ($word_text_sql != '' ? ', ' : '') . "'" . $word[$i] . "'"; } $prev_word = $word[$i]; } $word = $temp_word; $check_words = array(); switch (SQL_LAYER) { case 'postgresql': case 'msaccess': case 'mssql-odbc': case 'oracle': case 'db2': $sql = "SELECT word_id, word_text\r\n FROM " . SEARCH_WORD_TABLE . "\r\n WHERE word_text IN ({$word_text_sql})"; if (!($result = $db->sql_query($sql))) { message_die(GENERAL_ERROR, 'Could not select words', '', __LINE__, __FILE__, $sql); } while ($row = $db->sql_fetchrow($result)) { $check_words[$row['word_text']] = $row['word_id']; } break; } $value_sql = ''; $match_word = array(); for ($i = 0; $i < count($word); $i++) { $new_match = true; if (isset($check_words[$word[$i]])) { $new_match = false; } if ($new_match) { switch (SQL_LAYER) { case 'mysql': case 'mysql4': $value_sql .= ($value_sql != '' ? ', ' : '') . '(\'' . $word[$i] . '\', 0)'; break; case 'mssql': case 'mssql-odbc': $value_sql .= ($value_sql != '' ? ' UNION ALL ' : '') . "SELECT '" . $word[$i] . "', 0"; break; default: $sql = "INSERT INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)\r\n VALUES ('" . $word[$i] . "', '0')"; if (!$db->sql_query($sql)) { message_die(GENERAL_ERROR, 'Could not insert new word', '', __LINE__, __FILE__, $sql); } break; } } } if ($value_sql != '') { switch (SQL_LAYER) { case 'mysql': case 'mysql4': $sql = "INSERT IGNORE INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)\r\n VALUES {$value_sql}"; break; case 'mssql': case 'mssql-odbc': $sql = "INSERT INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)\r\n {$value_sql}"; break; } if (!$db->sql_query($sql)) { message_die(GENERAL_ERROR, 'Could not insert new word', '', __LINE__, __FILE__, $sql); } } } while (list($word_in, $match_sql) = @each($word_insert_sql)) { $title_match = $word_in == 'title' ? 1 : 0; if ($match_sql != '') { $sql = "INSERT INTO " . SEARCH_MATCH_TABLE . " (post_id, word_id, title_match)\r\n SELECT {$post_id}, word_id, {$title_match}\r\n FROM " . SEARCH_WORD_TABLE . "\r\n WHERE word_text IN ({$match_sql})"; if (!$db->sql_query($sql)) { message_die(GENERAL_ERROR, 'Could not insert new word matches', '', __LINE__, __FILE__, $sql); } } } if ($mode == 'single') { remove_common('single', 4 / 10, $word); } return; }
/** * Get similar topics * If user is guest or bot it will create a cache list in topics table to save some SQL charge */ function get_similar_topics($similar_forums_auth, $topic_id, $topic_title, $similar_topics_ids = '', $topic_desc = '') { global $db, $config, $user, $lang; $similar_topics = array(); if ($similar_topics_ids !== '' && (!$user->data['session_logged_in'] || $user->data['is_bot'])) { if ($similar_topics_ids == 'empty') { return $similar_topics; } $topics_array = $similar_topics_ids; $sql = "SELECT t.*, u.user_id, u.username, u.user_active, u.user_color, u2.username as user2, u2.user_id as id2, u2.user_active as user_active2, u2.user_color as user_color2, f.forum_id, f.forum_name, p.post_time, p.post_username\n\t\t\t\t\tFROM " . TOPICS_TABLE . " t, " . USERS_TABLE . " u, " . FORUMS_TABLE . " f, " . POSTS_TABLE . " p, " . USERS_TABLE . " u2\n\t\t\t\t\tWHERE t.topic_id IN (" . $topics_array . ")\n\t\t\t\t\t\tAND t.forum_id = f.forum_id\n\t\t\t\t\t\tAND p.poster_id = u2.user_id\n\t\t\t\t\t\tAND p.post_id = t.topic_last_post_id\n\t\t\t\t\t\tAND t.topic_poster = u.user_id\n\t\t\t\t\t\tAND t.topic_status <> " . TOPIC_MOVED . "\n\t\t\t\t\tGROUP BY t.topic_id\n\t\t\t\t\tORDER BY p.post_time"; $result = $db->sql_query($sql); $similar_topics = $db->sql_fetchrowset($result); $db->sql_freeresult($result); return $similar_topics; } if ($config['similar_ignore_forums_ids']) { $ignore_forums_ids = array_map('intval', explode("\n", trim($config['similar_ignore_forums_ids']))); } else { $ignore_forums_ids = array(); } // Get forum auth information to insure privacy of hidden topics $forums_auth_sql = ''; //foreach ($similar_forums_auth as $k=>$v) //$similar_forums_auth = auth(AUTH_ALL, AUTH_LIST_ALL, $user->data); foreach ($similar_forums_auth as $k => $v) { if (sizeof($ignore_forums_ids) && in_array($k, $ignore_forums_ids)) { continue; } if ($v['auth_view'] && $v['auth_read']) { $forums_auth_sql .= ($forums_auth_sql == '' ? '' : ', ') . $k; } } if ($forums_auth_sql != '') { $forums_auth_sql = ' AND t.forum_id IN (' . $forums_auth_sql . ') '; } if ($config['similar_stopwords']) { // encoding match for workaround $multibyte_charset = 'utf-8, big5, shift_jis, euc-kr, gb2312'; // check against stopwords start @(include_once IP_ROOT_PATH . 'includes/functions_search.' . PHP_EXT); stopwords_synonyms_init(); $synonyms_array = array(); // check against stopwords end $title_search = ''; $title_search_array = !strstr($multibyte_charset, $lang['ENCODING']) ? split_words(clean_words('post', $topic_title, $stopwords_array, $synonyms_array), 'search') : split(' ', $topic_title); for ($i = 0; $i < sizeof($title_search_array); $i++) { $title_search .= ($title_search == '' ? '' : ' ') . $title_search_array[$i]; } } else { $title_search = $topic_title; } /* if (!empty($topic_desc) && $config['similar_topicdesc']) { if ($config['similar_stopwords']) { $topicdesc = ''; $topic_desc_array = (!strstr($multibyte_charset, $lang['ENCODING'])) ? split_words(clean_words('post', $topic_desc, $stopwords_array, $synonyms_array), 'search') : split(' ', $topic_desc); for ($i = 0; $i < sizeof($topic_desc_array); $i++) { $topicdesc .= (($topicdesc == '') ? '': ' ') . $topic_desc_array[$i]; } } else { $topicdesc = $topic_desc; } $sql_topic_desc = "+MATCH(t.topic_desc) AGAINST('" . $db->sql_escape($topicdesc) . "')"; } $sql_match = "MATCH(t.topic_title) AGAINST('" . $db->sql_escape($title_search) . "')" . $sql_topic_desc; */ $sql_match = "MATCH(t.topic_title) AGAINST('" . $db->sql_escape($title_search) . "')"; if ($config['similar_sort_type'] == 'time') { $sql_sort = 'p.post_time'; } else { $sql_sort = 'relevance'; } //ORDER BY t.topic_type DESC, ' . $sql_sort . ' DESC LIMIT 0,' . intval($config['similar_max_topics']); $sql = "SELECT t.*, u.user_id, u.username, u.user_active, u.user_color, u2.username as user2, u2.user_id as id2, u2.user_active as user_active2, u2.user_color as user_color2, f.forum_id, f.forum_name, p.post_time, p.post_username, {$sql_match} as relevance\n\t\t\t\tFROM " . TOPICS_TABLE . " t, " . USERS_TABLE . " u, " . FORUMS_TABLE . " f, " . POSTS_TABLE . " p, " . USERS_TABLE . " u2\n\t\t\t\tWHERE t.topic_id <> {$topic_id} {$forums_auth_sql}\n\t\t\t\t\tAND {$sql_match}\n\t\t\t\t\tAND t.forum_id = f.forum_id\n\t\t\t\t\tAND p.poster_id = u2.user_id\n\t\t\t\t\tAND p.post_id = t.topic_last_post_id\n\t\t\t\t\tAND t.topic_poster = u.user_id\n\t\t\t\t\tAND t.topic_status <> " . TOPIC_MOVED . "\n\t\t\t\tGROUP BY t.topic_id\n\t\t\t\tORDER BY " . $sql_sort . " DESC LIMIT 0," . intval($config['similar_max_topics']); $result = $db->sql_query($sql); $similar_topics = $db->sql_fetchrowset($result); $db->sql_freeresult($result); $count_similar = sizeof($similar_topics); if (!$user->data['session_logged_in'] || $user->data['is_bot']) { $similar_ids_array = 'empty'; if (!empty($count_similar)) { $similar_ids_array = ''; for ($i = 0; $i < $count_similar; $i++) { $similar_ids_array .= (empty($similar_ids_array) ? '' : ',') . $similar_topics[$i]['topic_id']; } } $sql = "UPDATE " . TOPICS_TABLE . " SET topic_similar_topics = '" . $similar_ids_array . "' WHERE topic_id = " . $topic_id; $result = $db->sql_query($sql); } return $similar_topics; }
} } if (!($result = $db->sql_query($sql))) { message_die(GENERAL_ERROR, 'Could not obtain matched posts list', '', __LINE__, __FILE__, $sql); } $search_ids = array(); while ($row = $db->sql_fetchrow($result)) { $search_ids[] = $row['post_id']; } $db->sql_freeresult($result); $total_match_count = count($search_ids); } else { if ($search_keywords != '') { $stopword_array = file('language/' . $board_config['default_lang'] . '/Forums/search_stopwords.txt'); $synonym_array = file('language/' . $board_config['default_lang'] . '/Forums/search_synonyms.txt'); $split_search = !strstr($multibyte_charset, $lang['ENCODING']) ? split_words(clean_words('search', $search_keywords, $stopword_array, $synonym_array), 'search') : split(' ', $search_keywords); $search_msg_only = !$search_fields ? "AND m.title_match = 0" : (strstr($multibyte_charset, $lang['ENCODING']) ? '' : ''); $word_count = 0; $current_match_type = 'or'; $word_match = array(); $result_list = array(); for ($i = 0; $i < count($split_search); $i++) { if (preg_match('#^[\\*%]+$#', trim($split_search[$i])) || preg_match('#^[^\\*]{1,2}$#', str_replace(array('*', '%'), '', trim($split_search[$i])))) { $split_search[$i] = ''; continue; } switch ($split_search[$i]) { case 'and': $current_match_type = 'and'; break; case 'or':
function add_search_words($mode, $post_id, $post_text, $post_title = '') { $stopword_array = @file("core/lib/phpbb/search_stopwords.txt"); $synonym_array = @file("core/lib/phpbb/search_synonyms.txt"); $search_raw_words = array(); $search_raw_words['text'] = split_words(clean_words('post', $post_text, $stopword_array, $synonym_array)); $search_raw_words['title'] = split_words(clean_words('post', $post_title, $stopword_array, $synonym_array)); @set_time_limit(0); $word = array(); $word_insert_sql = array(); while (list($word_in, $search_matches) = @each($search_raw_words)) { $word_insert_sql[$word_in] = ''; if (!empty($search_matches)) { for ($i = 0; $i < count($search_matches); $i++) { $search_matches[$i] = trim($search_matches[$i]); if ($search_matches[$i] != '') { $word[] = $search_matches[$i]; if (!strstr($word_insert_sql[$word_in], "'" . $search_matches[$i] . "'")) { $word_insert_sql[$word_in] .= $word_insert_sql[$word_in] != "" ? ", '" . $search_matches[$i] . "'" : "'" . $search_matches[$i] . "'"; } } } } } if (count($word)) { sort($word); $prev_word = ''; $word_text_sql = ''; $temp_word = array(); for ($i = 0; $i < count($word); $i++) { if ($word[$i] != $prev_word) { $temp_word[] = $word[$i]; $word_text_sql .= ($word_text_sql != '' ? ', ' : '') . "'" . $word[$i] . "'"; } $prev_word = $word[$i]; } $word = $temp_word; $check_words = array(); $value_sql = ''; $match_word = array(); for ($i = 0; $i < count($word); $i++) { $new_match = true; if (isset($check_words[$word[$i]])) { $new_match = false; } if ($new_match) { $value_sql .= ($value_sql != '' ? ', ' : '') . '(\'' . $word[$i] . '\', 0)'; } } if ($value_sql != '') { $sql = "INSERT IGNORE INTO `z_phpbb_search_wordlist` (word_text, word_common) \n VALUES {$value_sql}"; mysql_query($sql); } } while (list($word_in, $match_sql) = @each($word_insert_sql)) { $title_match = $word_in == 'title' ? 1 : 0; if ($match_sql != '') { $sql = "INSERT INTO z_phpbb_search_wordmatch (post_id, word_id, title_match) \n SELECT {$post_id}, word_id, {$title_match} \n FROM z_phpbb_search_wordlist \n WHERE word_text IN ({$match_sql})"; mysql_query($sql); } } if ($mode == 'single') { remove_common('single', 4 / 10, $word); } return; }
function update_search_index($mode, $post_id, $message, $subject = null) { global $db_type, $forum_db; $return = ($hook = get_hook('si_fn_update_search_index_start')) ? eval($hook) : null; if ($return != null) { return; } $message = utf8_strtolower($message); $subject = utf8_strtolower($subject); // Split old and new post/subject to obtain array of 'words' $words_message = split_words($message); $words_subject = empty($subject) ? array() : split_words($subject); if ($mode == 'edit') { $query = array('SELECT' => 'w.id, w.word, m.subject_match', 'FROM' => 'search_words AS w', 'JOINS' => array(array('INNER JOIN' => 'search_matches AS m', 'ON' => 'w.id=m.word_id')), 'WHERE' => 'm.post_id=' . $post_id); ($hook = get_hook('si_fn_update_search_index_qr_get_current_words')) ? eval($hook) : null; $result = $forum_db->query_build($query) or error(__FILE__, __LINE__); // Declare here to stop array_keys() and array_diff() from complaining if not set $cur_words = array('post' => array(), 'subject' => array()); while ($row = $forum_db->fetch_assoc($result)) { $cur_words[$row['subject_match'] == 1 ? 'subject' : 'post'][$row['word']] = $row['id']; } $forum_db->free_result($result); $words = array('add' => array('post' => array_diff($words_message, array_keys($cur_words['post'])), 'subject' => array_diff($words_subject, array_keys($cur_words['subject']))), 'del' => array('post' => array_diff(array_keys($cur_words['post']), $words_message), 'subject' => array_diff(array_keys($cur_words['subject']), $words_subject))); } else { $words = array('add' => array('post' => $words_message, 'subject' => $words_subject), 'del' => array('post' => array(), 'subject' => array())); } // Get unique words from the above arrays $unique_words = array_unique(array_merge($words['add']['post'], $words['add']['subject'])); if (!empty($unique_words)) { $query = array('SELECT' => 'id, word', 'FROM' => 'search_words', 'WHERE' => 'word IN(\'' . implode('\',\'', array_map(array($forum_db, 'escape'), $unique_words)) . '\')'); ($hook = get_hook('si_fn_update_search_index_qr_get_existing_words')) ? eval($hook) : null; $result = $forum_db->query_build($query) or error(__FILE__, __LINE__); $existing_words = array(); while ($row = $forum_db->fetch_row($result)) { $existing_words[] = $row[1]; } $forum_db->free_result($result); $new_words = array_diff($unique_words, $existing_words); if (!empty($new_words)) { $query = array('INSERT' => 'word', 'INTO' => 'search_words', 'VALUES' => preg_replace('#^(.*)$#', '\'\\1\'', array_map(array($forum_db, 'escape'), $new_words))); ($hook = get_hook('si_fn_update_search_index_qr_insert_words')) ? eval($hook) : null; $forum_db->query_build($query) or error(__FILE__, __LINE__); } } // Delete matches (only if editing a post) foreach ($words['del'] as $match_in => $wordlist) { if (!empty($wordlist)) { $word_ids = array(); foreach ($wordlist as $word) { $word_ids[] = $cur_words[$match_in][$word]; } $query = array('DELETE' => 'search_matches', 'WHERE' => 'word_id IN (' . implode(', ', $word_ids) . ') AND post_id=' . $post_id . ' AND subject_match=' . ($match_in == 'subject' ? '1' : '0')); ($hook = get_hook('si_fn_update_search_index_qr_delete_matches')) ? eval($hook) : null; $forum_db->query_build($query) or error(__FILE__, __LINE__); } } // Add new matches foreach ($words['add'] as $match_in => $wordlist) { if (!empty($wordlist)) { $subquery = array('SELECT' => $post_id . ', id, ' . ($match_in == 'subject' ? '1' : '0'), 'FROM' => 'search_words', 'WHERE' => 'word IN (\'' . implode('\',\'', array_map(array($forum_db, 'escape'), $wordlist)) . '\')'); // Really this should use the query builder too, though it doesn't currently support the syntax $sql = 'INSERT INTO ' . $forum_db->prefix . 'search_matches (post_id, word_id, subject_match) ' . $forum_db->query_build($subquery, true); ($hook = get_hook('si_fn_update_search_index_qr_add_matches')) ? eval($hook) : null; $forum_db->query($sql) or error(__FILE__, __LINE__); } } unset($words); }
function update_search_index($mode, $post_id, $message, $subject = null) { global $db; $message = utf8_strtolower($message); $subject = utf8_strtolower($subject); // Remove any bbcode that we shouldn't index $message = strip_bbcode($message); // Split old and new post/subject to obtain array of 'words' $words_message = split_words($message, true); $words_subject = $subject ? split_words($subject, true) : array(); if ($mode == 'edit') { $data = array(':id' => $post_id); $ps = $db->run('SELECT w.id, w.word, m.subject_match FROM ' . $db->prefix . 'search_words AS w INNER JOIN ' . $db->prefix . 'search_matches AS m ON w.id=m.word_id WHERE m.post_id=:id', $data); // Declare here to stop array_keys() and array_diff() from complaining if not set $cur_words['post'] = array(); $cur_words['subject'] = array(); foreach ($ps as $result) { $match_in = $result['subject_match'] ? 'subject' : 'post'; $cur_words[$match_in][$result['word']] = $result['id']; } $db->free_result($ps); $words['add']['post'] = array_diff($words_message, array_keys($cur_words['post'])); $words['add']['subject'] = array_diff($words_subject, array_keys($cur_words['subject'])); $words['del']['post'] = array_diff(array_keys($cur_words['post']), $words_message); $words['del']['subject'] = array_diff(array_keys($cur_words['subject']), $words_subject); } else { $words['add']['post'] = $words_message; $words['add']['subject'] = $words_subject; $words['del']['post'] = array(); $words['del']['subject'] = array(); } unset($words_message); unset($words_subject); // Get unique words from the above arrays $unique_words = array_unique(array_merge($words['add']['post'], $words['add']['subject'])); $data = $placeholders = array(); foreach ($unique_words as $word) { $placeholders[] = '?'; $data[] = $word; } if (!empty($unique_words)) { $ps = $db->run('SELECT id, word FROM ' . $db->prefix . 'search_words WHERE word IN(' . implode(',', $placeholders) . ')', array_values($data)); $word_ids = array(); foreach ($ps as $cur_row) { $word_ids[$cur_row['word']] = $cur_row['id']; } $db->free_result($ps); $new_words = array_diff($unique_words, array_keys($word_ids)); unset($unique_words); if (!empty($new_words)) { foreach ($new_words as $word) { $data = array('word' => $word); $db->insert('search_words', $data); } } unset($new_words); } // Delete matches (only if editing a post) foreach ($words['del'] as $match_in => $wordlist) { $placeholders = $data = array(); if (!empty($wordlist)) { foreach ($wordlist as $word) { $placeholders[] = '?'; $data[] = $cur_words[$match_in][$word]; } $data[] = $post_id; $data[] = $match_in == 'subject' ? 1 : 0; $db->run('DELETE FROM ' . $db->prefix . 'search_matches WHERE word_id IN(' . implode(',', $placeholders) . ') AND post_id=? AND subject_match=?', $data); } } // Add new matches foreach ($words['add'] as $match_in => $wordlist) { $placeholders = $data = array(); $subject_match = $match_in == 'subject' ? 1 : 0; foreach ($wordlist as $word) { $placeholders[] = '?'; $data[] = $word; } if (!empty($wordlist)) { $db->run('INSERT INTO ' . $db->prefix . 'search_matches (post_id, word_id, subject_match) SELECT ' . $post_id . ', id, ' . $subject_match . ' FROM ' . $db->prefix . 'search_words WHERE word IN(' . implode(',', $placeholders) . ')', $data); } } unset($words); }
public function get_search_results() { global $db_type, $lang_common, $lang_search; $search = array(); $action = $this->request->get('action') ? $this->request->get('action') : null; $forums = $this->request->get('forums') ? is_array($this->request->get('forums')) ? $this->request->get('forums') : array_filter(explode(',', $this->request->get('forums'))) : ($this->request->get('forums') ? array($this->request->get('forums')) : array()); $sort_dir = $this->request->get('sort_dir') && $this->request->get('sort_dir') == 'DESC' ? 'DESC' : 'ASC'; $forums = array_map('intval', $forums); // Allow the old action names for backwards compatibility reasons if ($action == 'show_user') { $action = 'show_user_posts'; } elseif ($action == 'show_24h') { $action = 'show_recent'; } // If a search_id was supplied if ($this->request->get('search_id')) { $search_id = intval($this->request->get('search_id')); if ($search_id < 1) { message($lang_common['Bad request'], '404'); } } elseif ($action == 'search') { $keywords = $this->request->get('keywords') ? utf8_strtolower(feather_trim($this->request->get('keywords'))) : null; $author = $this->request->get('author') ? utf8_strtolower(feather_trim($this->request->get('author'))) : null; if (preg_match('%^[\\*\\%]+$%', $keywords) || feather_strlen(str_replace(array('*', '%'), '', $keywords)) < FEATHER_SEARCH_MIN_WORD && !is_cjk($keywords)) { $keywords = ''; } if (preg_match('%^[\\*\\%]+$%', $author) || feather_strlen(str_replace(array('*', '%'), '', $author)) < 2) { $author = ''; } if (!$keywords && !$author) { message($lang_search['No terms']); } if ($author) { $author = str_replace('*', '%', $author); } $show_as = $this->request->get('show_as') && $this->request->get('show_as') == 'topics' ? 'topics' : 'posts'; $sort_by = $this->request->get('sort_by') ? intval($this->request->get('sort_by')) : 0; $search_in = !$this->request->get('search_in') || $this->request->get('search_in') == '0' ? 0 : ($this->request->get('search_in') == '1' ? 1 : -1); } elseif ($action == 'show_user_posts' || $action == 'show_user_topics' || $action == 'show_subscriptions') { $user_id = $this->request->get('user_id') ? intval($this->request->get('user_id')) : $this->user->id; if ($user_id < 2) { message($lang_common['Bad request'], '404'); } // Subscribed topics can only be viewed by admins, moderators and the users themselves if ($action == 'show_subscriptions' && !$this->user->is_admmod && $user_id != $this->user->id) { message($lang_common['No permission'], '403'); } } elseif ($action == 'show_recent') { $interval = $this->request->get('value') ? intval($this->request->get('value')) : 86400; } elseif ($action == 'show_replies') { if ($this->user->is_guest) { message($lang_common['Bad request'], '404'); } } elseif ($action != 'show_new' && $action != 'show_unanswered') { message($lang_common['Bad request'], '404'); } // If a valid search_id was supplied we attempt to fetch the search results from the db if (isset($search_id)) { $ident = $this->user->is_guest ? get_remote_address() : $this->user->username; $search_data = DB::for_table('search_cache')->where('id', $search_id)->where('ident', $ident)->find_one_col('search_data'); if ($search_data) { $temp = unserialize($search_data); $search_ids = unserialize($temp['search_ids']); $num_hits = $temp['num_hits']; $sort_by = $temp['sort_by']; $sort_dir = $temp['sort_dir']; $show_as = $temp['show_as']; $search_type = $temp['search_type']; unset($temp); } else { message($lang_search['No hits']); } } else { $keyword_results = $author_results = array(); // Search a specific forum? $forum_sql = !empty($forums) || empty($forums) && $this->config['o_search_all_forums'] == '0' && !$this->user->is_admmod ? ' AND t.forum_id IN (' . implode(',', $forums) . ')' : ''; if (!empty($author) || !empty($keywords)) { // Flood protection if ($this->user->last_search && time() - $this->user->last_search < $this->user->g_search_flood && time() - $this->user->last_search >= 0) { message(sprintf($lang_search['Search flood'], $this->user->g_search_flood, $this->user->g_search_flood - (time() - $this->user->last_search))); } if (!$this->user->is_guest) { DB::for_table('users')->where('id', $this->user->id)->update_many('last_search', time()); } else { DB::for_table('online')->where('ident', get_remote_address())->update_many('last_search', time()); } switch ($sort_by) { case 1: $sort_by_sql = $show_as == 'topics' ? 't.poster' : 'p.poster'; $sort_type = SORT_STRING; break; case 2: $sort_by_sql = 't.subject'; $sort_type = SORT_STRING; break; case 3: $sort_by_sql = 't.forum_id'; $sort_type = SORT_NUMERIC; break; case 4: $sort_by_sql = 't.last_post'; $sort_type = SORT_NUMERIC; break; default: $sort_by_sql = $show_as == 'topics' ? 't.last_post' : 'p.posted'; $sort_type = SORT_NUMERIC; break; } // If it's a search for keywords if ($keywords) { // split the keywords into words $keywords_array = split_words($keywords, false); if (empty($keywords_array)) { message($lang_search['No hits']); } // Should we search in message body or topic subject specifically? $search_in_cond = $search_in ? $search_in > 0 ? ' AND m.subject_match = 0' : ' AND m.subject_match = 1' : ''; $word_count = 0; $match_type = 'and'; $sort_data = array(); foreach ($keywords_array as $cur_word) { switch ($cur_word) { case 'and': case 'or': case 'not': $match_type = $cur_word; break; default: if (is_cjk($cur_word)) { $where_cond = str_replace('*', '%', $cur_word); $where_cond_cjk = $search_in ? $search_in > 0 ? 'p.message LIKE %:where_cond%' : 't.subject LIKE %:where_cond%' : 'p.message LIKE %:where_cond% OR t.subject LIKE %:where_cond%'; $result = DB::for_table('posts')->raw_query('SELECT p.id AS post_id, p.topic_id, ' . $sort_by_sql . ' AS sort_by FROM ' . $this->feather->prefix . 'posts AS p INNER JOIN ' . $this->feather->prefix . 'topics AS t ON t.id=p.topic_id LEFT JOIN ' . $this->feather->prefix . 'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id=' . $this->user->g_id . ') WHERE (' . $where_cond_cjk . ') AND (fp.read_forum IS NULL OR fp.read_forum=1)' . $forum_sql, array(':where_cond' => $where_cond))->find_many(); } else { $result = DB::for_table('posts')->raw_query('SELECT m.post_id, p.topic_id, ' . $sort_by_sql . ' AS sort_by FROM ' . $this->feather->prefix . 'search_words AS w INNER JOIN ' . $this->feather->prefix . 'search_matches AS m ON m.word_id = w.id INNER JOIN ' . $this->feather->prefix . 'posts AS p ON p.id=m.post_id INNER JOIN ' . $this->feather->prefix . 'topics AS t ON t.id=p.topic_id LEFT JOIN ' . $this->feather->prefix . 'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id=' . $this->user->g_id . ') WHERE w.word LIKE :where_cond' . $search_in_cond . ' AND (fp.read_forum IS NULL OR fp.read_forum=1)' . $forum_sql, array(':where_cond' => str_replace('*', '%', $cur_word)))->find_many(); } $row = array(); foreach ($result as $temp) { $row[$temp['post_id']] = $temp['topic_id']; if (!$word_count) { $keyword_results[$temp['post_id']] = $temp['topic_id']; $sort_data[$temp['post_id']] = $temp['sort_by']; } elseif ($match_type == 'or') { $keyword_results[$temp['post_id']] = $temp['topic_id']; $sort_data[$temp['post_id']] = $temp['sort_by']; } elseif ($match_type == 'not') { unset($keyword_results[$temp['post_id']]); unset($sort_data[$temp['post_id']]); } } if ($match_type == 'and' && $word_count) { foreach ($keyword_results as $post_id => $topic_id) { if (!isset($row[$post_id])) { unset($keyword_results[$post_id]); unset($sort_data[$post_id]); } } } ++$word_count; $pdo = DB::get_db(); $pdo = null; break; } } // Sort the results - annoyingly array_multisort re-indexes arrays with numeric keys, so we need to split the keys out into a separate array then combine them again after $post_ids = array_keys($keyword_results); $topic_ids = array_values($keyword_results); array_multisort(array_values($sort_data), $sort_dir == 'DESC' ? SORT_DESC : SORT_ASC, $sort_type, $post_ids, $topic_ids); // combine the arrays back into a key=>value array (array_combine is PHP5 only unfortunately) $num_results = count($keyword_results); $keyword_results = array(); for ($i = 0; $i < $num_results; $i++) { $keyword_results[$post_ids[$i]] = $topic_ids[$i]; } unset($sort_data, $post_ids, $topic_ids); } // If it's a search for author name (and that author name isn't Guest) if ($author && $author != 'guest' && $author != utf8_strtolower($lang_common['Guest'])) { $username_exists = DB::for_table('users')->select('id')->where_like('username', $author)->find_many(); if ($username_exists) { $user_ids = array(); foreach ($username_exists as $row) { $user_ids[] = $row['id']; } $result = DB::for_table('posts')->raw_query('SELECT p.id AS post_id, p.topic_id FROM ' . $this->feather->prefix . 'posts AS p INNER JOIN ' . $this->feather->prefix . 'topics AS t ON t.id=p.topic_id LEFT JOIN ' . $this->feather->prefix . 'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id=' . $this->user->g_id . ') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.poster_id IN(' . implode(',', $user_ids) . ')' . $forum_sql . ' ORDER BY ' . $sort_by_sql . ' ' . $sort_dir)->find_many(); foreach ($result as $temp) { $author_results[$temp['post_id']] = $temp['topic_id']; } $pdo = DB::get_db(); $pdo = null; } } // If we searched for both keywords and author name we want the intersection between the results if ($author && $keywords) { $search_ids = array_intersect_assoc($keyword_results, $author_results); $search_type = array('both', array($keywords, feather_trim($this->request->get('author'))), implode(',', $forums), $search_in); } elseif ($keywords) { $search_ids = $keyword_results; $search_type = array('keywords', $keywords, implode(',', $forums), $search_in); } else { $search_ids = $author_results; $search_type = array('author', feather_trim($this->request->get('author')), implode(',', $forums), $search_in); } unset($keyword_results, $author_results); if ($show_as == 'topics') { $search_ids = array_values($search_ids); } else { $search_ids = array_keys($search_ids); } $search_ids = array_unique($search_ids); $num_hits = count($search_ids); if (!$num_hits) { message($lang_search['No hits']); } } elseif ($action == 'show_new' || $action == 'show_recent' || $action == 'show_replies' || $action == 'show_user_posts' || $action == 'show_user_topics' || $action == 'show_subscriptions' || $action == 'show_unanswered') { $search_type = array('action', $action); $show_as = 'topics'; // We want to sort things after last post $sort_by = 0; $sort_dir = 'DESC'; $where_search_action = array(array('fp.read_forum' => 'IS NULL'), array('fp.read_forum' => '1')); // If it's a search for new posts since last visit if ($action == 'show_new') { if ($this->user->is_guest) { message($lang_common['No permission'], '403'); } $result = DB::for_table('topics')->table_alias('t')->select('t.id')->left_outer_join('forum_perms', array('fp.forum_id', '=', 't.forum_id'), 'fp')->left_outer_join('forum_perms', array('fp.group_id', '=', $this->user->g_id), null, true)->where_any_is($where_search_action)->where_gt('t.last_post', $this->user->last_visit)->where_null('t.moved_to')->order_by_desc('t.last_post'); if ($this->request->get('fid')) { $result = $result->where('t.forum_id', intval($this->request->get('fid'))); } $result = $result->find_many(); $num_hits = count($result); if (!$num_hits) { message($lang_search['No new posts']); } } elseif ($action == 'show_recent') { $result = DB::for_table('topics')->table_alias('t')->select('t.id')->left_outer_join('forum_perms', array('fp.forum_id', '=', 't.forum_id'), 'fp')->left_outer_join('forum_perms', array('fp.group_id', '=', $this->user->g_id), null, true)->where_any_is($where_search_action)->where_gt('t.last_post', time() - $interval)->where_null('t.moved_to')->order_by_desc('t.last_post'); if ($this->request->get('fid')) { $result = $result->where('t.forum_id', intval($this->request->get('fid'))); } $result = $result->find_many(); $num_hits = count($result); if (!$num_hits) { message($lang_search['No recent posts']); } } elseif ($action == 'show_replies') { $result = DB::for_table('topics')->table_alias('t')->select('t.id')->inner_join('posts', array('t.id', '=', 'p.topic_id'), 'p')->left_outer_join('forum_perms', array('fp.forum_id', '=', 't.forum_id'), 'fp')->left_outer_join('forum_perms', array('fp.group_id', '=', $this->user->g_id), null, true)->where_any_is($where_search_action)->where('p.poster_id', $this->user->id)->group_by('t.id'); if ($db_type == 'pgsql') { $result = $result->group_by('t.last_post'); } $result = $result->find_many(); $num_hits = count($result); if (!$num_hits) { message($lang_search['No user posts']); } } elseif ($action == 'show_user_posts') { $show_as = 'posts'; $result = DB::for_table('posts')->table_alias('p')->select('p.id')->inner_join('topics', array('p.topic_id', '=', 't.id'), 't')->left_outer_join('forum_perms', array('fp.forum_id', '=', 't.forum_id'), 'fp')->left_outer_join('forum_perms', array('fp.group_id', '=', $this->user->g_id), null, true)->where_any_is($where_search_action)->where('p.poster_id', $user_id)->order_by_desc('p.posted'); $result = $result->find_many(); $num_hits = count($result); if (!$num_hits) { message($lang_search['No user posts']); } // Pass on the user ID so that we can later know whose posts we're searching for $search_type[2] = $user_id; } elseif ($action == 'show_user_topics') { $result = DB::for_table('topics')->table_alias('t')->select('t.id')->inner_join('posts', array('t.first_post_id', '=', 'p.id'), 'p')->left_outer_join('forum_perms', array('fp.forum_id', '=', 't.forum_id'), 'fp')->left_outer_join('forum_perms', array('fp.group_id', '=', $this->user->g_id), null, true)->where_any_is($where_search_action)->where('p.poster_id', $user_id)->order_by_desc('t.last_post'); $result = $result->find_many(); $num_hits = count($result); if (!$num_hits) { message($lang_search['No user topics']); } // Pass on the user ID so that we can later know whose topics we're searching for $search_type[2] = $user_id; } elseif ($action == 'show_subscriptions') { if ($this->user->is_guest) { message($lang_common['Bad request'], '404'); } $result = DB::for_table('topics')->table_alias('t')->select('t.id')->inner_join('topic_subscriptions', array('t.id', '=', 's.topic_id'), 's')->inner_join('topic_subscriptions', array('s.user_id', '=', $user_id), null, true)->left_outer_join('forum_perms', array('fp.forum_id', '=', 't.forum_id'), 'fp')->left_outer_join('forum_perms', array('fp.group_id', '=', $this->user->g_id), null, true)->where_any_is($where_search_action)->order_by_desc('t.last_post'); $result = $result->find_many(); $num_hits = count($result); if (!$num_hits) { message($lang_search['No subscriptions']); } // Pass on user ID so that we can later know whose subscriptions we're searching for $search_type[2] = $user_id; } else { $result = DB::for_table('topics')->table_alias('t')->select('t.id')->left_outer_join('forum_perms', array('fp.forum_id', '=', 't.forum_id'), 'fp')->left_outer_join('forum_perms', array('fp.group_id', '=', $this->user->g_id), null, true)->where('t.num_replies', 0)->where_null('t.moved_to')->where_any_is($where_search_action)->order_by_desc('t.last_post'); $result = $result->find_many(); $num_hits = count($result); if (!$num_hits) { message($lang_search['No unanswered']); } } $search_ids = array(); foreach ($result as $row) { $search_ids[] = $row['id']; } $pdo = DB::get_db(); $pdo = null; } else { message($lang_common['Bad request'], '404'); } // Prune "old" search results $old_searches = array(); $result = DB::for_table('online')->select('ident')->find_many(); if ($result) { foreach ($result as $row) { $old_searches[] = $row['ident']; } DB::for_table('search_cache')->where_not_in('ident', $old_searches)->delete_many(); } // Fill an array with our results and search properties $temp = serialize(array('search_ids' => serialize($search_ids), 'num_hits' => $num_hits, 'sort_by' => $sort_by, 'sort_dir' => $sort_dir, 'show_as' => $show_as, 'search_type' => $search_type)); $search_id = mt_rand(1, 2147483647); $ident = $this->user->is_guest ? get_remote_address() : $this->user->username; $insert_cache = array('id' => $search_id, 'ident' => $ident, 'search_data' => $temp); DB::for_table('search_cache')->create()->set($insert_cache)->save(); if ($search_type[0] != 'action') { $this->db->end_transaction(); $this->db->close(); // Redirect the user to the cached result page header('Location: ' . get_link('search/?search_id=' . $search_id)); exit; } } // If we're on the new posts search, display a "mark all as read" link if (!$this->user->is_guest && $search_type[0] == 'action' && $search_type[1] == 'show_new') { $search['forum_actions'][] = '<a href="' . get_link('mark-read/') . '">' . $lang_common['Mark all as read'] . '</a>'; } // Fetch results to display if (!empty($search_ids)) { // We have results $search['is_result'] = true; switch ($sort_by) { case 1: $sort_by_sql = $show_as == 'topics' ? 't.poster' : 'p.poster'; break; case 2: $sort_by_sql = 't.subject'; break; case 3: $sort_by_sql = 't.forum_id'; break; default: $sort_by_sql = $show_as == 'topics' ? 't.last_post' : 'p.posted'; break; } // Determine the topic or post offset (based on $_GET['p']) $per_page = $show_as == 'posts' ? $this->user->disp_posts : $this->user->disp_topics; $num_pages = ceil($num_hits / $per_page); $p = !$this->request->get('p') || $this->request->get('p') <= 1 || $this->request->get('p') > $num_pages ? 1 : intval($this->request->get('p')); $start_from = $per_page * ($p - 1); $search['start_from'] = $start_from; // Generate paging links $search['paging_links'] = '<span class="pages-label">' . $lang_common['Pages'] . ' </span>' . paginate_old($num_pages, $p, '?search_id=' . $search_id); // throw away the first $start_from of $search_ids, only keep the top $per_page of $search_ids $search_ids = array_slice($search_ids, $start_from, $per_page); // Run the query and fetch the results if ($show_as == 'posts') { $select_search_post = array('pid' => 'p.id', 'pposter' => 'p.poster', 'pposted' => 'p.posted', 'p.poster_id', 'p.message', 'p.hide_smilies', 'tid' => 't.id', 't.poster', 't.subject', 't.first_post_id', 't.last_post', 't.last_post_id', 't.last_poster', 't.num_replies', 't.forum_id', 'f.forum_name'); $result = DB::for_table('posts')->table_alias('p')->select_many($select_search_post)->inner_join('topics', array('t.id', '=', 'p.topic_id'), 't')->inner_join('forums', array('f.id', '=', 't.forum_id'), 'f')->where_in('p.id', $search_ids)->order_by($sort_by_sql, $sort_dir)->find_many(); } else { $select_search_topic = array('tid' => 't.id', 't.poster', 't.subject', 't.last_post', 't.last_post_id', 't.last_poster', 't.num_replies', 't.closed', 't.sticky', 't.forum_id', 'f.forum_name'); $result = DB::for_table('topics')->table_alias('t')->select_many($select_search_topic)->inner_join('forums', array('f.id', '=', 't.forum_id'), 'f')->where_in('t.id', $search_ids)->order_by($sort_by_sql, $sort_dir)->find_many(); } $search['search_set'] = array(); foreach ($result as $row) { $search['search_set'][] = $row; } $search['crumbs_text']['show_as'] = $lang_search['Search']; if ($search_type[0] == 'action') { if ($search_type[1] == 'show_user_topics') { $search['crumbs_text']['search_type'] = '<a href="' . get_link('search/?action=show_user_topics&user_id=' . $search_type[2]) . '">' . sprintf($lang_search['Quick search show_user_topics'], feather_escape($search['search_set'][0]['poster'])) . '</a>'; } elseif ($search_type[1] == 'show_user_posts') { $search['crumbs_text']['search_type'] = '<a href="' . get_link('search/?action=show_user_posts&user_id=' . $search_type[2]) . '">' . sprintf($lang_search['Quick search show_user_posts'], feather_escape($search['search_set'][0]['pposter'])) . '</a>'; } elseif ($search_type[1] == 'show_subscriptions') { // Fetch username of subscriber $subscriber_id = $search_type[2]; $subscriber_name = DB::for_table('users')->where('id', $subscriber_id)->find_one_col('username'); if (!$subscriber_name) { message($lang_common['Bad request'], '404'); } $search['crumbs_text']['search_type'] = '<a href="' . get_link('search/?action=show_subscription&user_id=' . $subscriber_id) . '">' . sprintf($lang_search['Quick search show_subscriptions'], feather_escape($subscriber_name)) . '</a>'; } else { $search_url = str_replace('_', '/', $search_type[1]); $search['crumbs_text']['search_type'] = '<a href="' . get_link('search/' . $search_url . '/') . '">' . $lang_search['Quick search ' . $search_type[1]] . '</a>'; } } else { $keywords = $author = ''; if ($search_type[0] == 'both') { list($keywords, $author) = $search_type[1]; $search['crumbs_text']['search_type'] = sprintf($lang_search['By both show as ' . $show_as], feather_escape($keywords), feather_escape($author)); } elseif ($search_type[0] == 'keywords') { $keywords = $search_type[1]; $search['crumbs_text']['search_type'] = sprintf($lang_search['By keywords show as ' . $show_as], feather_escape($keywords)); } elseif ($search_type[0] == 'author') { $author = $search_type[1]; $search['crumbs_text']['search_type'] = sprintf($lang_search['By user show as ' . $show_as], feather_escape($author)); } $search['crumbs_text']['search_type'] = '<a href="' . get_link('search/?action=search&keywords=' . urlencode($keywords) . '&author=' . urlencode($author) . '&forums=' . $search_type[2] . '&search_in=' . $search_type[3] . '&sort_by=' . $sort_by . '&sort_dir=' . $sort_dir . '&show_as=' . $show_as) . '">' . $search['crumbs_text']['search_type'] . '</a>'; } } $search['show_as'] = $show_as; return $search; }
if (!($result = $db->sql_query($sql))) { message_die(GENERAL_ERROR, 'Could not obtain matched posts list', '', __LINE__, __FILE__, $sql); } $search_ids = array(); while ($row = $db->sql_fetchrow($result)) { $search_ids[] = $row['post_id']; } $db->sql_freeresult($result); $total_match_count = count($search_ids); } else { if ($search_keywords != '') { $stopword_array = @file($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . '/search_stopwords.txt'); $synonym_array = @file($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . '/search_synonyms.txt'); $split_search = array(); $cleaned_search = clean_words('search', stripslashes($search_keywords), $stopword_array, $synonym_array); $split_search = split_words($cleaned_search, 'search'); $search_msg_only = !$search_fields ? "AND m.title_match = 0" : ''; $word_count = 0; $current_match_type = 'or'; $word_match = array(); $result_list = array(); for ($i = 0; $i < count($split_search); $i++) { switch ($split_search[$i]) { case 'and': $current_match_type = 'and'; break; case 'or': $current_match_type = 'or'; break; case 'not': $current_match_type = 'not';
$result_array = array(array(), array(), array()); $i = 0; while ($row && ($post_size <= $board_config['dbmtnc_rebuildcfg_maxmemory'] * 1024 || $i < $board_config['dbmtnc_rebuildcfg_minposts'])) { $last_post = $row['post_id']; // handle text $word_list = split_words(clean_words('post', $row['post_text'], $empty_array, $empty_array)); foreach ($word_list as $word) { // cutting of long words in functions_search.php seems not to work under some conditions - so check it again if ($word != '' && strlen($word) <= 20) { $result_array[0][] = $last_post; $result_array[1][] = 0; $result_array[2][] = $word; } } // handle subject $word_list = split_words(clean_words('post', $row['post_subject'], $empty_array, $empty_array)); foreach ($word_list as $word) { // cutting of long words in functions_search.php seems not to work under some conditions - so check it again if ($word != '' && strlen($word) <= 20) { $result_array[0][] = $last_post; $result_array[1][] = 1; $result_array[2][] = $word; } } unset($word_list); $row = $db->sql_fetchrow($result); $i++; $post_size += strlen($row['post_text']) + strlen($row['post_subject']); } // sort array array_multisort($result_array[2], SORT_ASC, SORT_STRING, $result_array[0], SORT_ASC, SORT_NUMERIC, $result_array[1]);
function update_search_index($mode, $post_id, $message, $subject = null) { global $db; // Split old and new post/subject to obtain array of 'words' $words_message = split_words($message); $words_subject = $subject ? split_words($subject) : array(); if ($mode == 'edit') { $result = $db->query('SELECT w.id, w.word, m.subject_match FROM ' . $db->prefix . 'search_words AS w INNER JOIN ' . $db->prefix . 'search_matches AS m ON w.id=m.word_id WHERE m.post_id=' . $post_id) or error('Unable to fetch search index words', __FILE__, __LINE__, $db->error()); // Declare here to stop array_keys() and array_diff() from complaining if not set $cur_words['post'] = array(); $cur_words['subject'] = array(); while ($row = $db->fetch_row($result)) { $match_in = $row[2] ? 'subject' : 'post'; $cur_words[$match_in][$row[1]] = $row[0]; } $db->free_result($result); $words['add']['post'] = array_diff($words_message, array_keys($cur_words['post'])); $words['add']['subject'] = array_diff($words_subject, array_keys($cur_words['subject'])); $words['del']['post'] = array_diff(array_keys($cur_words['post']), $words_message); $words['del']['subject'] = array_diff(array_keys($cur_words['subject']), $words_subject); } else { $words['add']['post'] = $words_message; $words['add']['subject'] = $words_subject; $words['del']['post'] = array(); $words['del']['subject'] = array(); } unset($words_message); unset($words_subject); // Get unique words from the above arrays $unique_words = array_unique(array_merge($words['add']['post'], $words['add']['subject'])); if ($unique_words) { $result = $db->query('SELECT id, word FROM ' . $db->prefix . 'search_words WHERE word IN(' . implode(',', preg_replace('#^(.*)$#u', '\'\\1\'', $unique_words)) . ')') or error('Unable to fetch search index words', __FILE__, __LINE__, $db->error()); $word_ids = array(); while ($row = $db->fetch_row($result)) { $word_ids[$row[1]] = $row[0]; } $db->free_result($result); $new_words = array_unique(array_diff($unique_words, array_keys($word_ids))); unset($unique_words); if ($new_words) { $db->query('INSERT INTO ' . $db->prefix . 'search_words (word) VALUES' . implode(',', preg_replace('#^(.*)$#u', '(\'\\1\')', $new_words))) or error('Unable to insert search index words', __FILE__, __LINE__, $db->error()); } unset($new_words); } // Delete matches (only if editing a post) while (list($match_in, $wordlist) = @each($words['del'])) { $subject_match = $match_in == 'subject' ? 1 : 0; if ($wordlist) { $sql = null; while (list(, $word) = @each($wordlist)) { $sql .= ($sql ? ',' : '') . $cur_words[$match_in][$word]; } $db->query('DELETE FROM ' . $db->prefix . 'search_matches WHERE word_id IN(' . $sql . ') AND post_id=' . $post_id . ' AND subject_match=' . $subject_match) or error('Unable to delete search index word matches', __FILE__, __LINE__, $db->error()); } } // Add new matches while (list($match_in, $wordlist) = @each($words['add'])) { $subject_match = $match_in == 'subject' ? 1 : 0; if ($wordlist) { $db->query('INSERT INTO ' . $db->prefix . 'search_matches (post_id, word_id, subject_match) SELECT ' . $post_id . ', id, ' . $subject_match . ' FROM ' . $db->prefix . 'search_words WHERE word IN(' . implode(',', preg_replace('#^(.*)$#', '\'\\1\'', $wordlist)) . ')') or error('Unable to insert search index word matches', __FILE__, __LINE__, $db->error()); } } unset($words); }
function update_search_index($mode, $post_id, $message, $subject = null) { global $db_type, $db; $message = utf8_strtolower($message); $subject = utf8_strtolower($subject); // Remove any bbcode that we shouldn't index $message = strip_bbcode($message); // Split old and new post/subject to obtain array of 'words' $words_message = split_words($message, true); $words_subject = $subject ? split_words($subject, true) : array(); if ($mode == 'edit') { // Declare here to stop array_keys() and array_diff() from complaining if not set $cur_words = array('post' => array(), 'subject' => array()); $query = $db->select(array('wid' => 'w.id', 'word' => 'w.word', 'subject_match' => 'm.subject_match'), 'search_words AS w'); $query->innerJoin('m', 'search_matches AS m', 'w.id = m.word_id'); $query->where = 'm.post_id = :post_id'; $params = array(':post_id' => $post_id); $result = $query->run($params); foreach ($result as $cur_word) { $match_in = $cur_word['subject_match'] ? 'subject' : 'post'; $cur_words[$match_in][$cur_word['word']] = $cur_word['id']; } unset($query, $params, $result); $words['add']['post'] = array_diff($words_message, array_keys($cur_words['post'])); $words['add']['subject'] = array_diff($words_subject, array_keys($cur_words['subject'])); $words['del']['post'] = array_diff(array_keys($cur_words['post']), $words_message); $words['del']['subject'] = array_diff(array_keys($cur_words['subject']), $words_subject); } else { $words['add']['post'] = $words_message; $words['add']['subject'] = $words_subject; $words['del']['post'] = array(); $words['del']['subject'] = array(); } unset($words_message); unset($words_subject); // Get unique words from the above arrays $unique_words = array_unique(array_merge($words['add']['post'], $words['add']['subject'])); if (!empty($unique_words)) { $word_ids = array(); $query = $db->select(array('id' => 'w.id', 'word' => 'w.word'), 'search_words AS w'); $query->where = 'w.word IN :words'; $params = array(':words' => $unique_words); $result = $query->run($params); foreach ($result as $cur_word) { $word_ids[$cur_word['word']] = $cur_word['id']; } unset($result, $query, $params); $new_words = array_diff($unique_words, array_keys($word_ids)); unset($unique_words); if (!empty($new_words)) { $insert_query = $db->insert(array('word' => ':word'), 'search_words'); foreach ($new_words as $cur_word) { $params = array(':word' => $cur_word); $insert_query->run($params); unset($params); } unset($insert_query); } unset($new_words); } $delete_query = $db->delete('search_matches'); $delete_query->where = 'word_id IN :wids AND post_id = :post_id AND subject_match = :subject_match'; // Delete matches (only if editing a post) foreach ($words['del'] as $match_in => $wordlist) { $subject_match = $match_in == 'subject' ? 1 : 0; if (!empty($wordlist)) { $word_ids = array(); foreach ($wordlist as $cur_word) { $word_ids[] = $cur_words[$match_in][$cur_word]; } $params = array(':wids' => $word_ids, ':post_id' => $post_id, ':subject_match' => $subject_match); $delete_query->run($params); unset($params); } } unset($delete_query); // Add new matches foreach ($words['add'] as $match_in => $wordlist) { $subject_match = $match_in == 'subject' ? 1 : 0; if (!empty($wordlist)) { $db->query('INSERT INTO ' . $db->prefix . 'search_matches (post_id, word_id, subject_match) SELECT ' . $post_id . ', id, ' . $subject_match . ' FROM ' . $db->prefix . 'search_words WHERE word IN(' . implode(',', array_map(array($db, 'quote'), $wordlist)) . ')') or error('Unable to insert search index word matches', __FILE__, __LINE__, $db->error()); } } unset($words); }
function update_search_index($mode, $post_id, $message, $subject = null) { global $db_type, $db; $message = utf8_strtolower($message); $subject = utf8_strtolower($subject); // Remove any bbcode that we shouldn't index $message = strip_bbcode($message); // Split old and new post/subject to obtain array of 'words' $words_message = split_words($message, true); $words_subject = $subject ? split_words($subject, true) : array(); if ($mode == 'edit') { $result = $db->query('SELECT w.id, w.word, m.subject_match FROM ' . $db->prefix . 'search_words AS w INNER JOIN ' . $db->prefix . 'search_matches AS m ON w.id=m.word_id WHERE m.post_id=' . $post_id, true) or error('Unable to fetch search index words', __FILE__, __LINE__, $db->error()); // Declare here to stop array_keys() and array_diff() from complaining if not set $cur_words['post'] = array(); $cur_words['subject'] = array(); while ($row = $db->fetch_row($result)) { $match_in = $row[2] ? 'subject' : 'post'; $cur_words[$match_in][$row[1]] = $row[0]; } $db->free_result($result); $words['add']['post'] = array_diff($words_message, array_keys($cur_words['post'])); $words['add']['subject'] = array_diff($words_subject, array_keys($cur_words['subject'])); $words['del']['post'] = array_diff(array_keys($cur_words['post']), $words_message); $words['del']['subject'] = array_diff(array_keys($cur_words['subject']), $words_subject); } else { $words['add']['post'] = $words_message; $words['add']['subject'] = $words_subject; $words['del']['post'] = array(); $words['del']['subject'] = array(); } unset($words_message); unset($words_subject); // Get unique words from the above arrays $unique_words = array_unique(array_merge($words['add']['post'], $words['add']['subject'])); if (!empty($unique_words)) { $result = $db->query('SELECT id, word FROM ' . $db->prefix . 'search_words WHERE word IN(\'' . implode('\',\'', array_map(array($db, 'escape'), $unique_words)) . '\')', true) or error('Unable to fetch search index words', __FILE__, __LINE__, $db->error()); $word_ids = array(); while ($row = $db->fetch_row($result)) { $word_ids[$row[1]] = $row[0]; } $db->free_result($result); $new_words = array_diff($unique_words, array_keys($word_ids)); unset($unique_words); if (!empty($new_words)) { switch ($db_type) { case 'mysql': case 'mysqli': case 'mysql_innodb': case 'mysqli_innodb': $db->query('INSERT INTO ' . $db->prefix . 'search_words (word) VALUES(\'' . implode('\'),(\'', array_map(array($db, 'escape'), $new_words)) . '\')'); break; default: foreach ($new_words as $word) { $db->query('INSERT INTO ' . $db->prefix . 'search_words (word) VALUES(\'' . $db->escape($word) . '\')'); } break; } } unset($new_words); } // Delete matches (only if editing a post) foreach ($words['del'] as $match_in => $wordlist) { $subject_match = $match_in == 'subject' ? 1 : 0; if (!empty($wordlist)) { $sql = ''; foreach ($wordlist as $word) { $sql .= ($sql != '' ? ',' : '') . $cur_words[$match_in][$word]; } $db->query('DELETE FROM ' . $db->prefix . 'search_matches WHERE word_id IN(' . $sql . ') AND post_id=' . $post_id . ' AND subject_match=' . $subject_match) or error('Unable to delete search index word matches', __FILE__, __LINE__, $db->error()); } } // Add new matches foreach ($words['add'] as $match_in => $wordlist) { $subject_match = $match_in == 'subject' ? 1 : 0; if (!empty($wordlist)) { $db->query('INSERT INTO ' . $db->prefix . 'search_matches (post_id, word_id, subject_match) SELECT ' . $post_id . ', id, ' . $subject_match . ' FROM ' . $db->prefix . 'search_words WHERE word IN(\'' . implode('\',\'', array_map(array($db, 'escape'), $wordlist)) . '\')') or error('Unable to insert search index word matches', __FILE__, __LINE__, $db->error()); } } unset($words); }
<?php if (!defined("WIKINI_VERSION")) { die("accès direct interdit"); } include_once "tools/tags/libs/tags.functions.php"; //mot clés utilisés d'office $tags = $this->GetParameter('tags'); $tagsvirgule = implode(',', split_words($tags)); //mot clés cachés d'office $notags = $this->GetParameter('notags'); //peut on éditer les pages? $lienedit = $this->GetParameter('edit'); $titrerss = $this->GetParameter('titrerss'); //classe CSS associée $class = $this->GetParameter('class'); if (empty($class)) { $class = 'microblog'; } //template billets microblog $vue = $this->GetParameter('vue'); if (empty($vue)) { $vue = 'bulle_microblog.tpl.html'; } //formulaire de microblog au dessus ou en dessous $enhaut = $this->GetParameter('enhaut'); if (empty($enhaut)) { $enhaut = "oui"; } //formulaire microblog seul ou avec la liste des billets? $afficher = $this->GetParameter('afficher');
function add_search_words($mode, $post_id, $post_text, $post_title = '') { global $db, $config, $lang; global $stopwords_array, $synonyms_array; stopwords_synonyms_init(); $search_raw_words = array(); $search_raw_words['text'] = split_words(clean_words('post', $post_text, $stopwords_array, $synonyms_array)); $search_raw_words['title'] = split_words(clean_words('post', $post_title, $stopwords_array, $synonyms_array)); @set_time_limit(0); $word = array(); $word_insert_sql = array(); while (list($word_in, $search_matches) = @each($search_raw_words)) { $word_insert_sql[$word_in] = ''; if (!empty($search_matches)) { for ($i = 0; $i < sizeof($search_matches); $i++) { $search_matches[$i] = trim($search_matches[$i]); if ($search_matches[$i] != '') { $word[] = $search_matches[$i]; if (!strstr($word_insert_sql[$word_in], "'" . $search_matches[$i] . "'")) { $word_insert_sql[$word_in] .= $word_insert_sql[$word_in] != "" ? ", '" . $search_matches[$i] . "'" : "'" . $search_matches[$i] . "'"; } } } } } if (sizeof($word)) { sort($word); $prev_word = ''; $word_text_sql = ''; $temp_word = array(); for ($i = 0; $i < sizeof($word); $i++) { if ($word[$i] != $prev_word) { $temp_word[] = $word[$i]; $word_text_sql .= ($word_text_sql != '' ? ', ' : '') . "'" . $word[$i] . "'"; } $prev_word = $word[$i]; } $word = $temp_word; $check_words = array(); $value_sql = ''; $match_word = array(); for ($i = 0; $i < sizeof($word); $i++) { $new_match = true; if (isset($check_words[$word[$i]])) { $new_match = false; } if ($new_match) { $value_sql .= ($value_sql != '' ? ', ' : '') . '(\'' . $word[$i] . '\', 0)'; } } if ($value_sql != '') { $sql = "INSERT IGNORE INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)\n\t\t\t\t\t\t\tVALUES {$value_sql}"; $db->sql_query($sql); } } while (list($word_in, $match_sql) = @each($word_insert_sql)) { $title_match = $word_in == 'title' ? 1 : 0; if ($match_sql != '') { $sql = "INSERT INTO " . SEARCH_MATCH_TABLE . " (post_id, word_id, title_match)\n\t\t\t\tSELECT {$post_id}, word_id, {$title_match}\n\t\t\t\t\tFROM " . SEARCH_WORD_TABLE . "\n\t\t\t\t\tWHERE word_text IN ({$match_sql})"; $db->sql_query($sql); } } if ($mode == 'single') { remove_common('single', 4 / 10, $word); } return; }
function clean_file($file, $url, $type, $charSet, $use_nofollow, $use_robot, $can_leave_domain) { global $db_con, $entities, $index_host, $index_meta_keywords, $index_meta_description, $case_sensitive, $utf_16; global $home_charset, $chrSet, $del_secchars, $index_rss, $converter_dir, $div_all, $div_hyphen, $del_dups; global $bb_decode, $ent_decode, $cn_seg, $quotes, $dup_quotes, $clear, $only_links, $text_length, $strict_high; global $use_divs, $not_divs, $not_divlist, $use_divlist, $ignore_fulltxt, $index_meta_title, $js_reloc; global $use_elems, $not_elems, $use_elementslist, $not_elementslist, $del_elems, $conv_puny, $include_dir; $new = array(); $data = array(); $string = ''; $home_charset = strtoupper($home_charset); if ($utf_16) { //$file = mb_ereg_replace("\\0", "", $file); $file = utf16_to_utf8($file); } // kill useless blanks, under scores and line feeds $file = preg_replace("/[ |\r\n|\\_]+/i", " ", $file); $urlparts = parse_addr($url); $host = $urlparts['host']; //remove filename from path and all tags which should be ignored $path = preg_replace('/([^\\/]+)$/i', "", $urlparts['path']); if ($use_nofollow == '1') { $file = preg_replace("@<!--sphider_noindex-->.*?<!--\\/sphider_noindex-->@si", " ", $file); } // parse the HTML head $headdata = get_head_data($file, $url, $use_nofollow, $use_robot, $can_leave_domain, $type); $title = $headdata['title']; $description = $headdata['description']; $keywords = $headdata['keywords']; $file = preg_replace("@<head>.*?</head>@si", " ", $file); // remove HTML head from file $file = preg_replace("@<!--.*?-->@si", " ", $file); $file = preg_replace("@<script[^>]*?>.*?<\\/script>@si", " ", $file); //$file = str_replace("window.location.replace", " ", $file); $file = preg_replace("@<style[^>]*>.*?<\\/style>@si", " ", $file); $file = preg_replace("/<link rel[^<>]*>/i", " ", $file); $file = preg_replace("@<div style=(\"|')display\\:none(\"|').*?<\\/div>@si", " ", $file); $file = preg_replace("@<a.*?>@si", " ", $file); $file = preg_replace("@<(object|img|audio|video).*?>@si", " ", $file); $file = preg_replace("@<(align|alt|data|body|form|height|input|id|name|span|src|table|td|type|width|layer|span).*?>@si", " ", $file); $file = preg_replace("@\\{document\\..*?\\}@si", " ", $file); // if activated in Admin settings, ignore the full text if ($ignore_fulltxt == '1') { $file = ''; } // if activated in Admin settings, remove all div contents as defined in common 'divs_not' list if ($not_divs == '1') { // JFIELD parse the doc into a DOM tree so we can // do cool stuff like exclude certain divs // echo "<pre>\n"; global $myFile; $myFile = ""; $myDepth = 0; $dom = new DOMDocument(); $dom->loadHTML($file); /* // JFIELD figuring out image exclusion and stuff echo "<pre>HEY:\n"; echo "$title\n"; echo "$description\n"; echo "$url\n"; //var_dump( $dom->getElementById('shared-image-desc') ); echo "</pre>\n"; */ // probably a better way to get the doc // than skipping over the non-doc like this foreach ($dom->childNodes as $item) { if (!$item->tagName) { continue; } recurseNodes($item); } $file = $myFile; // wikipedia - don't index content of image pages if (preg_match("/\\/images\\//", $url) && preg_match("/^File\\:/", $title)) { // image description stopwords $mystopwords = explode(" ", "wikipedia schools english featured article sos children file"); $mydesc = str_replace($mystopwords, " ", strtolower($description)); $description = ''; // otherwise the unstripped version gets used $title = str_replace("File:", "", $title); // remove this noise $file = "{$title} {$mydesc} picture image"; } // echo "</pre>\n"; // END JFIELD } // if activated in Admin settings, fetch all div contents as defined in common 'divs_use' list if ($use_divs == '1') { foreach ($use_divlist as $thisid) { // try to find divs with id as specified in common 'divs' list // regexp ? if (strpos($thisid, "/") == "1" && strrpos($thisid, "/") == strlen($thisid) - 1) { $thisid = substr($thisid, 2, strlen($thisid) - 3); // remove the regex capsules } else { // for string input only if (strrpos($thisid, "*") == strlen($thisid) - 1) { $thisid = str_replace("*", "(.*?)", $thisid); // replace wildcards at the end of string input } } if (preg_match_all("@(<div class|<div id)=(\"|')" . $thisid . "(\"|').*?(</div>)@si", $file, $found_divs, PREG_OFFSET_CAPTURE)) { foreach ($found_divs[0] as $another_div) { // walk through all found divs. Usually W3C does not allow more than one div with this id. But who knows . . . . $this_divstart = $another_div[1]; // get actual startpos from div-array $i = "end"; // if required $i will become the loop counter for nested divs $nextstart = strpos($file, "<div", $this_divstart + 4); // find start pos of next div $nextend = strpos($file, "</div", $this_divstart + 4); // find end pos of next div //check for nested divs $start1 = strpos($file, "<div", $nextstart + 4); // find start pos of next div if ($start1 && $start1 < $nextend) { $i = "0"; // yes, nested } while ($i != "end") { // loop for (multiple) 'nested divs' $i = '0'; while ($nextstart && $nextstart < $nextend) { // next div is a nested div? $nextend1 = strpos($file, "</div", $nextstart + 4); // this is only the endpos of current div $nextend = strpos($file, "</div", $nextend1 + 6); // find end pos of next div $nextstart = strpos($file, "<div", $nextstart + 4); // find start pos of next div if ($nextstart && $nextstart < $nextend1) { // again nested in next layer? $i++; // counter for next level nested divs } } // if nested divs were found, correct end pos of div to be deleted while ($i > '1') { $nextend = strpos($file, "</div", $nextend + 6); $i--; } $nextend1 = strpos($file, "</div", $nextend + 6); // $nextend from former div (might have been nested) if ($nextend1) { $nextend = $nextend1; // defines next endpos } if (!$nextstart || $nextend < $nextstart) { $i = 'end'; // no longer nested divs } } // collect all divs to be indexed $all_divs[] = substr($file, $this_divstart, $nextend + 6 - $this_divstart); } // add content of all found divs to full text foreach ($all_divs as $use_thisdiv) { $divfile .= " " . $use_thisdiv; } } } $file = $divfile; // now this will be used as the body part of the page content } // if activated in Admin settings, fetch the content of all elements as defined in common 'elements_use' list and use the content of these elements as page content if ($use_elems == '1') { foreach ($use_elementslist as $this_element) { // try to find elements with id as specified in common 'elöements_use' list // regexp ? if (strpos($this_element, "/") == "1" && strrpos($this_element, "/") == strlen($this_element) - 1) { $this_element = substr($this_element, 2, strlen($this_element) - 3); // remove the regex capsules } if (preg_match_all("@<{$this_element}.*?>.*?<\\/{$this_element}>@si", $file, $found_elements, PREG_OFFSET_CAPTURE)) { foreach ($found_elements as $new_element) { // walk through all found elementss. foreach ($new_element as $new) { // build substring without content tags $string = $new[0]; $string = substr($string, strpos($string, ">") + 1); $string = substr($string, 0, strrpos($string, "<")); // collect all elements to be indexed $all_elements[] = $string; } } } } $file = ''; // add content of all found elements to full text foreach ($all_elements as $use_thiselem) { $file .= " " . $use_thiselem; // now all this will be used as the body part of the page content } } // if activated in Admin settings, fetch the content of all elements as defined in common 'elements_not' list and delete that part of the page if ($not_elems == '1') { foreach ($not_elementslist as $this_element) { // try to find elements with id as specified in common 'elements_not' list // regexp ? if (strpos($this_element, "/") == "1" && strrpos($this_element, "/") == strlen($this_element) - 1) { $this_element = substr($this_element, 2, strlen($this_element) - 3); // remove the regex capsules } if (preg_match_all("@<{$this_element}.*?>.*?<\\/{$this_element}>@si", $file, $found_elements, PREG_OFFSET_CAPTURE)) { foreach ($found_elements as $new_element) { // walk through all found elementss. foreach ($new_element as $new) { // collect all elements to be ignored $all_elements[] = $new[0]; } } } } // remove the content of all found elements from full text foreach ($all_elements as $use_thiselem) { $file = str_replace($use_thiselem, " ", $file); } } // parse bbcode if ($bb_decode == '1') { $file = bbcode($file); } $file = preg_replace("@<div.*?>@si", " ", $file); $file = preg_replace("@<\\/.*?>@si", " ", $file); //create spaces between tags, so that removing tags doesnt concatenate strings $file = preg_replace("/<[\\w ]+>/", "\\0 ", $file); $file = preg_replace("/<\\/[\\w ]+>/", "\\0 ", $file); $file = preg_replace("@<\\/a>@si", " ", $file); // remove lost end tag //$file = strip_tags($file); // remove the content of HTML tags from $file (does not work for invalid written and unclosed tags) // replaced since Sphider-plus version 2.7 // remove the content of HTML tags from $file $found_tags = array(); $another_tag = array(); if (preg_match_all("@<.*?>@s", $file, $found_tags, PREG_OFFSET_CAPTURE)) { foreach ($found_tags[0] as $another_tag) { // walk through all found tags. if (strlen($another_tag[0]) < "500") { // delete this tag from full text if not too long (unclosed) $file = str_replace($another_tag[0], " ", $file); } } } if ($del_elems) { // if activated in Admin backend, delete < element /> from full text $found_tags = array(); $another_tag = array(); if (preg_match_all("@\\<.*?\\>@s", $file, $found_tags, PREG_OFFSET_CAPTURE)) { foreach ($found_tags[0] as $another_tag) { // walk through all found tags. $file = str_replace($another_tag[0], " ", $file); } } } if ($conv_puny) { // make punycode readable require_once "{$include_dir}/idna_converter.php"; // Initialize the converter class $IDN = new idna_convert(array('idn_version' => 2008)); $found_tags = array(); $another_tag = array(); $this_tag = ''; $file = str_replace("http", " http", $file); //place a blank in front of all http's if (preg_match_all("@http.*? @s", $file, $found_tags, PREG_OFFSET_CAPTURE)) { foreach ($found_tags[0] as $another_tag) { // walk through all found tags. // Decode the URL to readable format $this_tag = $IDN->decode(rawurldecode($another_tag[0])); $this_tag = rawurldecode($this_tag); $file = str_replace($another_tag[0], $this_tag, $file); } } } $file = str_replace(" ", " ", $file); // replace special (long) blanks with standard blank $file = str_replace("â€â€ÂÂ", "'", $file); // replace invalid coded quotations $file = str_replace("©", "—", $file); // replace invalid coded long dash with correct long dash $file = preg_replace("/ +/", " ", $file); // replace TABs with a standard blank $file = preg_replace("/ +/", " ", $file); // kill duplicate blanks $file = preg_replace("/__+/", " ", $file); // kill duplicate underscore $file = preg_replace("/--+/", " ", $file); // kill duplicate hyphens $file = preg_replace("/\\*\\*+/", " ", $file); // kill duplicate stars $file = preg_replace("/\\#\\#+/", " ", $file); // kill duplicate hash tags $file = str_replace(" ", " ", $file); $file = str_replace(" ", " ", $file); // kill duplicate blanks $file = str_replace("­", "", $file); // kill break character $file = preg_replace("/\\☨\\☨+/", " ", $file); // kill duplicates. . . Yes, I've met something $file = preg_replace("/\\(\\(+/", " ", $file); // kill duplicates. . . no comment $file = preg_replace("/\\<\\<+/", " ", $file); // kill duplicates $file = preg_replace("/\\>\\>+/", " ", $file); // kill duplicates $file = preg_replace("/\\*\\~+/", " ", $file); // kill duplicates $file = preg_replace("/\\+\\++/", " ", $file); // kill duplicates $file = preg_replace("/\\=\\=+/", " ", $file); // kill duplicates $file = preg_replace("/\\~\\~+/", " ", $file); // kill duplicates // kill some other duplicates, already met on the Internet if ($del_dups) { $file = preg_replace("/\\(\\(+/", " ", $file); $file = preg_replace("/\\)\\)+/", " ", $file); $file = preg_replace("/\\~\\~+/", " ", $file); $file = preg_replace("/\\=\\=+/", " ", $file); $file = preg_replace("/\\?\\?+/", " ", $file); $file = preg_replace("/\\!\\!+/", " ", $file); $file = preg_replace("/\\.\\.+/", " ", $file); $file = preg_replace("/\\<\\<+/", " ", $file); $file = preg_replace("/\\>\\>+/", " ", $file); $file = preg_replace("/\\:\\:+/", " ", $file); $file = preg_replace("/\\+\\++/", " ", $file); $file = preg_replace("/\\-\\-+/", " ", $file); $file = preg_replace("/\\*\\*+/", " ", $file); } $file = str_replace(" ", " ", $file); $file = str_replace(" ", " ", $file); // kill duplicate blanks $file = str_replace("­", "", $file); // kill break character // kill some special cases $file = str_replace(""", "\"", $file); $file = str_replace("…", " ", $file); if ($text_length != "0") { // build substring of full text until last space in front of $text_length $file = substr($file, 0, strrpos(substr($file, 0, $text_length), " ")); } if ($index_host == 1) { // separate words in host and path $host_sep = preg_replace("/\\.|\\/|\\\\/", " ", $host); $path_sep = preg_replace("/\\.|\\/|\\\\/", " ", $path); $file = $file . " " . $host . " " . $host_sep; $file = $file . " " . $path . " " . $path_sep; } if ($headdata['title'] && $index_meta_title) { $file = $file . " " . $title; } if ($index_meta_description == 1) { $file = $file . " " . $description; } if ($index_meta_keywords == 1) { $file = $file . " " . $keywords; } if ($ent_decode == '1') { // as it seems, the PHP function html_entity_decode() has some problems. // In case that 2 entities are placed directly together like: — // we are obliged to be helpful by eliminating one of them $file = str_replace(" ", " ", $file); // now PHP does not get confused $file = html_entity_decode($file, ENT_QUOTES, 'UTF-8'); $title = str_replace(" ", " ", $title); $title = html_entity_decode($title, ENT_QUOTES, 'UTF-8'); } // correct some other trash found on the Internet $file = str_replace("�", "fi", $file); $file = str_replace("fl", "fl", $file); // for URLs use entities, so that links become readable in full text $file = str_replace("<a href=\"http://www.", "<a href="http://www.", $file); // replace .. with a standard blank $file = str_replace("...", " ", $file); // kill duplicate blanks " ", \r, \t, \n and \f if (preg_match("@8859|utf@", $charSet)) { $file = preg_replace("/[\\s,]+/", " ", $file); } if ($index_rss == '1') { $file = preg_replace('/0b/si', '.', $file); // try to correct bad charset interpretation $file = preg_replace('//si', '\'', $file); $trash = array("\r\n", "\n", "\r", "0E", "0C", "0I"); // kill 'LF' and the others } else { $trash = array("\r\n", "\f", "\n", "\r", "\t"); } $replace = ' '; $file = str_replace($trash, $replace, $file); $fulltext = $file; // required for result listing as extract around the keywords and for PHRASE search if ($del_secchars) { $file = del_secchars($file); } // use the cleaned $file to just highlight the pure query term in result listing if ($strict_high) { $fulltext = $file; } // convert all single quotes into standard quote if ($quotes == '1') { $all_quotes = array("‘" => "'", "‘" => "'", "’" => "'", "’" => "'", "′" => "'", "′" => "'", "‘" => "'", "‘" => "'", "´" => "'", "`" => "'", "’" => "'", "‘" => "'", "’" => "'", "’" => "'"); //reset($all_quotes); while ($char = each($all_quotes)) { $file = preg_replace("/" . $char[0] . "/si", $char[1], $file); $title = preg_replace("/" . $char[0] . "/si", $char[1], $title); $description = preg_replace("/" . $char[0] . "/si", $char[1], $description); $keywords = preg_replace("/" . $char[0] . "/si", $char[1], $keywords); } } // convert all double quotes into standard quotations if ($dup_quotes == '1') { $all_quotes = array("“" => "\"", "�" => "\"", "„" => "\""); reset($all_quotes); while ($char = each($all_quotes)) { $file = preg_replace("/" . $char[0] . "/i", $char[1], $file); $title = preg_replace("/" . $char[0] . "/i", $char[1], $title); $description = preg_replace("/" . $char[0] . "/i", $char[1], $description); $keywords = preg_replace("/" . $char[0] . "/i", $char[1], $keywords); } } // split words at hyphen, single quote, dot and comma into their basics if ($div_all || $div_hyphen) { $file = split_words($file); // jfield: yes, we want to index words split on hyphens, // but what does that have to do with changing the appearance // of the title? sphider_plus, you so crazy // $title = split_words($title); $description = split_words($description); $keywords = split_words($keywords); } reset($entities); while ($char = each($entities)) { $file = preg_replace("/" . $char[0] . "/i", $char[1], $file); $title = preg_replace("/" . $char[0] . "/i", $char[1], $title); $description = preg_replace("/" . $char[0] . "/i", $char[1], $description); $keywords = preg_replace("/" . $char[0] . "/i", $char[1], $keywords); } // replace special (long) blanks in title $title = str_replace(" ", " ", $title); //remove all the fancy jokes some webmasters add $title = preg_replace("@<(.*?)>@si", "", $title); $title = preg_replace("@ +@si", " ", $title); // replace TABs with a standard blank $fulltext = preg_replace("/ +/", " ", $fulltext); $count = count(preg_split("/[\\s,]+/", $fulltext)); $data['fulltext'] = $db_con->real_escape_string($fulltext); $data['content'] = $file; $data['title'] = $db_con->real_escape_string($title); $data['description'] = $db_con->real_escape_string($description); $data['keywords'] = $db_con->real_escape_string($keywords); $data['host'] = $host; $data['path'] = $path; $data['nofollow'] = $headdata['nofollow']; $data['noindex'] = $headdata['noindex']; $data['base'] = $headdata['base']; $data['cano_link'] = $headdata['cano_link']; $data['count'] = $count; $data['refresh'] = $headdata['refresh']; $data['wait'] = $headdata['wait']; if ($clear == 1) { unset($char, $file, $fulltext, $path_sep, $headdata, $regs, $urlparts, $host); } return $data; }
$sort_by_sql = 't.forum_id'; $sort_type = SORT_NUMERIC; break; case 4: $sort_by_sql = 't.last_post'; $sort_type = SORT_NUMERIC; break; default: $sort_by_sql = $show_as == 'topics' ? 't.last_post' : 'p.posted'; $sort_type = SORT_NUMERIC; break; } // If it's a search for keywords if ($keywords) { // split the keywords into words $keywords_array = split_words($keywords, false); if (empty($keywords_array)) { message($lang_search['No hits']); } // Should we search in message body or topic subject specifically? $search_in_cond = $search_in ? $search_in > 0 ? ' AND m.subject_match = 0' : ' AND m.subject_match = 1' : ''; $word_count = 0; $match_type = 'and'; $sort_data = array(); foreach ($keywords_array as $cur_word) { $data = array(); $data[] = $panther_user['g_id']; switch ($cur_word) { case 'and': case 'or': case 'not':
function add_search_words($mode, $post_id, $post_text, $post_title = '', $topic_id = '') { global $ft_cfg, $lang; $stopword_array = @file(FT_ROOT . 'language/lang_' . $ft_cfg['default_lang'] . "/search_stopwords.txt"); $synonym_array = @file(FT_ROOT . 'language/lang_' . $ft_cfg['default_lang'] . "/search_synonyms.txt"); $search_raw_words = array(); $search_raw_words['text'] = split_words(clean_words('post', $post_text, $stopword_array, $synonym_array)); $search_raw_words['title'] = split_words(clean_words('post', $post_title, $stopword_array, $synonym_array)); @set_time_limit(0); $word = array(); $word_insert_sql = array(); while (list($word_in, $search_matches) = @each($search_raw_words)) { $word_insert_sql[$word_in] = ''; if (!empty($search_matches)) { for ($i = 0, $cnt = count($search_matches); $i < $cnt; $i++) { $search_matches[$i] = @$search_matches[$i] ? trim($search_matches[$i]) : ''; if ($search_matches[$i] != '') { $word[] = $search_matches[$i]; if (!strstr($word_insert_sql[$word_in], "'" . $search_matches[$i] . "'")) { $word_insert_sql[$word_in] .= $word_insert_sql[$word_in] != "" ? ", '" . $search_matches[$i] . "'" : "'" . $search_matches[$i] . "'"; } } } } } if (count($word)) { sort($word); $prev_word = ''; $word_text_sql = ''; $temp_word = array(); for ($i = 0; $i < count($word); $i++) { if ($word[$i] != $prev_word) { $temp_word[] = $word[$i]; $word_text_sql .= ($word_text_sql != '' ? ', ' : '') . "'" . $word[$i] . "'"; } $prev_word = $word[$i]; } $word = $temp_word; $check_words = array(); $value_sql = ''; $match_word = array(); for ($i = 0; $i < count($word); $i++) { $new_match = true; if (isset($check_words[$word[$i]])) { $new_match = false; } if ($new_match) { $sql = "INSERT INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)\n\t\t\t\t\tVALUES ('" . $word[$i] . "', 0)"; if (!DB()->sql_query($sql)) { message_die(GENERAL_ERROR, 'Could not insert new word', '', __LINE__, __FILE__, $sql); } } } if ($value_sql != '') { $sql = "INSERT IGNORE INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)\n\t\t\t\tVALUES {$value_sql}"; if (!DB()->sql_query($sql)) { message_die(GENERAL_ERROR, 'Could not insert new word', '', __LINE__, __FILE__, $sql); } } } while (list($word_in, $match_sql) = @each($word_insert_sql)) { $title_match = $word_in == 'title' ? 1 : 0; if ($match_sql != '') { $sql = "INSERT INTO " . SEARCH_MATCH_TABLE . " (post_id, word_id, title_match)\n\t\t\t\tSELECT {$post_id}, word_id, {$title_match}\n\t\t\t\t\tFROM " . SEARCH_WORD_TABLE . "\n\t\t\t\t\tWHERE word_text IN ({$match_sql})"; if (!DB()->sql_query($sql)) { message_die(GENERAL_ERROR, 'Could not insert new word matches', '', __LINE__, __FILE__, $sql); } } } if ($mode == 'single') { remove_common('single', 4 / 10, $word); } return; }