/** * Check for existing FAQs matching a ticket to be submitted, via searching. * * @param tempcode Page title * @param string Ticket ID we'd be creating * @param string What is being searched for * @return ?tempcode The search results (NULL: could not search) */ function do_search($title, $ticket_id, $content) { require_code('database_search'); // We don't want to display too many --- just enough to show the top results $max = 10; // Search under all hooks we've asked to search under $results = array(); require_code('hooks/modules/search/catalogue_entries'); $object = object_factory('Hook_search_catalogue_entries'); $info = $object->info(); if (is_null($info)) { return NULL; } // Get the ID of the default FAQ catalogue $catalogue_id = $GLOBALS['SITE_DB']->query_value('catalogue_categories', 'id', array('c_name' => 'faqs')); if (is_null($catalogue_id)) { return NULL; } // Category filter $where_clause = 'r.' . $info['category'] . '=' . strval($catalogue_id); $boolean_operator = 'OR'; $content_where = build_content_where($content, true, $boolean_operator); $hook_results = $object->run($content, false, 'ASC', $max, 0, false, $content_where, '', NULL, NULL, 'relevance', NULL, $boolean_operator, $where_clause, NULL, true); if (is_null($hook_results) || count($hook_results) == 0) { return NULL; } foreach ($hook_results as $i => $result) { $result['object'] = $object; $result['type'] = 'catalogue_entries'; $hook_results[$i] = $result; } $results = sort_search_results($hook_results, array(), 'ASC'); $out = build_search_results_interface($results, 0, $max, 'ASC'); return do_template('SUPPORT_TICKETS_SEARCH_SCREEN', array('_GUID' => '427e28208e15494a8f126eb4fb2aa60c', 'TITLE' => $title, 'URL' => build_url(array('page' => '_SELF', 'id' => $ticket_id, 'type' => 'post'), '_SELF'), 'POST_FIELDS' => build_keep_post_fields(), 'RESULTS' => $out)); }
/** * The actualiser of a search. * * @param ID_TEXT Codename for what's being searched (blank: mixed search) * @param string Author name * @param ?AUTO_LINK Author ID (NULL: none given) * @param integer Days to search * @param ID_TEXT Sort key * @param ID_TEXT Sort direction * @set ASC DESC * @param boolean Whether to only search titles * @param string Comma-separated list of categories to search under * @return array A triple: The results, results browser, the number of results */ function results($id, $author, $author_id, $days, $sort, $direction, $only_titles, $search_under) { $title = get_page_title('RESULTS'); cache_module_installed_status(); $cutoff = $days == -1 ? NULL : time() - $days * 24 * 60 * 60; // What we're searching for $content = get_param('content', false, true); // Search keyword highlighting in any loaded Comcode global $SEARCH__CONTENT_BITS; $_content_bits = explode(' ', str_replace('"', '', preg_replace('#(^|\\s)\\+#', '', preg_replace('#(^|\\s)\\-#', '', $content)))); $SEARCH__CONTENT_BITS = array(); require_code('textfiles'); $too_common_words = explode(chr(10), read_text_file('too_common_words', '', true)); foreach ($_content_bits as $content_bit) { $content_bit = trim($content_bit); if ($content_bit == '') { continue; } if (!in_array(strtolower($content_bit), $too_common_words)) { $SEARCH__CONTENT_BITS[] = $content_bit; } } $start = get_param_integer('start', 0); $default_max = 10; if (ini_get('memory_limit') != '-1' && ini_get('memory_limit') != '0') { if (intval(preg_replace('#M$#', '', ini_get('memory_limit'))) < 20) { $default_max = 5; } } $max = get_param_integer('max', $default_max); // Also see get_search_rows $save_title = get_param('save_title', ''); if (!is_guest() && $save_title != '' && $start == 0) { static $saved_search = false; if (!$saved_search) { $GLOBALS['SITE_DB']->query_insert('searches_saved', array('s_title' => $save_title, 's_member_id' => get_member(), 's_time' => time(), 's_primary' => $content, 's_auxillary' => serialize(array_merge($_POST, $_GET)))); $saved_search = true; } } $boolean_operator = get_param('conjunctive_operator', 'OR'); $boolean_search = $this->_is_boolean_search(); $content_where = build_content_where($content, $boolean_search, $boolean_operator); disable_php_memory_limit(); // Search under all hooks we've asked to search under $results = array(); $_hooks = find_all_hooks('modules', 'search'); foreach (array_keys($_hooks) as $hook) { require_code('hooks/modules/search/' . filter_naughty_harsh($hook)); $object = object_factory('Hook_search_' . filter_naughty_harsh($hook), true); if (is_null($object)) { continue; } $info = $object->info(); if (is_null($info)) { continue; } $test = get_param_integer('search_' . $hook, 0); if (($test == 1 || get_param_integer('all_defaults', 0) == 1 && $info['default'] || $id == $hook) && ($id == '' || $id == $hook)) { // Category filter if ($search_under != '!' && $search_under != '-1' && array_key_exists('category', $info)) { $cats = explode(',', $search_under); $where_clause = '('; foreach ($cats as $cat) { if (trim($cat) == '') { continue; } if ($where_clause != '(') { $where_clause .= ' OR '; } if ($info['integer_category']) { $where_clause .= (strpos($info['category'], '.') !== false ? '' : 'r.') . $info['category'] . '=' . strval((int) $cat); } else { $where_clause .= db_string_equal_to((strpos($info['category'], '.') !== false ? '' : 'r.') . $info['category'], $cat); } } $where_clause .= ')'; } else { $where_clause = ''; } $only_search_meta = get_param_integer('only_search_meta', 0) == 1; $direction = get_param('direction', 'ASC'); if (function_exists('set_time_limit')) { @set_time_limit(5); } // Prevent errant search hooks (easily written!) taking down a server. Each call given 5 seconds (calling set_time_limit resets the timer). $hook_results = $object->run($content, $only_search_meta, $direction, $max, $start, $only_titles, $content_where, $author, $author_id, $cutoff, $sort, $max, $boolean_operator, $where_clause, $search_under, $boolean_search ? 1 : 0); if (is_null($hook_results)) { continue; } foreach ($hook_results as $i => $result) { $result['object'] = $object; $hook_results[$i] = $result; } $results = sort_search_results($hook_results, $results, $direction); } } if (function_exists('set_time_limit')) { @set_time_limit(15); } global $EXTRA_HEAD; $EXTRA_HEAD->attach('<meta name="robots" content="noindex,nofollow" />'); // XHTMLXHTML // Now glue our templates together $out = build_search_results_interface($results, $start, $max, $direction, $id == ''); if ($out->is_empty()) { if ($days != -1 && $GLOBALS['TOTAL_RESULTS'] == 0) { $ret_maybe = $this->results($id, $author, $author_id, -1, $sort, $direction, $only_titles, $search_under); if (!$ret_maybe[0]->is_empty()) { attach_message(do_lang_tempcode('NO_RESULTS_DAYS', escape_html(integer_format($days))), 'notice'); return $ret_maybe; } } return array(new ocp_tempcode(), new ocp_tempcode(), 0); } require_code('templates_results_browser'); $results_browser = results_browser(do_lang_tempcode('RESULTS'), NULL, $start, 'start', $max, 'max', $GLOBALS['TOTAL_RESULTS'], NULL, 'results', true, true); if ($start == 0) { $GLOBALS['SITE_DB']->query_insert('searches_logged', array('s_member_id' => get_member(), 's_time' => time(), 's_primary' => substr($content, 0, 255), 's_auxillary' => serialize(array_merge($_POST, $_GET)), 's_num_results' => count($results))); } return array($out, $results_browser, $GLOBALS['TOTAL_RESULTS']); }