function create_search_cache($keywords, $author, $search_in = false, $forum = array(-1), $show_as = 'topics', $sort_by = null, $sort_dir = 'DESC') { global $forum_db, $forum_user, $forum_config, $forum_url, $lang_search, $lang_common, $db_type; $return = ($hook = get_hook('sf_fn_create_search_cache_start')) ? eval($hook) : null; if ($return != null) { return; } if (utf8_strlen(str_replace(array('*', '%'), '', $author)) < 2) { $author = ''; } if (utf8_strlen(str_replace(array('*', '%'), '', $keywords)) < FORUM_SEARCH_MIN_WORD) { $keywords = ''; } if (!$keywords && !$author) { message($lang_search['No terms']); } $keywords = utf8_strtolower($keywords); $author = utf8_strtolower($author); // Flood protection if ($forum_user['last_search'] && time() - $forum_user['last_search'] < $forum_user['g_search_flood'] && time() - $forum_user['last_search'] >= 0) { message(sprintf($lang_search['Search flood'], $forum_user['g_search_flood'])); } if ($forum_user['is_guest']) { $query = array('UPDATE' => 'online', 'SET' => 'last_search=' . time(), 'WHERE' => 'ident=\'' . $forum_db->escape(get_remote_address()) . '\''); } else { $query = array('UPDATE' => 'users', 'SET' => 'last_search=' . time(), 'WHERE' => 'id=' . $forum_user['id']); } ($hook = get_hook('sf_fn_create_search_cache_qr_update_last_search_time')) ? eval($hook) : null; $forum_db->query_build($query) or error(__FILE__, __LINE__); // We need to grab results, insert them into the cache and reload with a search id before showing them $keyword_results = $author_results = array(); // If it's a search for keywords if ($keywords) { // Remove any apostrophes which aren't part of words $keywords = substr(preg_replace('((?<=\\W)\'|\'(?=\\W))', '', ' ' . $keywords . ' '), 1, -1); // Remove symbols and multiple whitespace $keywords = preg_replace('/[\\^\\$&\\(\\)<>`"\\|,@_\\?%~\\+\\[\\]{}:=\\/#\\\\;!\\.\\s]+/', ' ', $keywords); // Fill an array with all the words $keywords_array = array_unique(explode(' ', $keywords)); // Remove any words that are not indexed $keywords_array = array_filter($keywords_array, 'validate_search_word'); if (empty($keywords_array)) { no_search_results(); } $word_count = 0; $match_type = 'and'; $result_list = array(); foreach ($keywords_array as $cur_word) { switch ($cur_word) { case 'and': case 'or': case 'not': $match_type = $cur_word; break; default: $query = array('SELECT' => 'm.post_id', 'FROM' => 'search_words AS w', 'JOINS' => array(array('INNER JOIN' => 'search_matches AS m', 'ON' => 'm.word_id=w.id')), 'WHERE' => 'w.word LIKE \'' . $forum_db->escape(str_replace('*', '%', $cur_word)) . '\''); // Search in what? if ($search_in) { $query['WHERE'] .= $search_in > 0 ? ' AND m.subject_match=0' : ' AND m.subject_match=1'; } ($hook = get_hook('sf_fn_create_search_cache_qr_get_keyword_hits')) ? eval($hook) : null; $result = $forum_db->query_build($query) or error(__FILE__, __LINE__); $row = array(); while (list($post_id) = $forum_db->fetch_row($result)) { $row[$post_id] = 1; if (!$word_count) { $result_list[$post_id] = 1; } else { if ($match_type == 'or') { $result_list[$post_id] = 1; } else { if ($match_type == 'not') { $result_list[$post_id] = 0; } } } } if ($match_type == 'and' && $word_count) { foreach (array_keys($result_list) as $post_id) { if (!isset($row[$post_id])) { $result_list[$post_id] = 0; } } } ++$word_count; $forum_db->free_result($result); break; } } foreach ($result_list as $post_id => $matches) { if ($matches) { $keyword_results[] = $post_id; } } unset($result_list); } // 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'])) { $query = array('SELECT' => 'u.id', 'FROM' => 'users AS u', 'WHERE' => 'u.username ' . ($db_type == 'pgsql' ? 'ILIKE' : 'LIKE') . ' \'' . $forum_db->escape(str_replace('*', '%', $author)) . '\''); ($hook = get_hook('sf_fn_create_search_cache_qr_get_author')) ? eval($hook) : null; $result = $forum_db->query_build($query) or error(__FILE__, __LINE__); $user_ids = array(); while ($row = $forum_db->fetch_row($result)) { $user_ids[] = $row[0]; } if (!empty($user_ids)) { $query = array('SELECT' => 'p.id', 'FROM' => 'posts AS p', 'WHERE' => 'p.poster_id IN(' . implode(',', $user_ids) . ')'); ($hook = get_hook('sf_fn_create_search_cache_qr_get_author_hits')) ? eval($hook) : null; $result = $forum_db->query_build($query) or error(__FILE__, __LINE__); $search_ids = array(); while ($row = $forum_db->fetch_row($result)) { $author_results[] = $row[0]; } $forum_db->free_result($result); } } if ($author && $keywords) { // If we searched for both keywords and author name we want the intersection between the results $search_ids = array_intersect($keyword_results, $author_results); unset($keyword_results, $author_results); } else { if ($keywords) { $search_ids = $keyword_results; } else { $search_ids = $author_results; } } if (count($search_ids) == 0) { no_search_results(); } // Setup the default show_as topics search $query = array('SELECT' => 't.id', 'FROM' => 'posts AS p', 'JOINS' => array(array('INNER JOIN' => 'topics AS t', 'ON' => 't.id=p.topic_id'), array('LEFT JOIN' => 'forum_perms AS fp', 'ON' => '(fp.forum_id=t.forum_id AND fp.group_id=' . $forum_user['g_id'] . ')')), 'WHERE' => '(fp.read_forum IS NULL OR fp.read_forum=1) AND p.id IN(' . implode(',', $search_ids) . ')', 'GROUP BY' => 't.id'); // Search a specific forum? if (!in_array(-1, $forum) || $forum_config['o_search_all_forums'] == '0' && !$forum_user['is_admmod']) { $query['WHERE'] .= ' AND t.forum_id IN(' . implode(',', $forum) . ')'; } // Adjust the query if show_as posts if ($show_as == 'posts') { $query['SELECT'] = 'p.id'; unset($query['GROUP BY']); } ($hook = get_hook('sf_fn_create_search_cache_qr_get_hits')) ? eval($hook) : null; $result = $forum_db->query_build($query) or error(__FILE__, __LINE__); $search_ids = array(); while ($row = $forum_db->fetch_row($result)) { $search_ids[] = $row[0]; } // Prune "old" search results $query = array('SELECT' => 'o.ident', 'FROM' => 'online AS o'); ($hook = get_hook('sf_fn_create_search_cache_qr_get_online_idents')) ? eval($hook) : null; $result = $forum_db->query_build($query) or error(__FILE__, __LINE__); $online_idents = array(); while ($row = $forum_db->fetch_row($result)) { $online_idents[] = '\'' . $forum_db->escape($row[0]) . '\''; } if (!empty($online_idents)) { $query = array('DELETE' => 'search_cache', 'WHERE' => 'ident NOT IN(' . implode(',', $online_idents) . ')'); ($hook = get_hook('sf_fn_create_search_cache_qr_delete_old_cached_searches')) ? eval($hook) : null; $forum_db->query_build($query) or error(__FILE__, __LINE__); } // Final search results $search_results = implode(',', $search_ids); // Fill an array with our results and search properties $search_data = serialize(compact('search_results', 'sort_by', 'sort_dir', 'show_as')); $search_id = mt_rand(1, 2147483647); $ident = $forum_user['is_guest'] ? get_remote_address() : $forum_user['username']; $query = array('INSERT' => 'id, ident, search_data', 'INTO' => 'search_cache', 'VALUES' => $search_id . ', \'' . $forum_db->escape($ident) . '\', \'' . $forum_db->escape($search_data) . '\''); ($hook = get_hook('sf_fn_create_search_cache_qr_cache_search')) ? eval($hook) : null; $forum_db->query_build($query) or error(__FILE__, __LINE__); $return = ($hook = get_hook('sf_fn_create_search_cache_end')) ? eval($hook) : null; if ($return != null) { return; } $forum_db->end_transaction(); $forum_db->close(); // Redirect the user to the cached result page header('Location: ' . str_replace('&', '&', forum_link($forum_url['search_results'], $search_id))); exit; }
} else { if ($show_as == 'topics') { $forum_page['per_page'] = $forum_user['disp_topics']; } else { if ($show_as == 'forums') { $forum_page['per_page'] = 0; } } } // Show all // We now have a query that will give us our results in $query, lets get the data! $num_hits = get_search_results($query, $search_set); ($hook = get_hook('se_post_results_fetched')) ? eval($hook) : null; // No search results? if ($num_hits == 0) { no_search_results($action); } // // Output the search results // // Setup breadcrumbs and results header and footer $forum_page['crumbs'][] = array($forum_config['o_board_title'], forum_link($forum_url['index'])); $action = isset($action) ? $action : null; generate_search_crumbs($action); // Generate paging links if ($show_as == 'posts' || $show_as == 'topics') { $forum_page['page_post']['paging'] = '<p class="paging"><span class="pages">' . $lang_common['Pages'] . '</span> ' . paginate($forum_page['num_pages'], $forum_page['page'], $url_type, $lang_common['Paging separator'], $search_id) . '</p>'; } // Get topic/forum tracking data if (!$forum_user['is_guest']) { $tracked_topics = get_tracked_topics();